一、session过期处理 我们知道session默认的过期时间是30分钟,为了快速实现session过期后如何处理,我们将session设置成1分钟,当然security里面要求session最少过期时间是1分钟,如果设置的少于1分钟会当成1分钟处理。 1) application.properties中设置session过期时间

server.servlet.session.timeout=60s
  1. 在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,这样就实现了一个账号仅能一处登录了。