I am trying to configure SAML2 IdP Salesforce
as external provider in IdentityServer3. I am using SustainSys/Saml2 library. So for testing purpose I have downloaded SampleIdentityServer3. and configured SAML2 IdP like below
private void ConfigureSaml2(IAppBuilder app, string signInAsType)
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;
var options = new Saml2AuthenticationOptions(false)
{
SPOptions = new SPOptions
{
EntityId = new EntityId("http://localhost:4589/IdSrv3/Saml2"),
MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
},
SignInAsAuthenticationType = signInAsType,
Caption = "SAML2p",
};
UseIdSrv3LogoutOnFederatedLogout(app, options);
options.SPOptions.ServiceCertificates.Add(new X509Certificate2(
AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/Sustainsys.Saml2.Tests.pfx"));
var idp = new IdentityProvider(
new EntityId("https://XXXXXX-dev-ed.my.salesforce.com"),
options.SPOptions)
{
MetadataLocation = "https://XXXXXX-dev-ed.my.salesforce.com/.well-known/samlidp.xml",
LoadMetadata = true,
};
options.IdentityProviders.Add(idp);
app.UseSaml2Authentication(options);
}
Note that if i don't set MinIncomingSigningAlgorithm
to sh1 then the SustainSys library throws error.
Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signing algorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1 is weaker than the minimum accepted http://www.w3.org/2001/04/xmldsig-more#rsa-sha256. If you want to allow this signing algorithm, use the minIncomingSigningAlgorithm configuration attribute.
So i set the MinIncomingSigningAlgorithm
to "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
to get rid of the error.
But then i get different error
Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signature verified correctly with the key contained in the signature, but that key is not trusted.
based on issue #493 #735 the certificate in metadata must match with the certificate in SAML2 response.
In metadata the certificate is (notice start and end values)
<ds:X509Data>
<ds:X509Certificate>
MIIGk... removed from brevity....tmv6J1g==
</ds:X509Certificate>
</ds:X509Data>
But in SAML2 response ( the one that is logged by SustainSys library)
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:4589/IdSrv3/Saml2/Acs" ID="_19fd2d8d9aab0401f56fXXXXXXXXX" InResponseTo="id473a52c49f194bXXXXXXXXX" IssueInstant="2018-08-27T20:10:04.296Z" Version="2.0">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://XXXXXXX-dev-ed.my.salesforce.com</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#_19fd2d8d9aab0401f56f642dXXXXXXXXXXXXX">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml samlp" /></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>fQiiyd0T57Ztr5BAfMFe9MTrhY0=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
B6hndlsBgY45J+hm8My2gPVo....removed for brevity....YT88ajt7jQ==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIENz... remove for brevity....y2Ul24Jyc4V/jJN
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" />
</samlp:Status>
</samlp:Response>
looking at X509Certificate
value in metadata and in SAML2 response they don't match.
Question
Does the X509Certificate
value in SAML2 response supposed to match with X509Certificate
value in metadata? If yes, why can't SustainSys library always use the X509Certificate
value from SAML2 response?
Update
Just to see if matching the values would work, I saved certificate value from SAML2 response into separate .cer
file. and Then in KeyInfoSerializer.cs file i updated ReadX509Certificate
method (this is the method that loads the certificate from metadata)
private static SecurityKeyIdentifierClause ReadX509Certificate(XmlReader reader)
{
reader.ReadStartElement("X509Certificate", SignedXml.XmlDsigNamespaceUrl);
((XmlDictionaryReader)reader).ReadContentAsString();
var cer = new X509Certificate2(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/salesforcepublickey.cer");
var clause = new X509RawDataKeyIdentifierClause(cer);
reader.ReadEndElement();
return clause;
}
However, it still throws error The signature verified correctly with the key contained in the signature, but that key is not trusted.
Found it.
It was issue on Salesforce side. In Saleforce, when i check the logs Identity->Identity Provider Event Log
i see error Error: User does not have access to this service provider
For this, the user was not given permission. Even if the user is System Administrator, the access to Connected App is not given by default. To give permission, go to 'Manage Users -> Users' and click edit on the user you are testing.Click profile name link .e.g System Administrator. This takes to profile page. You can scroll below to 'Connected App Access' and you would see that the access is not given. Give the access by clicking edit profile in the top of page.