首先还是吐槽,百度了两天,尝试了十多种方案,各种重写,无效。。。。。最后,还是在官网找到解决方案。
哎。。。已经很多次了。官网。官网。官网。。以后要多看官网。
还是描述下需求吧。很简单,相同的用户登录时,只能保留最后一个session。防止多处登录。也不算是单点。
在开始贴代码之前,各位看官一定要注意条件:
springboot+spring session redis+spring security ,使用java config方式。
可能不使用spring session redis 或者 spring security的情况,不会出现我的问题,因为不涉及redis session的控制。
一般情况下,如果使用spring自带的内存管理方式,非常简单就可以实现(没有尝试,看百度应该问题不大)
springsecurity配置中
@Override protected void configure(HttpSecurity http) throws Exception { .... http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/login?expired"); }所以,解决方案是,在springsecurity配置中,注册spring session redis 的sessionregistry。代码如下:
@Override protected void configure(HttpSecurity http) throws Exception { // 允许所有用户访问"/"和"/register" http.authorizeRequests().antMatchers("/", "/public/**", "/login").permitAll().antMatchers("/admin/**") .hasRole("ADMIN") // 其他地址的访问均需验证权限 .anyRequest().authenticated()// .hasRole("USER") .and().formLogin() // 指定登录页是"/login" .loginPage("/login") // .failureUrl("/login?error=true") .defaultSuccessUrl("/main").permitAll() .and().headers().frameOptions().disable().and().logout() .logoutUrl("/logout").logoutSuccessUrl("/").permitAll(); http.exceptionHandling().accessDeniedPage("/403") .and().csrf().disable(); http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(false).expiredUrl("/login?expired") .sessionRegistry(sessionRegistry()); } @Bean SpringSessionBackedSessionRegistry sessionRegistry() { return new SpringSessionBackedSessionRegistry(getSessionRepository()); } @Autowired JedisConnectionFactory jedisConnectionFactory; @Bean public FindByIndexNameSessionRepository getSessionRepository() { return new RedisOperationsSessionRepository(jedisConnectionFactory); }