ProviderNotFoundException:找不到ExpiringUsernameAuthenticationToken的AuthenticationProvider

时间:2015-02-23 19:32:55

标签: spring-security spring-saml

我们使用Spring Security和Spring SAML开发了一个应用程序,它在我们使用SSOCircle作为IDP的开发环境中工作。当我们使用他们的IDP进入我们客户的环境时,只要我们不暂停,我们就能够在没有问题的情况下对应用程序进行身份验证和导航。如果用户在提交页面之前暂停了超过一分钟,则应用程序将重定向到原始登录页面,并且提交的数据将丢失。

日志显示:

o.s.s.w.a.ExceptionTranslationFilter
                - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.providers.ExpiringUsernameAuthenticationToken

在此之前,日志显示大约每分钟类似于:

SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.providers.ExpiringUsernameAuthenticationToken@e6313ceb: Principal: REDACTED

客户告诉我们,他们的IDP超时为60秒,偏差时间为+30秒。

我们要求他们暂时将IDP超时调整为30分钟,我们的问题就消失了。当我们开始生产时,我们必须将原始设置为60秒。

我们的应用程序正在使用SAMLAuthenticationProvider:

@Override
protected void configure(AuthenticationManagerBuilder auth)
        throws Exception {
    auth.authenticationProvider(samlAuthenticationProvider());
}

@Bean
public SAMLAuthenticationProvider samlAuthenticationProvider() {
    SAMLAuthenticationProvider samlAuthenticationProvider = new SAMLAuthenticationProvider();
    samlAuthenticationProvider.setForcePrincipalAsString(false);
    samlAuthenticationProvider.setUserDetails(samlUserDetailsService);
    return samlAuthenticationProvider;
}

我们如何配置ExpiringUsernameAuthenticationToken来使用它?如果没有设置,为什么原始身份验证有效?

为什么应用程序试图在IDP会话到期时重新进行身份验证?

WebSSOProfileConsumerImpl和SingleLogoutProfileImpl都提供了设置responseSkew的方法。这应该设置为等于,小于还是大于IDP的偏斜时间?

1 个答案:

答案 0 :(得分:1)

默认情况下,Spring SAML会在其SAML响应中观察IDP提供的SessionNotOnOrAfter字段。该字段表示一旦时间达到提供的值,用户必须重新进行身份验证。

Spring SAML尝试通过将当前Authentication对象发送到AuthenticationManager来尝试重新验证用户,该AuhenticationProvier尝试查找支持Authentiction此类对象的ExpiringUsernameAuthenticationToken(在Spring SAML的情况下ProviderNotFoundException。在你的情况下,没有这样的提供者 - 这就是你看到EntryPoint例外的原因。出现此错误后,Spring Security可能会调用默认的SessionNotOnOrAfter,将您的用户重定向到登录页面。

要忽略SAMLAuthenticationProvider值只是扩展类getExpirationDate,请覆盖方法null并使其返回securityContext.xml。然后在SessionNotOnOrAfter

中使用新课程

但正确的解决办法是让你的IDP以合理的会话长度返回{{1}}值 - 我想知道为什么他们坚持在那里使用60秒。