1. 程式人生 > 其它 >SpringSecurity學習記錄4

SpringSecurity學習記錄4

技術標籤:SpringSecurity

2.12 RememberMe功能實現

Spring Security 中Remember Me為“記住我” 功能,使用者只需要在登入時新增 remember me 複選框,取值為 true Spring Security會自動把使用者資訊儲存到資料來源中,以後就可以不登入進行訪問。

新增依賴

Spring Security 實 現 Remember Me 功 能 時 底 層 實 現 依 賴Spring-JDBC,所以需要匯入 SpringJDBC。以後多使用 MyBatis 框架而很少直接匯入 spring-jdbc,所以此處匯入 mybatis 啟動器同時還需 要新增 MySQL 驅動

<!-- mybatis 依賴 -->
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.1</version>
</dependency>
<!-- mysql 資料庫依賴 -->
<dependency>
   <groupId>mysql</
groupId
>
<artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency>

配置資料來源

在 application.properties 中配置資料來源。請確保資料庫中已經存在shop資料庫

spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver
spring.datasource.url= jdbc:mysql://localhost:3306/security?
useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username= root
spring.datasource.password= root

編寫配置

RememberMeConfig.java

package com.xxxx.springsecuritydemo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;
/**
* @author zhoubin
* @since 1.0.0
*/
@Configuration
public class RememberMeConfig {
   @Autowired
   private DataSource dataSource;
   @Bean
   public PersistentTokenRepository getPersistentTokenRepository(){
      JdbcTokenRepositoryImpl jdbcTokenRepository = new
JdbcTokenRepositoryImpl();
      jdbcTokenRepository.setDataSource(dataSource);
      //自動建表,第一次啟動時需要,第二次啟動時註釋掉
      jdbcTokenRepository.setCreateTableOnStartup(true);
      return jdbcTokenRepository;
   }
}

修改SecurityConfig.java

在SecurityConfig中新增RememberMeConfig和UserDetailsService實現類物件,並自動注入。 在 configure 中新增下面配置內容。

http.rememberMe()
      //登入邏輯交給哪個物件
     .userDetailsService(userService)
      // 持久層物件
     .tokenRepository(persistentTokenRepository);

在客戶端頁面新增複選框

在客戶端登入頁面中新增 remember-me 的複選框,只要使用者勾選了複選框下次就不需要進行登入了。

<form action="/login" method="post">
   使用者名稱:<input type="text" name="username" /><br/>
   密碼:<input type="password" name="password" /><br/>
    <input type="checkbox" name="remember-me" value="true"/><br/>
    <input type="submit" value="登入" />
</form>

有效時間

啟專案後登入狀態失效了。但是可以通過設定狀態有效時間,即使專案重新啟動下次也可 以正常登入。

http.rememberMe()
      //失效時間,單位秒
     .tokenValiditySeconds(120)
      //登入邏輯交給哪個物件
     .userDetailsService(userService)
      // 持久層物件
     .tokenRepository(persistentTokenRepository);

2.13 退出登入

使用者只需要向 Spring Security 專案中傳送 /logout 退出請求即可。

實現退出非常簡單,只要在頁面中新增 /logout 的超連結即可。

<a href="/logout">退出登入</a>

為了實現更好的效果,通常新增退出的配置。預設的退出 url 為 /logout ,退出成功後跳轉到 /login? logout

image-20210102100401846

如果不希望使用預設值,可以通過下面的方法進行修改。

http.logout()
     .logoutUrl("/logout")
     .logoutSuccessUrl("/login.html");

2.14 SpringSecurity中的CSRF

從剛開始學習Spring Security時,在配置類中一直存在這樣一行程式碼: http.csrf().disable(); 如 果沒有這行程式碼導致使用者無法被認證。這行程式碼的含義是:關閉 csrf 防護。

什麼是CSRF

CSRF(Cross-site request forgery)跨站請求偽造,也被稱為“OneClick Attack” 或者 Session Riding。通過偽造使用者請求訪問受信任站點的非法請求訪問。 跨域:只要網路協議,ip 地址,埠中任何一個不相同就是跨域請求。 客戶端與服務進行互動時,由於 http 協議本身是無狀態協議,所以引入了cookie進行記錄客戶端身 份。在cookie中會存放session id用來識別客戶端身份的。在跨域的情況下,session id 可能被第三方 惡意劫持,通過這個 session id 向服務端發起請求時,服務端會認為這個請求是合法的,可能發生很多 意想不到的事情。

2、Spring Security中的CSRF

從 Spring Security4開始CSRF防護預設開啟。預設會攔截請求。進行CSRF處理。CSRF為了保證不是 其他第三方網站訪問,要求訪問時攜帶引數名為 _csrf 值為token(token 在服務端產生)的內容,如果 token和服務端的token匹配成功,則正常訪問。

2.1、編寫控制器方法

編寫控制器方法,跳轉到 templates 中 login.html 頁面。

@RequestMapping("/showLogin")
public String showLogin(){
   return "login";
}

2.2、新建login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login" method="post">
    <input type="hidden" th:value="${_csrf.token}" name="_csrf"
th:if="${_csrf}"/>
   使用者名稱:<input type="text" name="username" /><br/>
   密碼:<input type="password" name="password" /><br/>
    <input type="submit" value="登入" />
</form>
</body>
</html>

修改配置類
在配置類中註釋掉 CSRF 防護失效
//關閉csrf防護
// http.csrf().disable();