Spring Security Saml和SP应用程序的无状态会话

时间:2016-06-28 06:49:34

标签: spring-security spring-boot httpsession spring-saml

我尝试运行启动示例spring security saml boot, https://github.com/vdenotaris/spring-boot-security-saml-sample

我能够运行它并与身份提供者集成。

但是,我发现每次都会创建一个会话并保持持续,直到用户签出。

我正在使用基于资源的服务和spring boot,因此不希望会话开销。

我尝试将以下行添加到configure方法中,  http.sessionManagement()         .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

但是,通过此设置,我总是被要求登录身份提供商。

如果我登录,它会回到页面,要求我再循环登录。

我不确定在禁用会话时这是否是正确的行为。

任何人都可以通过spring security saml扩展和服务提供者应用程序为我提供正确的方法来使用无状态会话。

谢谢,

2 个答案:

答案 0 :(得分:2)

您需要一个会话以确保SAML身份验证部分,因此您有两个选项:

1)您的应用程序中有2个不同的安全上下文,一个用于SAML身份验证,另一个用于无状态服务。不确定如何验证您的服务,但它必须有某种令牌身份验证才能成为无状态。 您可以定义2 WebSecurityConfigurerAdapter并覆盖configure(HttpSecurity http)方法。然后在saml配置中使用http.requestMatchers("/saml/**"),在服务配置中使用http.requestMatchers("/service/**")/saml下的所有内容都将通过saml身份验证,/service下的所有内容都将通过您拥有的其他内容。

2)向SAML配置添加更多过滤器(在saml过滤器之前),以便它可以使用不同类型的auth(例如基于令牌),并且只要此过滤器可以生成有效的在{saml过滤器之前{1}}你应该是好的。

您还可以查看此库:https://github.com/ulisesbocchio/spring-boot-security-saml以简化您的SAML配置

答案 1 :(得分:1)

要在无状态状态下启用SAML,您将需要:

  • 要将SAMLMessageStorageFactory设置为空。
  • 确保SAML过滤器位于“记住我”过滤器之后。
  • 实际上启用无状态并照常配置“记住我”服务。

请注意,这样做意味着您没有JSESSIONID,这意味着spring将不再记录原始请求的URL,因此以后将无法将您重定向回该URL。 (建议稍后解决)。

@Configuration
@EnableWebSecurity
public class YourSecurityConfig extends WebSecurityConfigurerAdapter {
    
    /**
     * Since SAML is being used under a stateless mode, we can not use the default
     * Message Storage factory as it uses http sessions. Instead we have to use
     * the EmptyStorageFactory().
     * 
     */
    @Bean
    public SAMLMessageStorageFactory sAMLMessageStorageFactory() {
        return new EmptyStorageFactory();
    }

    
@Autowired(required=false)
    @Qualifier("samlFilter")
    FilterChainProxy samlFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       ...
       // Only try to do SAML stuff after we have tried to authenticate the user.
       http.addFilterAfter(samlFilter, RememberMeAuthenticationFilter.class)
       
       // (Optional part if you want redirects)
       // Just before we get to the samlFilter if we have not yet authenticated we
       // may set a cookie storing the location to which we should redirect back to
       // when all is said and done.
       http.addFilterBefore(setRedirectCookieForPostSAMLAction, samlFilter.getClass());
       // On SAML auth success, apply the redirect from the cookie. 
       sAMLProcessingFilter.setAuthenticationSuccessHandler(new ReadRedirectCookieForSAMLSuccessHandler());
       // (End Optional part)
       ...
       // Don't forget to enable your token based remember me service
       // Also don't forget to set stateless
       http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

最后,如果您确实想支持某种形式的重定向,请执行以下操作:

  • 让您的UI将您重定向到一些特殊的URL,并将该URL记录在GET参数中。例如。如果您到/secure.html,UI会将您重定向到/saml-redirect.html?redirectTo=/secure.html
  • 创建一个过滤器SetRedirectCookieForPostSAMLAction,如果用户要转到saml-redirec.html且未经身份验证,则该过滤器会设置一个记录redirectTo值的cookie。在SAML筛选器将用户重定向到IDP之前,将调用此筛选器。

public class setRedirectCookieForPostSAMLAction implements Filter {
   void setRedirectCookieIfRequired(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        // If the user is not authenticated and is going to the saml redirect page
        if(authentication == null && 
            new AntPathRequestMatcher("/saml-redirect.html", null).matches(request)) {
            if(request has a redirectTo param) {
                 Set cookie "saml-redirect-post-action" to Base64(redirectTo);
            }
        }

}
}
  • 创建一个成功处理程序ReadRedirectCookieForSAMLSuccessHandler,该处理程序将在用户使用SSO成功登录时运行(上面已配置)。如果重定向cookie,则此成功处理程序仅需要重定向用户。此外,它还应清除该cookie重定向cookie。

(别忘了检查重定向的外观是否合法,并且仅在重定向用户之前转到您的应用。)