單機 Session 管理:
本文Demo 基於 springboot 2.0.1版本.
spring security 中提供了很好的 session 配置管理。包括session 無效處理、session 並發控制、session過期等相應處理配置。
在 Security 的配置中我們重寫了 protected void configure(HttpSecurity http) 方法,在里面可以可以通過以下配置來達到以上描述的 Session 相關配置。
http.sessionManagement() // .invalidSessionUrl("http://localhost:8080/#/login")
.invalidSessionStrategy(invalidSessionStrategy)//session無效處理策略
.maximumSessions(1) //允許最大的session // .maxSessionsPreventsLogin(true) //只允許一個地點登錄,再次登陸報錯
.expiredSessionStrategy(sessionInformationExpiredStrategy) //session過期處理策略,被頂號了
;
invalidSessionUrl : 配置當 session 無效的時候的跳轉地址,我們可以配置成當前系統的登錄頁即可。
invalidSessionStrategy:配置 session 無效時的處理策略,需要實現 InvalidSessionStrategy 接口,重寫對應方法,默認為 SimpleRedirectInvalidSessionStrategy ,可以參考這個類來寫我們的實現。這里就寫的簡單點如下:
public class WuzzInvalidSessionStrategy implements InvalidSessionStrategy { @Override public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String message = "session已失效"; response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(message)); } }
maximumSessions : 配置允許同時登陸的最大session數。這里配置成 1,當用戶在不同瀏覽器,或者不同機器下重復登陸后,系統會自動將前一次登錄的 session 踢出,此時session 將會進入過期處理策略。
maxSessionsPreventsLogin : 當同時登陸的最大sseion 數達到 maximumSessions 配置后,拒絕后續同賬戶登錄,拋出信息 :Maximum sessions of 1 for this principal exceeded
expiredSessionStrategy : session過期處理策略 ,需要實現 SessionInformationExpiredStrategy 接口,默認實現 SimpleRedirectSessionInformationExpiredStrategy。這里簡單做一下實現:
public class WuzzExpiredSessionStrategy implements SessionInformationExpiredStrategy { /* (non-Javadoc) * @see org.springframework.security.web.session.SessionInformationExpiredStrategy#onExpiredSessionDetected(org.springframework.security.web.session.SessionInformationExpiredEvent) */ @Override public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException { String message = "session過期處理。"; event.getResponse().setStatus(HttpStatus.UNAUTHORIZED.value()); event.getResponse().setContentType("application/json;charset=UTF-8"); event.getResponse().getWriter().write(JSON.toJSONString(message)); } }
集群 Session 管理:
session 存儲策略配置,security 給我們提供了一個參數配置 session 存儲策略類型 spring.session.store-type = REDIS,可配置類型由 org.springframework.boot.autoconfigure.session.StoreType 類決定。REDIS,MONGODB,JDBC,HAZELCAST,NONE
重點說一下Redis backed sessions:要實現 redis +security整合,步驟如下:
1.導入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
2.修改配置項:
spring.session.store-type = REDIS # Redis服務地址 spring.redis.host=192.168.1.101 # Redis服務端口 spring.redis.port=6379 # Redis 連接密碼 spring.redis.password=wuzhenzhao
3.啟動類配置上注解 @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)。標識啟用Redis 的session管理策略。
4.驗證,此時將項目分別在 8080、8081兩個端口上啟動。在 8080 端口的服務上做登錄,將會在 redis上看到類似一下信息:
登陸成功后直接訪問 8081 受保護的資源,結果發現無需重復登陸。