2

現在、spring-security が正常に実行されている spring-boot (1.2.1.RELEASE) アプリケーションがあります。

次の構成で同時実行制御を正常に実装しました

@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 つの異なるセッションで同じユーザー アカウントを使用してログインしようとすると、現在のユーザーがログアウトするまで、2 回目の試行は失敗します。

これは単一インスタンス環境ではうまく機能しますが、Herkou の複数の dyno にデプロイしたいので、セッションを外部化する必要があります。

spring-session + spring-boot-starter-redis は、これに最適な候補のようです。

spring-session のドキュメントから、アノテーション@EnableRedisHttpSessionを追加してJedisConnectionFactory.

これは実際に機能し、その注釈を追加すると、セッションが Redis に保存されます。これは、redis-cli を使用して確認できます。

ただし、この注釈を追加すると、同時実行制御が壊れます。

注釈@EnableRedisHttpSessionを追加すると、SessionRegistryImplメソッドが呼び出されることはなく、メソッドも呼び出されませんHttpSessionEventPublisher.sessionCreated()/sessionDestroy()

これは、現在のユーザーがログアウトすると、そのユーザー名を使用しようとしている他のセッションはログインできず、ログアウトしたばかりのユーザーは再ログインできないことを意味します。これは、セッションが ???registry/repository??? から削除されないためです。

ストアとしてredisを使用しながら、セッションの作成/破棄を機能させる方法についての洞察をいただければ幸いです。

4

1 に答える 1