SpringBoot安全篇Ⅵ --- 整合Spring Security


知識儲備:

關於SpringSecurity的詳細學習可以查看SpringSecurity的官方文檔

Spring Security概覽

應用程序的兩個主要區域是"認證"和"授權"(訪問控制)。這兩個主要區域是Spring Security的兩個目標。

"認證"(Authentication),是建立一個他聲明的主體的過程(一個"主體"一般是指用戶,設備或一些可以在你的應用程序中執行動作的其他系統)。

"授權"(Authorization)指確定一個主體是否允許在你的應用程序執行一個動作的過程。為了抵達需要授權的點, 主體的身份已經有認證過程建立。

一.Spring Security快速入門

1.1 導入spring-boot-starter-security

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

1.2 編寫SpringSecurity的配置類,該類需要繼承WebSecurityConfigurerAdapter

這邊需要開啟基於WebSecurity的注解,由於這個注解內部以及有了@Configuration,所以不需要再加上@Configuration了。

@EnableWebSecurity //開啟基於WebSecurity的注解(已經開啟了@Configuration)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

}

1.3 在配置類中定制授權規則

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //定制請求的授權規則
        http.authorizeRequests().antMatchers("/").permitAll() //讓所有人可以訪問首頁
        .antMatchers("/level1/**").hasRole("VIP1")
        .antMatchers("/level2/**").hasRole("VIP2")
        .antMatchers("/level3/**").hasRole("VIP3");
        //訪問測試

        //開啟自動配置的登陸功能,如果沒有登錄,則會來到登錄頁面
        http.formLogin();
        //該功能開啟之后的效果:SpringSecurity自動處理的請求
        //1、/login 來到登錄頁
        //2、重定向到 /login?error 表示登錄失敗
        //3、更多信息

    }

1.4 定義認證規則

這邊需要注意的是如果不用PasswordEncoder去驗證密碼會報錯誤,這里是解決方案

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //super.configure(auth);
        //auth.jdbcAuthentication()
        //內存用戶驗證
    /*    auth.inMemoryAuthentication().withUser("wang").password("123456").roles("VIP1","VIP2").and()
                .withUser("xia").password("654321").roles("VIP2","VIP3");  //表單提交的時候密碼是以密文匹配,會報錯*/
        auth.inMemoryAuthentication()
                .passwordEncoder(new MyPasswordEncoder())
                .withUser("wang").password("123456").roles("VIP1","VIP2").and()
                .withUser("yun").password("123456").roles("VIP3"); //表單提交的時候密碼是以明文匹配

    }

二.注銷

在protected void configure(HttpSecurity http) throws Exception(){}方法中開啟自動配置的注銷功能:

http.logout()

開啟后默認規則:

1.訪問/logout表示用戶注銷,清空session

2.注銷成功會返回/login?logout頁面

配置注銷以后直接來到首頁;

http.logout().logoutSuccessUrl("/"); //注銷以后來到首頁

完整代碼:

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //定制請求的授權規則
        http.authorizeRequests().antMatchers("/").permitAll() //讓所有人可以訪問首頁
        .antMatchers("/level1/**").hasRole("VIP1")
        .antMatchers("/level2/**").hasRole("VIP2")
        .antMatchers("/level3/**").hasRole("VIP3");
        //訪問測試

        //開啟自動配置的登陸功能,如果沒有登錄,則會來到登錄頁面
        //SpringSecurity自動處理的請求
        //默認規則
        //1、/login 來到登錄頁
        //2、重定向到 /login?error 表示登錄失敗
        //3、更多信息
        http.formLogin();



        //開啟自動配置的注銷功能
        //默認規則
        //1.訪問/logout表示用戶注銷,清空session
        //2.注銷成功會返回/login?logout頁面

        http.logout().logoutSuccessUrl("/"); //注銷以后來到首頁
    }

三.權限控制

3.1 版本依賴

使用這項功能前需要先將SpringBoot版本切換為1.5.6.RELEASE,SpringBoot2.x的版本使用時遇到了一些問題所以我將SpringBoot版本降級了。如果有Springboot2.x整合Spring Security成功使用權限控制的可以教教我。。。

將SpringBoot版本變為1.5.6.RELEASE后需要將thymeleaf的版本也切換一下:

<properties>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>
<thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.version>
</properties>

在html使用spring security標簽還需要導入thymeleaf-extra-springsecurity4包,版本為上面的版本3.0.2.RELEASE

<dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>     
 </dependency>

3.2 權限控制

首先引入標簽庫

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">

如果沒有認證則顯示下面內容:

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

如果角色認證了顯示出角色的信息:

<!--如果認證了-->
<div sec:authorize="isAuthenticated()">
    <h2><span sec:authentication="name"></span>,您好,您的角色有<span sec:authentication="principal.authorities"></span></h2>
    <form th:action="@{/logout}" method="post">
        <input type="submit" value="注銷"/>
    </form>
</div>

控制只有擁有某個權限時才能顯示該內容

<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>

四.記住我

在protected void configure(HttpSecurity http) throws Exception(){}方法中開啟記住我功能:

//開啟記住我功能
 http.rememberMe();

開啟該功能后,登陸頁面會自動多一個記住我的復選框按鈕。

 

勾選登陸后,會自動生成cookie,下次訪問時無需登陸即可訪問。

 

五.自定義登陸頁

上述功能都是基於默認規則的登錄功能,那么如何制定自己的登錄頁呢?

5.1 定制Controller登錄頁

/*
     * 登陸頁
     * @return
     */
    @GetMapping("/userlogin")
    public String loginPage() {
        return PREFIX+"login";
    }
    

5.2 在protected void configure(HttpSecurity http) throws Exception(){}中配置:

http.formLogin().usernameParameter("user").passwordParameter("pwd").loginPage("/userlogin");

一旦定制loginPage,那么loginPage的post請求就是登錄。

5.3 登錄的表單

<div align="center">
        <form th:action="@{/userlogin}" method="post">
            用戶名:<input name="user"/><br>
            密碼:<input name="pwd"><br/>
            <input type="checkbox" name="remeber"/>記住我 <br/>
            <input type="submit" value="登陸">
        </form>
</div>

5.4 自定義記住我功能

//開啟記住我功能
http.rememberMe().rememberMeParameter("remeber");

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM