[英]“HTTP Status 401 - Authentication Failed: Incoming SAML message is invalid” with Salesforce as IdP for implementating SSO
I've implemented SSO using Spring SAML and everything is working fine. 我使用Spring SAML实现了SSO,一切正常。 It worked with the following IDP's till now: 1) idp.ssocircle.com 2) openidp.feide.no 它与以下IDP一起使用到现在为止:1)idp.ssocircle.com 2)openidp.feide.no
Now I'm testing with salesforce.com as my Identity Provider. 现在我正在使用salesforce.com作为我的身份提供商进行测试。 As there is no provision to upload Service Provider Metadata I've done the following configuration settings at its IdP: 由于没有上传服务提供商元数据的规定,我在其IdP上完成了以下配置设置:
Gave my entityID and Assertion Consumer Service URL. 给我的entityID和Assertion Consumer Service URL。 I also uploaded my SP certificate. 我还上传了我的SP证书。 I've downloaded its metadata (idp metadata) which is as follows (hiding the sensitive information): 我已经下载了它的元数据(idp元数据),如下所示(隐藏敏感信息):
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://ABC-dev-ed.my.salesforce.com" validUntil="2024-04-11T13:55:57.307Z">
<md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>XXXXXXXXX</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://ABC-dev-ed.my.salesforce.com/idp/endpoint/HttpPost"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://ABC-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect"/>
Now when I tried to test my SP, first it redirected me to the IDP(salesforce) asking for credentials where I entered them but then after that I was redirected back to my Assertion consumer Service URL(which is my SP) but here an exception was generated saying that 现在,当我尝试测试我的SP时,首先它将我重定向到IDP(salesforce),询问我输入的凭据,但之后我被重定向回我的Assertion消费者服务URL(这是我的SP)但这里有例外生成了这样说
HTTP Status 401 - This request requires HTTP authentication(Authentication Failed: Incoming SAML message is invalid). HTTP状态401 - 此请求需要HTTP身份验证(身份验证失败:传入SAML消息无效)。
I've tried the following but didn't work :( - Though not necessary, I've downloaded the certificate file from the salesforce and imported it to my keystore.jks so that to make sure that key is used for signature validation.(Not necessary due to the certificate info already present in IDP metadata). 我尝试了以下但没有工作:( - 虽然没有必要,但我已经从salesforce下载了证书文件并将其导入我的keystore.jks,以确保该密钥用于签名验证。(由于IDP元数据中已存在证书信息,因此不必要)。
Here is what I found in my log file(Adding necessary info only after successful AuthnRequest): 这是我在日志文件中找到的内容(仅在成功的AuthnRequest之后添加必要的信息):
AuthNRequest;SUCCESS;127.0.0.1
.....STARTED_FAILING_HERE.....
Attempting to extract credential from an X509Data
Found 1 X509Certificates
Found 0 X509CRLs
Single certificate was present, treating as end-entity certificate
Credentials successfully extracted from child {http://www.w3.org/2000/09/xmldsig#}X509Data by provider org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider
A total of 1 credentials were resolved
Registry could not locate evaluable criteria for criteria class org.opensaml.xml.security.keyinfo.KeyInfoCriteria
Attempting to validate signature using key from supplied credential
Creating XMLSignature object
Validating signature with signature algorithm URI: http://www.w3.org/2000/09/xmldsig#rsa-sha1
Validation credential key algorithm 'RSA', key instance class 'sun.security.rsa.RSAPublicKeyImpl'
Signature validated with key from supplied credential
Signature validation using candidate credential was successful
Successfully verified signature using KeyInfo-derived credential
Attempting to establish trust of KeyInfo-derived credential
Failed to validate untrusted credential against trusted key
Failed to establish trust of KeyInfo-derived credential
Failed to verify signature and/or establish trust using any KeyInfo-derived credentials
Attempting to verify signature using trusted credentials
Attempting to validate signature using key from supplied credential
Creating XMLSignature object
Validating signature with signature algorithm URI: http://www.w3.org/2000/09/xmldsig#rsa-sha1
Validation credential key algorithm 'RSA', key instance class 'sun.security.rsa.RSAPublicKeyImpl'
Signature did not validate against the credential's key
Signature validation using candidate validation credential failed
org.opensaml.xml.validation.ValidationException: Signature did not validate against the credential's key
at org.opensaml.xml.signature.SignatureValidator.validate(SignatureValidator.java:79)
at org.opensaml.xml.signature.impl.BaseSignatureTrustEngine.verifySignature(BaseSignatureTrustEngine.java:142)
at org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine.validate(ExplicitKeySignatureTrustEngine.java:110)
at org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine.validate(ExplicitKeySignatureTrustEngine.java:49)
at org.opensaml.ws.security.provider.BaseTrustEngineRule.evaluate(BaseTrustEngineRule.java:104)
at org.opensaml.ws.security.provider.BaseTrustEngineRule.evaluate(BaseTrustEngineRule.java:91)
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.doEvaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:128)
at org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule.evaluate(SAMLProtocolMessageXMLSignatureSecurityPolicyRule.java:107)
at org.opensaml.ws.security.provider.BasicSecurityPolicy.evaluate(BasicSecurityPolicy.java:51)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.processSecurityPolicy(BaseMessageDecoder.java:132)
at org.opensaml.ws.message.decoder.BaseMessageDecoder.decode(BaseMessageDecoder.java:83)
at org.opensaml.saml2.binding.decoding.BaseSAML2MessageDecoder.decode(BaseSAML2MessageDecoder.java:70)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:105)
at org.springframework.security.saml.processor.SAMLProcessorImpl.retrieveMessage(SAMLProcessorImpl.java:172)
at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:77)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:195)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:301)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:162)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:140)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Failed to verify signature using either KeyInfo-derived or directly trusted credentials
Validation of protocol message signature failed for context issuer 'https://ABC-dev-ed.my.salesforce.com', message type: {urn:oasis:names:tc:SAML:2.0:protocol}Response
Authentication request failed: org.springframework.security.authentication.AuthenticationServiceException: Incoming SAML message is invalid
Updated SecurityContextHolder to contain null Authentication
Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@153a591
Can someone please tell me what is going wrong by looking at the above log. 有人可以通过查看上面的日志告诉我出了什么问题。 Any help would be highly appreciated. 任何帮助将受到高度赞赏。
Thanks, 谢谢,
Abhilash Abhilash
Your IDP is using a different key for digital signatures than it defines in metadata. 您的IDP使用的数字签名密钥与元数据中定义的密钥不同。
You should inspect the SAML message you received and look for element X509Certificate inside element Signature. 您应检查收到的SAML消息,并在元素签名中查找元素X509Certificate。 Extract the content of the certificate into a separate file, eg sales-force-sign.cer 将证书的内容提取到单独的文件中,例如sales-force-sign.cer
You then need to import the certificate into your samlKeystore.jks, you can find details on how to do it in chapter 4.5 (Key management) of the Spring SAML manual. 然后,您需要将证书导入samlKeystore.jks,您可以在Spring SAML手册的第4.5章(密钥管理)中找到有关如何执行此操作的详细信息。 Make sure to note the alias you import the key with. 请务必记下导入密钥的别名。
As last step you need to tell Spring SAML to use the newly imported key for signature verifications for your IDP, for that you should update your securityContext.xml and update your ExtendedMetadta for your IDP with property signingKey and value of the alias you used earlier to import the key. 作为最后一步,您需要告诉Spring SAML使用新导入的密钥进行IDP的签名验证,因为您应该更新securityContext.xml并使用属性signingKey和您之前使用的别名的值更新IDP的ExtendedMetadta。导入密钥。 It will look similar to: 它看起来类似于:
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.FilesystemMetadataProvider">
<constructor-arg>
<value type="java.io.File">classpath:salesforce_metadata.xml</value>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="signingKey" value="sf-proxy"/>
</bean>
</constructor-arg>
</bean>
Again you can find details on all of this in the manual. 您可以再次在手册中找到有关所有这些内容的详细信息。
Alternatively you can simply add the key you extracted from the message into your IDP metadata. 或者,您只需将从消息中提取的密钥添加到IDP元数据中即可。 Just manualy update the XML file and add another KeyDescriptor with use="signing". 只需手动更新XML文件并使用use =“signing”添加另一个KeyDescriptor。 It might be faster to do. 这可能会更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.