将 spring-session 和 Redis 添加到现有的 Spring Boot Spring Security 配置中

Posted

技术标签:

【中文标题】将 spring-session 和 Redis 添加到现有的 Spring Boot Spring Security 配置中【英文标题】:Adding spring-session & Redis to existing Spring Boot Spring Security configuration 【发布时间】:2015-04-19 17:56:42 【问题描述】:

目前我们有一个 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();
        
    

如果您尝试在 2 个不同的会话中使用相同的用户帐户登录,第二次尝试将失败,直到当前用户按预期和要求注销。

这在单实例环境中效果很好,但我们想部署到 Herkou 上的多个 dyno,因此需要外部化会话。

spring-session + spring-boot-starter-redis 似乎是一个很好的选择。

从 spring-session 文档中,它提到我们需要做的就是添加注释 @EnableRedisHttpSession 并定义一个 JedisConnectionFactory

这确实有效,并且添加该注释会导致会话存储在 Redis 中,我可以使用 redis-cli 看到。

但是,添加此注释会破坏并发控制。

添加注释@EnableRedisHttpSession 后,SessionRegistryImpl 方法将永远不会被调用,HttpSessionEventPublisher.sessionCreated()/sessionDestroy() 方法也不会被调用。

这意味着当当前用户注销时,尝试使用该用户名的其他会话仍然无法登录,并且刚刚注销的用户将无法重新登录。这是因为会话永远不会从???registry/repository???

中删除

任何关于如何让我的会话创建/销毁工作的见解,同时使用 redis 作为存储,将不胜感激。

【问题讨论】:

【参考方案1】:

我们目前不支持 Spring Security 的并发控制和 Spring Session。你可以在 GitHub 上找到existing issue。

一般的想法是使用 Spring Session 的 SessionRepository 接口来实现 Spring Security 的 SessionRepository 接口。

如果您想提交 PR,我们将不胜感激!

【讨论】:

以上是关于将 spring-session 和 Redis 添加到现有的 Spring Boot Spring Security 配置中的主要内容,如果未能解决你的问题,请参考以下文章

spring-session用redis实现session共享实践

Spring-session整合到Redis

原保存一下之前spring-session的redis单点登录配置文件跨域

Spring-Session+Redis实现session共享

spring-session redis集群配置步骤总结

spring-session实现session共享案例(单点登录)