【问题标题】:SAML authenticated users don't appear in Spring Security's SessionRegistrySAML 身份验证的用户不会出现在 Spring Security 的 SessionRegistry 中
【发布时间】:2015-04-20 22:55:48
【问题描述】:

我们的应用程序过去只有一种登录方式:用户名和密码。一旦新用户登录到应用程序,他们的会话就会出现在 Spring Security 的 SessionRegistry 中。

现在我在 Spring SAML 的帮助下实现了 SAML 支持。我将设置重点放在sample application's configuration 上。一切正常。但是我注意到通过 SAML 登录的用户不会将他们的会话添加到 SessionRegistry

基于表单的身份验证的常用上下文文件包含以下内容:

<session-management 
  invalid-session-url="/login"
  session-fixation-protection="newSession"
  session-authentication-error-url="/login?invalid_session=1">

  <concurrency-control
    max-sessions="1"
    error-if-maximum-exceeded="false"
    session-registry-alias="springSessionRegistry"/>

</session-management>

在我的 SAML 配置的 http 元素中,我添加了相同的内容。这创建了一个新的SessionRegistry,但它不包含任何内容。我也试过了

<concurrency-control session-registry-ref="springSessionRegistry"/>

但这也不包含任何经过 SAML 身份验证的会话。

那么如何访问 SAML 会话?

【问题讨论】:

    标签: java spring session spring-security spring-saml


    【解决方案1】:

    问题在于 Spring Security 的 bean 定义解析器仅自动将基于 session-managementconcurrency-control 创建的 bean 链接到核心 Spring Security 模块中包含的身份验证处理器。这意味着,SAMLProcessingFilter.setSessionAuthenticationStrategy() 没有被调用。

    您应该能够通过以下方式声明samlWebSSOProcessingFilter bean 来使其工作(它指的是由concurrency-control 元素自动创建的并发bean):

    <bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="authenticationSuccessHandler" ref="successRedirectHandler"/>
        <property name="authenticationFailureHandler" ref="failureRedirectHandler"/>
        <property name="sessionAuthenticationStrategy" ref="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy#0"/>
    </bean>
    

    【讨论】:

    • 我不得不使用CompositeSessionAuthenticationStrategy#2,因为我有多个http 元素。我敢肯定这是一个非常脆弱的设置。我想我必须手动创建自己的会话控制策略以使其可靠,因为它是impossible to refer to the strategy in a reliable way。感谢您的出色图书馆和您提供的支持!
    • 很高兴它有帮助。我同意这远非理想,创建自己的策略绝对是更好的选择。从长远来看,我将尝试调用直接包含在 bean def 中的此类。解析器。
    • 谢谢@VladimírSchäfer
    • @VladimírSchäfer 你有 samlWebSSSOProcessing 过滤器的 Java 配置示例吗?我们有同样的问题:使用 samlWebSSOProcessingFilter.setSessionAuthenticationStrategy(new ConcurrentSessionControlAuthenticationStrategy),用户不会添加到 SessionRegistry。
    • 最后,我明白我的问题是我只是向 samlWebSSOProcessingFilter.setSessionAuthenticationStrategy 添加了一个 ConcurrentSessionControlAuthenticationStrategy,我需要一个 CompositeSessionAuthenticationStrategy,带有 ConcurrentSessionStrat 和一个 RegisterSessionAuthenticationStrategy,否则新登录的用户不是在 Spring Security 的 SessionRegistry 中注册。
    【解决方案2】:

    正如我在 Vladimir 回答的评论中所说,我的问题是我只向 samlWebSSOProcessingFilter 添加了一个 ConcurrentSessionControlAuthenticationStrategy,因此,新登录的用户没有在 Spring Security 的 SessionRegistry 中注册。

    为了解决这个问题,我创建了一个这样的 CompositeSessionAuthenticationStrategy:

       @Bean
        public SAMLProcessingFilter samlWebSSOProcessingFilter() throws Exception {
            SAMLProcessingFilter samlWebSSOProcessingFilter = new SAMLProcessingFilter();
            samlWebSSOProcessingFilter.setAuthenticationManager(authenticationManager());
            samlWebSSOProcessingFilter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler);
            samlWebSSOProcessingFilter.setAuthenticationFailureHandler(authenticationFailureHandler());
    
            samlWebSSOProcessingFilter.setSessionAuthenticationStrategy(authStrategy());
            
            return samlWebSSOProcessingFilter;
        }
        
        /**
         * @return the strategy for the SAML authentication: ConcurrentSessionControl (max 1 session per user)
         *      + RegisterSessionAuthStrat (otherwise, the session of the users are not tracked when they authenticate with SAML)
         *
         * @author Cyril Gambis
         * @date 27 juil. 2020
         */
        private CompositeSessionAuthenticationStrategy authStrategy() {
            List<SessionAuthenticationStrategy> strategies = new ArrayList<>();
            
            ConcurrentSessionControlAuthenticationStrategy concurrentStrategy = new ConcurrentSessionControlAuthenticationStrategy(this.sessionRegistry);
            concurrentStrategy.setExceptionIfMaximumExceeded(false);
    
            RegisterSessionAuthenticationStrategy registerStrategy = new RegisterSessionAuthenticationStrategy(this.sessionRegistry);
            
            strategies.add(concurrentStrategy);
            strategies.add(registerStrategy);
            
            CompositeSessionAuthenticationStrategy compositeStrategy = new CompositeSessionAuthenticationStrategy(strategies);
            
            return compositeStrategy;
        }
    

    现在,新用户已正确注册。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 2012-03-24
      • 2011-11-14
      • 2017-07-17
      • 2013-10-01
      • 2020-11-04
      相关资源
      最近更新 更多