目前,我们有一个spring-boot (1.2.1.RELEASE)应用程序,spring-security运行成功。
我们已经使用以下配置成功地实现了并发控制
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig {
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@Configuration
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
private static final int MAX_CONCURRENT_USER_SESSIONS = 1;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//snipped
.sessionManagement()
.maximumSessions(MAX_CONCURRENT_USER_SESSIONS)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());
}
@Bean
public SessionRegistry sessionRegistry() {
SessionRegistry sessionRegistry = new SessionRegistryImpl();
return sessionRegistry;
}
@Bean
public static HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
}如果您尝试在两个不同的会话中使用相同的用户帐户登录,第二次尝试将失败,直到当前用户按预期和要求注销为止。
这在单实例环境中工作得很好,但我们希望部署到Herkou上的多个dyno,因此需要将会话外部化。
spring-session + spring-boot-starter-redis似乎是一个很好的候选者。
spring-session文档中提到,我们所需要做的就是添加注释@EnableRedisHttpSession并定义一个JedisConnectionFactory。
这确实有效,添加该注释会导致会话存储在Redis中,我可以使用redis-cli查看。
但是,添加此注释会破坏并发控制。
添加了注释@EnableRedisHttpSession后,永远不会调用SessionRegistryImpl方法和HttpSessionEventPublisher.sessionCreated()/sessionDestroy()方法。
这意味着当当前用户注销时,尝试使用该用户名的其他会话仍将无法登录,并且刚刚注销的用户将无法重新登录。这是因为会话永远不会从注册表/存储库中删除。
任何关于我如何在使用redis作为存储时如何创建/销毁会话的见解都将不胜感激。
发布于 2015-02-19 05:17:45
我们目前不支持Spring Security的并发控制和Spring Session。你可以在GitHub上找到existing issue。
总体思路是使用Spring Session的SessionRepository接口实现Spring Security的SessionRepository接口。
如果你想提交一份公关,将不胜感激!
https://stackoverflow.com/questions/28588587
复制相似问题