Spring security ProviderNotFoundException:未找到ExpireingUserNameAuthenticationToken的AuthenticationProvider

Spring security ProviderNotFoundException:未找到ExpireingUserNameAuthenticationToken的AuthenticationProvider,spring-security,spring-saml,Spring Security,Spring Saml,我们已经使用SpringSecurity和SpringSAML开发了一个应用程序,该应用程序在我们的开发环境中工作,在我们的开发环境中,我们使用SSOCIRCE作为我们的IDP。当我们使用客户的IDP进入客户的环境时,只要我们不暂停,我们就能够在应用程序中进行身份验证和导航,而不会出现问题。如果用户在提交页面之前在页面上暂停超过分钟,应用程序将重定向到原始登录页面,提交的数据将丢失 日志显示: o.s.s.w.a.ExceptionTranslationFilter

我们已经使用SpringSecurity和SpringSAML开发了一个应用程序,该应用程序在我们的开发环境中工作,在我们的开发环境中,我们使用SSOCIRCE作为我们的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会话过期时尝试重新验证


WebsProfileConsumerImpl和SingleLogoutProfileImpl都提供了设置响应的方法。是否应将其设置为等于、小于或大于IDP的倾斜时间?

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

Spring SAML通过将当前的
Authentication
对象发送到
AuthenticationManager
,尝试重新验证用户身份,后者尝试查找支持此类
authenticationProvider
对象的
auhenticationProvider
(对于Spring SAML,则为
ExpiringUsernameAuthenticationToken
)。在您的情况下,没有这样的提供程序-这就是为什么您会看到
ProviderNotFoundException
异常。出现此错误后,Spring安全性可能会调用默认的
入口点
,将用户重定向到登录页面

为了忽略
sessionnotorafter
值,只需扩展类
SAMLAuthenticationProvider
,重写方法
getExpirationDate
,并使其返回
null
。然后在
securityContext.xml
中使用新类


但是正确的解决方案是让您的IDP返回具有合理会话长度的
sessionnotorafter
值-我想知道他们为什么坚持使用60秒。

所以您客户的IDP在SAML响应中设置sessionnotorafter,并且在将来只包括60秒?你想观察什么样的行为?忽略60秒超时?是,大约。15:39:45,他们发送了NOTONORFAFTER=“2015-02-23T15:41:14Z”。在有人进行身份验证后,我们希望他们在应用程序的HttpSession过期或注销之前保持正常行为。谢谢,@Vladimír Sch fer。我很快就会测试这个。你知道关于设置sessionnotorAfter的任何“官方”建议,我可以用来帮助说服他们吗?我会和他们争论,这个值应该与HTTP会话通常的最长时间相似,因为它们的含义基本相同。但是,简单地忽略该值可能会容易得多,只要让他们知道这是SP的实现方式并获得同意即可。其他一些供应商也完全忽略了该值(例如Ping-)