SpringBoot學習之路---簡單記錄整合SpringSecurity實現登錄認證授權

基本上每一個項目都會有用戶登錄的這個功能,用戶需要在登錄之後才能夠去訪問一些資源,如果沒登錄的話就不能訪問(403)。我們可以自己編碼去實現這樣的業務邏輯,當然每一次都自己去編碼是比較耗時的,畢竟市面上已經有現成的開源的框架可以拿來使用了(Apache的shiro與Spring的Spring Security),這一篇的博客的主角就是介紹一下後者在SpringBoot中的整合配置,以及如何基本使用


首先還是一樣,要用到什麼技術,就引入什麼技術的maven依賴:

<!--        引入security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

同時因爲後面還要用到thymeleaf模版引擎,所以我們順便把thymeleaf也導入了:

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

shiro、Springsecurity這些框架技術都統稱爲安全框架,安全框架有兩個重要的作用,是認證授權。認證是程序確認你是什麼身份,而授權就是程序根據你的身份給你不同的權利。

這裏不講空話,用我看的學習資源裏面的一個場景,一個武林祕籍系統,用戶可以根據不同的權限從而查看到不同的武林祕籍,這是初始的樣子:
在這裏插入圖片描述
我們現在需要做的是點進去每個祕籍,需要不同的身份,比如我是普通的用戶,那麼我只能去查看普通的武林祕籍,同理,另外兩個也是一樣,而且,當我們登錄之後會去顯示出用戶的信息和所擁有的身份。

這時就可以用到springsecurity了,我們需要創建一個SpringSecurity的配置類,讓其繼承於WebSecurityConfigurerAdapter,並實現一些方法:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@EnableWebSecurity註解的作用是開啓security的服務(有點廢話),它內部也是個組合註解,有一個@Configuration,可以理解爲通知SpringBoot讓其掃描到該類。

之後看看讓其繼承兩個方法,爲什麼是兩個呢,一個是認證,另外一個是授權啦:

//授權
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("VIP1") //普通武林祕籍,並設置所需身份爲VIP1
                .antMatchers("/level2/**").hasRole("VIP2") //高級武功祕籍,並設置所需身份爲VIP2
                .antMatchers("/level3/**").hasRole("VIP3"); //爵士武功祕籍,並設置所需身份爲VIP3

        //自動配置登錄,使用這行代碼之後,springsecurity會幫我們生成一個登錄,並自動幫我們校驗用戶名和密碼!,默認的路徑爲/login
        http.formLogin();

        //自動配置註銷,可以通過訪問路徑/logout,來幫我們註銷當前用戶,底層原理是撤銷相關的session
        http.logout().logoutSuccessUrl("/");

        //自動配置記住我功能,就像是很多網站的"記住我"功能,使用這個後,下次進入網站無需登錄,底層原理是像瀏覽器發送一個cookie信息,內容是一個sessionid,有效期14天,這樣下次訪問時帶上這個sessionid就能找到session了
        http.rememberMe();
    }

    //認證
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    			//這裏爲了簡便,就不從數據庫中換取數據了,從內存中獲取,inMemoryAuthentication()就是從內存中獲取,這裏分別設置了兩個用戶,它們的身份分別是"VIP1""VIP2""VIP3",用戶名和密碼見具體方法。
                auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("leslie").password("123").roles("VIP1","VIP2")
                .and()
                .withUser("lion").password("123").roles("VIP3");
    }

每一行代碼的作用寫在註釋中。總結下,到這一步,我們做完的事情有給leslielion的兩個用戶授權VIP1、VIP2和VIP3的身份,併爲不同的訪問路徑授權了不同的用戶。

配置類寫完之後,還不夠,這裏controller代碼略過了,無非就是控制頁面跳轉到哪裏。前端頁面代碼也是需要修改了,修改之前需要引入thymeleaf-springsecurity的整合:

<!--        引入thymeleaf與spring security整合-->
        <!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

修改後的前端代碼:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	  xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">歡迎光臨武林祕籍管理系統</h1>

<div sec:authorize="!isAuthenticated()">
	<h2 align="center">遊客您好,如果想查看武林祕籍 <a th:href="@{/login}">請登錄</a></h2>
</div>


<div sec:authorize="isAuthenticated()">
	<h2 align="center"><span sec:authentication="name"></span>您好,你的角色是:<span sec:authentication="principal.authorities"></span></h2>
	<form method="post" th:action="@{/logout}">
	<input type="submit" value="註銷"/>
	</form>
</div>
<hr>

<div sec:authorize="hasRole('VIP1')">
	<h3>普通武功祕籍</h3>
	<ul>
		<li><a th:href="@{/level1/1}">羅漢拳</a></li>
		<li><a th:href="@{/level1/2}">武當長拳</a></li>
		<li><a th:href="@{/level1/3}">全真劍法</a></li>
	</ul>
</div>

<div sec:authorize="hasRole('VIP2')">
	<h3>高級武功祕籍</h3>
	<ul>
		<li><a th:href="@{/level2/1}">太極拳</a></li>
		<li><a th:href="@{/level2/2}">七傷拳</a></li>
		<li><a th:href="@{/level2/3}">梯雲縱</a></li>
	</ul>
</div>

<div sec:authorize="hasRole('VIP3')">
	<h3>絕世武功祕籍</h3>
	<ul>
		<li><a th:href="@{/level3/1}">葵花寶典</a></li>
		<li><a th:href="@{/level3/2}">龜派氣功</a></li>
		<li><a th:href="@{/level3/3}">獨孤九劍</a></li>
	</ul>
</div>


</body>
</html>

這裏說明一下,添加一些代碼的作用

頁面首先需要引入thymeleaf的約束空間:

xmlns:sec="http://www.thymeleaf.org/extras/spring-security"

引入之後就可以使用一些和springsecurity有關的標籤了。

  • sec:authentication=“name”:表示取出當前登錄的用戶名。
  • sec:authentication=“principal.authorities”:取出當前用戶的所有身份
  • sec:authorize=“isAuthenticated()”:判斷當前狀態是否登錄,同理屬性內前面加一個!表示判斷是否未登錄,有這個之後,我們以後就不需要自己編寫攔截器判斷判斷登錄狀態了。
  • sec:authorize=“hasRole(‘VIP3’)”:判斷當前登錄用戶是否有該身份。

之後我們再次查看該頁面:

在這裏插入圖片描述

可以看到 sec:authorize=“isAuthenticated()” 的作用出來了,如果未登錄的話,只顯示這個,點擊登錄,看看Springsecurity爲我們生成的登錄頁面:
在這裏插入圖片描述
還挺好看的,下面的那個單選框"Remember me on this computer"是之前http.rememberMe();所自動配置的功能。首先登錄leslie,看看能否顯示前兩個級別的武功祕籍:

在這裏插入圖片描述
成功,點擊註銷(剛剛http.logout()的作用),再換成lion用戶試試,看看能否顯示絕世武功祕籍:

在這裏插入圖片描述
簡單記錄到這裏,由於springsecurity的具體知識我也還沒有學過,覺得挺方便的,之後找機會補完這方面的知識,再着重記錄。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章