Spring Security系列教程之會話管理處理會話過期問題
前言
在上一章節中,一一哥 給各位講解瞭HTTP協議、會話、URL重新、會話固定攻擊等概念,並且實現瞭對會話固定攻擊的防禦攔截。
在Spring Security中,其實除瞭可以對會話固定攻擊進行攔截之外,還可以對會話過期進行處理,也就是會話可能會過期,過期瞭該怎麼處理。接下來請各位跟著 壹哥 繼續學習,看看會話過期時到底怎麼處理的吧。
一. 會話過期
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;
自定義過期策略。
二. 會話過期時的處理策略(一)
在上面的章節中,我給各位介紹瞭在會話過期時,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執行瞭..."); } //定義一個會話過期後要跳轉到的接口 @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類
我們創建一個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會話過期內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringBoot淺析安全管理之Spring Security配置
- Spring boot整合security詳解
- Spring Boot security 默認攔截靜態資源的解決方法
- java SpringSecurity使用詳解
- 一文詳解Spring Security的基本用法