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

Spring security 使用Spring Security Saml和SP应用程序的无状态会话,spring-security,spring-boot,httpsession,spring-saml,Spring Security,Spring Boot,Httpsession,Spring Saml,我试着从, 我能够运行它并与身份提供商集成 但是,我看到每次都会创建一个会话,并一直保持到用户注销为止 我在spring boot中使用基于资源的服务,因此不希望增加会话的开销 我尝试将下面的行添加到configure方法中, http.sessionManagement() .sessionCreationPolicy(sessionCreationPolicy.STATELESS) 但是,在这个设置下,我总是被要求登录到身份提供者 如果我登录,它会返回页面,要求我在循环中再次登录 我不确定

我试着从,

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

但是,我看到每次都会创建一个会话,并一直保持到用户注销为止

我在spring boot中使用基于资源的服务,因此不希望增加会话的开销

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

但是,在这个设置下,我总是被要求登录到身份提供者

如果我登录,它会返回页面,要求我在循环中再次登录

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

任何人都能为我提供使用SpringSecuritySAML扩展和服务提供商应用程序的无状态会话的正确方法吗

谢谢


Sri

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

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

2) 在SAML配置中添加更多过滤器(在SAML过滤器之前),使其与不同类型的身份验证(例如基于令牌的身份验证)一起工作,并且只要此过滤器能够在SAML过滤器之前生成有效的
身份验证
,您就应该是好的


您还可以签出此库:要简化SAML配置,在无状态下启用SAML,您需要:

  • 将SamlMessageStoreFactory设置为空工厂
  • 确保SAML筛选器位于“记住我”筛选器之后
  • 实际上,启用无状态并像往常一样配置您的“记住我”服务
请注意,这样做意味着您没有JSESSIONID,这意味着spring将不再记录原始请求的URL,因此无法处理稍后将您重定向回该URL的问题。(建议稍后对此进行解决)

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

  • 让UI将您重定向到某个特殊URL,并在GET参数中记录要转到的URL。例如,如果您出现在
    /secure.html
    ,UI会将您重定向到
    /saml redirect.html?redirectTo=/secure.html
  • 创建一个过滤器
    SetRedirectCookieForPostSAMLAction
    ,如果用户要
    saml redirec.html
    且未经过身份验证,则该过滤器将设置一个cookie,记录
    重定向到
    值。在SAML筛选器将用户重定向到IDP之前调用此筛选器
  • 创建一个成功处理程序
    ReadRedirectCookieForSAMLSuccessHandler
    ,当用户使用SSO(上面配置)成功登录时将运行该处理程序。如果重定向cookie失败,则此成功处理程序只需重定向用户。它还应该清除cookie重定向cookie

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

嗨,Sri,我们的项目中也有同样的要求。你能告诉我你是如何实施的吗。提前谢谢。KittyHi Sam,我尝试了与您建议的相同的方法,在saml身份验证之后,当用户使用不同的端点进行下一次调用时,spring允许它命中端点。但是第二个端点是无状态的,我创建了一个过滤器,并使用不同的逻辑使其验证成功。过滤器中使用的逻辑现在没有用处,因为spring认为它已经通过了身份验证。为了在rest端点实现(/saml/**)中解决这个问题,我将使会话无效。但我觉得这不是正确的方法。请告诉我是否有更好的解决办法-KittyI认为1)中不清楚的是如何阻止spring使用它在SAML身份验证期间创建的jsessionid,使其不能在
“/service/**”
下使用,spring似乎看到了jsessionid,并假设请求在所有地方都经过了身份验证。在一天结束时,spring安全性只是向执行的每个请求添加了一系列筛选器,其中一个是会话筛选器。您可以修改该链并插入自己的条件会话筛选器,或者拥有不同的“领域”,这些“领域”对于不同的路径基本上是不同的筛选器链,您可以使用WebSecurityConfigureAdapter定义它们
@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);
    }
}

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);
            }
        }

}
}