跨多个tomcat Web应用程序具有记住我功能的Spring Security SAML扩展

时间:2018-08-06 17:26:02

标签: spring spring-security saml-2.0 spring-saml remember-me

我有2个Spring应用程序,它们在tomcat服务器上并排运行。我将基于令牌的RememberMeAuthenticationProvider与自定义UserDetailsS​​ervice一起使用,因此我只对用户进行一次身份验证,他们可以在两个应用程序之间导航,而无需重新进行身份验证。

除了正常的用户名/密码登录过程外,我还配置了spring saml扩展名,以使用外部IdP对应用程序(SP)上的用户进行身份验证。我将SAMLAuthenticationProvider与自定义SAMLUserDetailsS​​ervice一起使用,以将saml断言用户名与数据库中的用户匹配,并且它们在我的应用程序的 one 中进行了身份验证。我遇到的问题是用户未在我的第二个应用程序上进行身份验证。就像我期望的那样,当导航到第二个应用程序时,它一直在询问用户名和密码,因为没有记住我为SAMLAuthenticationProvider配置的令牌/ cookie。

我可以通过SAMLUserDetailsS​​ervice使用基于令牌的记住我的服务吗?

3 个答案:

答案 0 :(得分:0)

您是否已将两个应用程序都配置为使用同一会话存储?他们在同一个域/子域中,以便他们可以共享身份验证Cookie吗?我会将其中一个应用程序设置为(唯一)身份验证点,并将第二个应用程序的登录名设置为进行身份验证。

答案 1 :(得分:0)

我最终使用SAMLAuthenticationProvider并在用户成功进行身份验证时手动创建了一个“记住我”令牌(通过在RememberMeAuthenticationProvider下复制春季源代码)。

我找不到通过弹簧配置将SAMLAuthenticationProvider和RememberMeAuthenticationProvider的功能完美结合的方法,但现在可以使用。

答案 2 :(得分:0)

关键是确保已设置SAMLProcessingFilter.rememberMeServices。 这有点棘手,因为没有公开默认的rememberMe()组件。这是一个可能的解决方案。

@Autowired
public void configureRememberMe(
        @Qualifier(BeanIds.SPRING_SECURITY_FILTER_CHAIN) Filter securityChain,
        List<SAMLProcessingFilter> filters
) {
    RememberMeServices rememberMe = ((FilterChainProxy) securityChain).getFilterChains().stream()
            .flatMap(chain -> chain.getFilters().stream())
            .filter(RememberMeAuthenticationFilter.class::isInstance)
            .map(RememberMeAuthenticationFilter.class::cast)
            .findAny()
            .map(RememberMeAuthenticationFilter::getRememberMeServices)
            .orElseGet(NullRememberMeServices::new);

    filters.forEach(filter -> filter.setRememberMeServices(rememberMe));
}

如果您构建自己的RememberMeServices,则只需将其直接注入而不是将其从过滤器链中捕获即可。

下一个问题是如果您没有.alwaysRemember()。我认为没有任何方法可以通过IdP传递请求参数。您将不得不基于某个外部上下文扩展RememberMeServices并覆盖rememberMeRequested,或者扩展WebSSOProfile以便在绑定URL中动态添加“记住我”参数。