单机 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 受保护的资源,结果发现无需重复登陆。