一、session过期处理 我们知道session默认的过期时间是30分钟,为了快速实现session过期后如何处理,我们将session设置成1分钟,当然security里面要求session最少过期时间是1分钟,如果设置的少于1分钟会当成1分钟处理。 1) application.properties中设置session过期时间
server.servlet.session.timeout=60s
- 在WebSecurityConfigurerAdapter实现类中配置session过期后的跳转路径及设置不拦截该路径
protected void configure(HttpSecurity http) throws Exception {
ValidateCodeFilter validateCodeFilter = new ValidateCodeFilter();
validateCodeFilter.setAuthenticationFailureHandler(failHandler); // 使用我们自定义的失败处理器
http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class) // 在UsernamePasswordAuthenticationFilter过滤器前面增加验证码过滤器
.formLogin()
.loginPage("/authentication/require")
.loginProcessingUrl("/authentication/form")
.successHandler(authentication)
.failureHandler(failHandler)
.and()
.rememberMe()
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(securityProperties.getProperties().getRememberMeSeconds())
.userDetailsService(userDetailsService)
.and()
.sessionManagement()
.invalidSessionUrl("/session/invalid") //session过期跳转路径
.and()
.authorizeRequests()
.antMatchers("/authentication/require",
securityProperties.getProperties().getLoginPage(),
"/code/image",
"/code/sms",
"/session/invalid").permitAll() // 不拦截/code/image
.anyRequest()
.authenticated()
.and()
.csrf().disable();
}
3)处理session过期跳转路径,当session过期后给前端返回session失效信息
@GetMapping("/session/invalid")
@ResponseStatus(code = HttpStatus.UNAUTHORIZED)
public String sessionInvalid(){
String message = "session失效";
return message;
}
在页面中我们可以提示后重定向到登录页面进行登录,这样简单的session过期处理就完成了。 二、session并发控制 有时侯我们会有这样的需求,一个账号只允许一个地方登录。不能同时在两个地方登录一个账号。 1)实现SessionInformationExpiredStrategy,处理同时登录。
public class ExpireSessionStrategy implements SessionInformationExpiredStrategy {
@Override
public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException, ServletException {
event.getResponse().setContentType("application/json;charset=utf-8");
event.getResponse().getWriter().write("并发登录");
}
}
2)后登陆的账号挤掉前面登录的账号,继续配置我们实现的WebSecurityConfigurerAdapter类
.and()
.sessionManagement()
.invalidSessionUrl("/session/invalid")
.maximumSessions(1) // 一个账号同时在线一个用户
.expiredSessionStrategy(new ExpireSessionStrategy())
3)如果一个账号已登录,不允许在进行登录
.and()
.sessionManagement()
.invalidSessionUrl("/session/invalid")
.maximumSessions(1) // 一个账号同时在线一个用户
.maxSessionsPreventsLogin(true) // 如果一个账号已经登录了一个用户,则后面的不让登录
.expiredSessionStrategy(new ExpireSessionStrategy())
ok,这样就实现了一个账号仅能一处登录了。