SpringBoot2.x 集成 Spring Security


目前Web開發常用的兩個安全框架:Apache Shiro 和 Spring Security,這里學習的是Spring Security,Spring Security本身是Spring社區的一個子架構,相對而言對Spring有更好的支持。

Spring Security官方文檔:https://docs.spring.io/spring-security/site/docs/

安全框架基本概念:

  • “認證” (Authentication):身份認證/登錄,驗證用戶是不是擁有相應的身份;
  • “授權”(Authorization) :授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限;即判斷用戶是否能做事情,常見的如:驗證某個用戶是否擁有某個角色。

下面開始集成SpringSecurity到SpringBoot中

1. 引入Maven依賴

視圖框架采用的SpringBoot推薦的Thymeleaf,Thymeleaf框架對Spring Security有擴展支持,只需要引入相應Jar就好。SpringBoot2.1.X版本默認集成的是Security5

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

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

<!--thymeleaf對security5的支持依賴-->
 <dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    <version>3.0.4.RELEASE</version>
 </dependency>

 thymeleaf-extras-springsecurity5的使用可以參照文檔:https://github.com/thymeleaf/thymeleaf-extras-springsecurity

說明:thymeleaf-extras-springsecurity5和thymeleaf-extras-springsecurity4有所不同,IDEA對5支持不好,於是我自己在頁面中使用的還是4

 

2. 編寫Security配置類

 Spring Security比較重要的幾個類

  • WebSecurityConfigurerAdapter:自定義Security策略,配置類需要繼承這個類,實現其兩個configure方法(認證和授權)
  • AuthenticationManagerBuilder:自定義認證策略
  • HttpSecurity:自定義授權策略
  • @EnableWebSecurity:開啟WebSecurity模式
/**
 * 自定義Security配置類
 *
 * @author azure
 * @since 2019/10/12
 */
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 認證
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication() // 項目啟動 賬戶-密碼-角色 信息保存進內存中
                  .withUser("zhangsan").password("{noop}123456").roles("VIP1")
            .and().withUser("lisi").password("{noop}123456").roles("VIP1, VIP2")
            .and().withUser("wangwu").password("{noop}123456").roles("VIP1", "VIP2", "VIP3");

        /*
          說明:
            1.這里采用的的是把用戶角色保存在內存中,數據是寫死的,當然數據可以從數據庫中查出再寫入內存中;
            2.隨后定義的三個用戶,沒有用戶定義了其用戶名,密碼和角色
            3.Security5默認要求密碼使用加密,不加密的話就使用"{noop}123456"這樣的寫法,加密的話需要使用
                PasswordEncoder的實現類進行加密
         */
    }

    /**
     * 授權
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
     // 禁止隧道 // 禁止跨域 // 禁止頭部 
     http.csrf().disable().cors().disable().headers().disable();


        // 所有的人都可以訪問的路徑
        http.authorizeRequests().antMatchers("/", "/webjars/**", "/static/**").permitAll()
                // VIP1的用戶可以訪問level1下的所有路徑
                .antMatchers("/level1/**").hasRole("VIP1")
                // VIP2的用戶可以訪問level2下的所有路徑
                .antMatchers("/level2/**").hasRole("VIP2")
          // VIP3的用戶可以訪問level3下所有的路徑 .antMatchers(
"/level3/**").hasRole("VIP3"); /* 開啟自動配置的登錄功能,如果沒有登錄就會來到登錄頁面 1. 會自動生成登錄頁面 /login 2. 登錄失敗會自動重定向到 /login?error */ http.formLogin() /* 自定義登錄頁面設置 1. 登錄的路徑還是設置成/login,否則算是自定義登錄路徑,其他的設置也需要改變 /login(get):到登錄頁,, 自定義的話就是 /authenticate(get) /login(post):登錄檢查,,自定義的話就是 /authenticate(post) 2. 可以自定義form表達提交的參數名稱 默認username字段提交用戶名,可以通過usernameParameter自定義 默認password字段提交密碼,可以用過passwordParameter自定義 3. loginProcessingUrl("/xxx") 可以自定義登錄成功后跳轉的路徑 */ .loginPage("/login"); /* 開啟自動配置的記住我功能 1.登錄成功后,將cookie發送給瀏覽器保存,以后登錄帶上這個cookie,只要通過檢查就可以免登錄 2.點擊注銷之后會刪除cookie 3.rememberMe功能跟前端約定的表單提交名稱是remember-me,可以通過rememberMeParameter自定義 */ http.rememberMe(); //.rememberMeParameter("remember")自定義表單提交名稱為remember /* 開啟自動配置的退出功能: 1. 訪問/logout請求,用戶注銷,清楚session 2. 注銷成功后重定向到 login?logout,,可以通過logoutSuccessUrl("/")自定義 */ http.logout().logoutSuccessUrl("/"); } }

 

 3. 頁面端編寫

頁面引入thymeleaf對security支持的命名空間支持:xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4,其中常用的屬性和方法如下:

  • sec:authorize="isAuthenticated()":是否授權成功
  • sec:authentication="principal.authorities":獲取用戶所擁有的角色
  • sec:authentication="name":獲取用戶名字
  • sec:authorize="hasRole("xxx")":判斷當前用戶是否擁有指定角色

首頁:主要是對用戶權限的控制

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首頁</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>
            <small sec:authentication="principal.authorities"></small>
        </h2>
        <form th:action="@{/logout}" method="post">
            <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>

 

 登錄頁:主要是登錄路徑和提交用戶名密碼的名稱(security默認的是:/login,username,password,remember-me  但是都支持自定義)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <title>登錄</title>
    <link th:href="@{/webjars/bootstrap/4.3.1/css/bootstrap.css}" rel="stylesheet">
    <link th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head>
<body class="text-center">
    <form class="form-signin" th:action="@{/login}" method="post">
      <img class="mb-4" th:src="@{/asserts/images/bootstrap-solid.svg}" alt="" width="72" height="72">
      <h1 class="h3 mb-3 font-weight-normal">請登錄</h1>
      <label for="username" class="sr-only">username</label>
      <input type="text" id="username" name="username" class="form-control" placeholder="username" required="" autofocus="">
      <label for="password" class="sr-only">Password</label>
      <input type="password" id="password" name="password" class="form-control" placeholder="password" required="">
      <div class="checkbox mb-3">
          <label>
              <input type="checkbox" name="remember-me"> 記住我
          </label>
      </div>
      <button class="btn btn-lg btn-primary btn-block" type="submit">登錄</button>
      <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
    </form>
</body>
</html>

 

 4.參照

SpringBoot 2.x - SpringSecurity(內存管理版)

springboot2.1.2+springsecurity5.1.3+thymeleaf3.0.11 sec標簽不生效

 springsecurity5+thymeleaf3的sec:authorize標簽問題

 


免責聲明!

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



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