SAML经过身份验证的用户不会出现在Spring Security的SessionRegistry中

时间:2015-02-19 14:36:33

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

我们的应用程序过去只有一种登录方式:用户名和密码。一旦新用户登录到该应用程序,他们的会话将出现在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会话?

2 个答案:

答案 0 :(得分:4)

问题是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>

答案 1 :(得分:1)

正如我在对弗拉基米尔的回答的评论中所说的那样,我的问题是我只向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;
    }

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