SAML2 - 响应没有任何可以通过主题验证的有效断言

SAML2 - Response doesn't have any valid assertion which would pass subject validation

我有一个使用 SAML2 进行身份验证的解决方案,它与测试环境中的 idp 正确集成。然后现在在生产服务器中,当在我们的服务器中处理 saml 响应(POST 重定向)时,我收到此错误。 我查看了 SAML2 响应,它是正确的,与测试服务器中的响应相同。所以它一定是我们这边的东西。

org.springframework.security.authentication.AuthenticationServiceException: Error validating SAML message
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:101)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:92)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:185)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

 Caused by: org.opensaml.common.SAMLException: Response doesn't have any valid assertion which would pass subject validation
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:229)
at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:88)
... 37 more
Caused by: org.opensaml.xml.security.SecurityException: Error extracting certificates from X509Data
at org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider.extractCertificates(InlineX509DataProvider.java:195)
at org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider.process(InlineX509DataProvider.java:126)
at org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver.processKeyInfoChild(BasicProviderKeyInfoCredentialResolver.java:300)
at org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver.processKeyInfoChildren(BasicProviderKeyInfoCredentialResolver.java:256)
at org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver.processKeyInfo(BasicProviderKeyInfoCredentialResolver.java:190)
at org.opensaml.xml.security.keyinfo.BasicProviderKeyInfoCredentialResolver.resolveFromSource(BasicProviderKeyInfoCredentialResolver.java:149)
at org.opensaml.xml.security.credential.AbstractCriteriaFilteringCredentialResolver.resolve(AbstractCriteriaFilteringCredentialResolver.java:57)
at org.opensaml.xml.security.credential.AbstractCriteriaFilteringCredentialResolver.resolve(AbstractCriteriaFilteringCredentialResolver.java:37)
at org.opensaml.security.MetadataCredentialResolver.retrieveFromMetadata(MetadataCredentialResolver.java:275)
at org.springframework.security.saml.trust.MetadataCredentialResolver.retrieveFromMetadata(MetadataCredentialResolver.java:123)
at org.opensaml.security.MetadataCredentialResolver.resolveFromSource(MetadataCredentialResolver.java:178)
at org.opensaml.xml.security.credential.AbstractCriteriaFilteringCredentialResolver.resolve(AbstractCriteriaFilteringCredentialResolver.java:57)
at org.opensaml.xml.security.credential.AbstractCriteriaFilteringCredentialResolver.resolve(AbstractCriteriaFilteringCredentialResolver.java:37)
at org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine.validate(ExplicitKeySignatureTrustEngine.java:98)
at org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine.validate(ExplicitKeySignatureTrustEngine.java:49)
at org.springframework.security.saml.websso.AbstractProfileBase.verifySignature(AbstractProfileBase.java:271)
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAssertionSignature(WebSSOProfileConsumerImpl.java:419)
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.verifyAssertion(WebSSOProfileConsumerImpl.java:292)
at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:214)
... 38 more

Caused by: java.security.cert.CertificateException: Unable to decode X.509 certificates
at org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:362)
at org.opensaml.xml.security.keyinfo.KeyInfoHelper.getCertificate(KeyInfoHelper.java:201)
at org.opensaml.xml.security.keyinfo.KeyInfoHelper.getCertificates(KeyInfoHelper.java:176)
at org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider.extractCertificates(InlineX509DataProvider.java:192)
... 56 more
Caused by: java.security.KeyStoreException: failed to extract any certificates or private keys - maybe bad password?
at org.apache.commons.ssl.KeyStoreBuilder.parse(KeyStoreBuilder.java:443)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:213)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:165)
at org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:359)
... 59 more

我终于明白了:

这个问题的发生是因为使用的库版本spring-security-saml2-core。似乎存在一些错误或限制,可能在 opensaml 或库 not-yet-commons-ssl 中。

解决方法是将spring-security-saml2更新到最新版本(目前是1.0.9)。这个问题似乎也没有发生在 spring-security-saml2

的第一个版本中