Spring Security系列教程之會話管理處理會話過期問題
前言
在上一章節(jié)中,一一哥 給各位講解了HTTP協議、會話、URL重新、會話固定攻擊等概念,并且實現了對會話固定攻擊的防御攔截。
在Spring Security中,其實除了可以對會話固定攻擊進行攔截之外,還可以對會話過期進行處理,也就是會話可能會過期,過期了該怎么處理。接下來請各位跟著 壹哥 繼續(xù)學習,看看會話過期時到底怎么處理的吧。
一. 會話過期
1. 會話過期概念
在處理會話過期之前,我們首先得知道啥是會話過期。
所謂的會話過期,是指當用戶登錄網站后,較長一段時間沒有與服務器進行交互,將會導致服務器上的用戶會話數據(即session)被銷毀。此時,當用戶再次操作網頁時,如果服務器進行了session校驗,那么瀏覽器將會提醒用戶session超時,導致這個問題的關鍵詞有兩個:一個是「長時間」,一個是「未操作」。
2. Session的超時時間
既然會話會過期,就得有個過期時間,默認情況下,Session的過期時間是30分鐘,當然我們可以在yml配置文件手動修改會話的過期時間。
server:
servlet:
session:
#會話過期時間默認是30m過期,最少為1分鐘
timeout: 60s
另外會話的過期時間最少為1分鐘,即便我們設置為小于60秒,也會被修正為1分鐘,在Spring Boot的TomcatServletWebServerFactory類中,對此有默認實現,源碼如下:
private long getSessionTimeoutInMinutes() {
Duration sessionTimeout = getSession().getTimeout();
if (isZeroOrLess(sessionTimeout)) {
return 0;
}
return Math.max(sessionTimeout.toMinutes(), 1);
}
private boolean isZeroOrLess(Duration sessionTimeout) {
return sessionTimeout == null || sessionTimeout.isNegative() || sessionTimeout.isZero();
}
3. 會話過期時的處理策略
你可能會問,萬一會話過期了怎么辦呢?別擔心!
默認情況下,在會話過期時,Spring Security為我們提供了2種處理策略:
跳轉到某個指定的URL;
自定義過期策略。
二. 會話過期時的處理策略(一)
在上面的章節(jié)中,我給各位介紹了在會話過期時,Spring Security給我們提供了2種處理策略,我們先學習第一種處理策略,即當會話過期時跳轉到某個指定的URL,接下來請看代碼實現。
1. 配置會話過期時間
為了方便驗證測試,我們先把會話的過期時間設置為60秒,這樣會話在很短時間內就可以過期。
server:
servlet:
session:
#會話過期時間默認是30m過期,最少為1分鐘
timeout: 60s
2. 定義測試接口
接下來我們定義幾個測試接口,并且定義一個用來處理會話過期的接口“/session/inval”。
@RestController
public class UserController {
@GetMapping("/user/hello")
public String helloUser() {
return "hello, user";
}
@GetMapping("/admin/hello")
public String helloAdmin() {
return "hello, admin";
}
@GetMapping("/app/hello")
public String helloApp() {
return "hello, app";
}
@RequestMapping("/logout")
public void logout(HttpSession session){
session.invalidate();
System.out.println("logout執(zhí)行了...");
}
//定義一個會話過期后要跳轉到的接口
@GetMapping("/session/invalid")
public String invalid(){
return "會話過期invalid...";
}
}
3. 配置跳轉到某個URL
我們還是在之前的SecurityConfig類中,進行會話過期效果的配置實現,主要是利用invalSessionUrl()方法來實現。
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/user/**")
.hasRole("USER")
.antMatchers("/app/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.csrf()
.disable()
.formLogin()
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
//注銷成功,重定向到該路徑下
.logoutSuccessUrl("/login")
//使得session失效
.invalidateHttpSession(true)
//清除認證信息
.clearAuthentication(true)
.and()
//進行會話管理
.sessionManagement()
.sessionFixation()
//設置會話固定防御策略
.migrateSession()
//配置會話過期策略
.invalidSessionUrl("/session/invalid");
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
4. 啟動測試
我們把項目重啟,然后訪問/user/hello接口,在我們登陸認證成功后就可以正常訪問/user/hello接口。

這時候如果我們把當前窗口頁面關閉,經過60秒后,會話就會過期,等再次訪問/user/hello接口,就可以看到如下效果,即跳轉到了我們指定的會話過期界面。

三. 會話過期時的處理策略(二)
我在上面說了,會話過期之后的處理策略,除了上面跳轉到指定的URL方案之外,我們還可以自定義會話過期策略,其代碼如下。
1. 自定義MyInvalSessionStrategy類
我們創(chuàng)建一個MyInvalSessionStrategy類,實現InvalSessionStrategy接口,在這里進行會話過期時的處理邏輯。
//我們先定義一個處理會話過期的策略類
public class MyInvalidSessionStrategy implements InvalidSessionStrategy {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("session無效");
}
}
2. 配置自定義過期策略
接下來我們把上面定義的MyInvalSessionStrategy類,通過invalSessionStrategy()方法,設置自定義的會話過期策略。
//然后在配置文件中關聯處理會話過期策略
@EnableWebSecurity(debug = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/user/**")
.hasRole("USER")
.antMatchers("/app/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.csrf()
.disable()
.formLogin()
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
//注銷成功,重定向到該路徑下
.logoutSuccessUrl("/login")
//使得session失效
.invalidateHttpSession(true)
//清除認證信息
.clearAuthentication(true)
.and()
//進行會話管理
.sessionManagement()
.sessionFixation()
//設置會話固定防御策略
.migrateSession()
//配置會話過期策略
//.invalidSessionUrl("/session/invalid")
//設置會話過期策略
.invalidSessionStrategy(new MyInvalidSessionStrategy());
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
至此,壹哥就帶各位實現了在會話過期時的代碼處理方案了,你學會了嗎?
到此這篇關于Spring Security系列教程之會話管理處理會話過期問題的文章就介紹到這了,更多相關Spring Security會話過期內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何解決SpringBoot定時任務報錯Unexpected error occurred 
這篇文章主要介紹了如何解決SpringBoot定時任務報錯Unexpected error occurred in scheduled task問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
Java?C++算法題解leetcode801使序列遞增的最小交換次數
這篇文章主要為大家介紹了Java?C++題解leetcode801使序列遞增的最小交換次數示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
Java ArrayList.toArray(T[]) 方法的參數類型是 T 而不是 E的原因分析
這篇文章主要介紹了Java ArrayList.toArray(T[]) 方法的參數類型是 T 而不是 E的原因分析的相關資料,需要的朋友可以參考下2016-04-04
MyEclipse 2016 CI 4新增BootStrap模板
MyEclipse2016是一款全球使用最為廣泛的企業(yè)級開發(fā)環(huán)境程序,這篇文章主要介紹了MyEclipse 2016 CI 4新增BootStrap模板的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06

