Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Salesforce by (11.9k points)

I've implemented SSO using Spring SAML and everything is working fine. It worked with the following IDP's till now: 1) idp.ssocircle.com 2) openidp.feide.no

Now I'm testing with salesforce.com as my Identity Provider. As there is no provision to upload Service Provider Metadata I've done the following configuration settings at its IdP:

Gave my entityID and Assertion Consumer Service URL. I also uploaded my SP certificate. I've downloaded its metadata (idp metadata) which is as follows (hiding the sensitive information):

<?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

HTTP Status 401 - This request requires HTTP authentication(Authentication Failed: Incoming SAML message is invalid).

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).

Here is what I found in my log file(Adding necessary info only after successful 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.

1 Answer

0 votes
by (32.1k points)
edited by

It looks like your IDP is using a different key for digital signatures than it represents in the metadata.

You should investigate the SAML message you received and look for element X509Certificate inside element Signature. Extract the content of the certificate into an individual file, e.g. sales-force-sign.cer.

Or, you can just add the key which extracted from the message into your IDP metadata. You can manually update the XML file and add another KeyDescriptor with use="signing". It might be faster to do.

To learn in-depth about Workflow in Salesforce, sign up for an industry based Salesforce Course!

Related questions

Browse Categories

...