Reputation: 55
Dotnet Core version: 2.1.302
Following code is added in the startup.cs file in ConfigureServices(IServiceCollection services)
method:
services.AddSaml2("saml2", options =>
{
options.SPOptions.EntityId = new Sustainsys.Saml2.Metadata.EntityId(this.Configuration.Get<AppSetting>().SPEntityId);
options.SPOptions.MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
options.SPOptions.NameIdPolicy = new Sustainsys.Saml2.Saml2P.Saml2NameIdPolicy(true, Sustainsys.Saml2.Saml2P.NameIdFormat.Unspecified);
options.IdentityProviders.Add(
new Sustainsys.Saml2.IdentityProvider(
new Sustainsys.Saml2.Metadata.EntityId(this.Configuration.Get<AppSetting>().SPMetadata), options.SPOptions)
{
LoadMetadata = true,
Binding = Sustainsys.Saml2.WebSso.Saml2BindingType.HttpPost
});
})
The authentication is triggered by following controller action:
[HttpGet]
public IActionResult Login(string returnUrl = null)
{
var redirectUrl = Url.Content("~/Saml/Callback");
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl }, "saml2");
}
The authentication with the ID server is successfully done and response is received as POST request on https://SP-Server-xxxx/server/Saml2/Acs
as per XML at the end of this post. However, then following error is returned with HTTP code 500:
{
error: "IDX13102: Exception thrown while reading '[PII is hidden]' for Saml2SecurityToken. Inner exception: 'System.ArgumentException'."
}
Please suggest what is wrong with the setup or the implementation.
Response XML:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Consent="urn:oasis:names:tc:SAML:2.0:consent:obtained" Destination="https://SP-Server-xxxx/server/Saml2/Acs" ID="XXXXX" InResponseTo="XXXXX" IssueInstant="2018-11-28T06:26:12Z" Version="2.0">
<saml:Issuer>https://ID-Server-yyyy/zzzz/saml2/metadata</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="XXXXX" IssueInstant="2018-11-28T06:26:12Z" Version="2.0">
<saml:Issuer>https://ID-Server-yyyy/zzzz/saml2/metadata</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<CanonicalizationMethod xmlns="http://www.w3.org/2000/09/xmldsig#" 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="#yyyyy">
<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#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue xmlns="http://www.w3.org/2000/09/xmldsig#">zzzzz</DigestValue>
</ds:Reference>
</ds:SignedInfo>
<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#"> 'removed the signature value' </SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate> 'removed the certificate' </ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://ID-Server-yyyy/zzzz/saml2/metadata" SPNameQualifier="https://SP-Server-xxxx">
[email protected]
</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData InResponseTo="XXXXX" NotOnOrAfter="2018-11-28T06:31:12Z" Recipient="https://SP-Server-xxxx/server/Saml2/Acs"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2018-11-28T06:21:12Z" NotOnOrAfter="2018-11-28T06:31:12Z">
<saml:AudienceRestriction>
<saml:Audience>https://SP-Server-xxxx</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2018-11-28T06:26:09Z" SessionIndex="XXXXX">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
<saml:AuthnContextDeclRef>name/password/uri</saml:AuthnContextDeclRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="LastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Last Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">[email protected]</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="MiddleName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Middle Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="FirstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">First Name</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="Id" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml:AttributeValue xsi:type="xs:string">Id Value</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
UPDATE:
After setting IdentityModelEventSource.ShowPII
to true the error response is changed as followed:
{
error: "IDX13102: Exception thrown while reading 'AuthnContext' for Saml2SecurityToken. Inner exception: 'System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri' at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value) at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference) at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)'."
}
Based on the error message I assume the ID server needs to set the AuthnContext with a valid URI. Please confirm.
Following is the Stack-Trace:
2018-11-29 08:45:10.700 +01:00 [Debug] Signature validation passed for Saml Response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id
2018-11-29 08:45:10.759 +01:00 [Error] Exception is occurred
Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenReadException: IDX13102: Exception thrown while reading 'AuthnContext' for Saml2SecurityToken. Inner exception: 'System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri'
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)'. ---> System.ArgumentException: IDX13300: 'value' must be an absolute Uri, was: 'name/password/uri'
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext.set_DeclarationReference(Uri value)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2AuthenticationContext..ctor(Uri classReference, Uri declarationReference)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)
--- End of inner exception stack trace ---
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationContext(XmlDictionaryReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2Serializer.ReadAuthenticationStatement(XmlDictionaryReader reader)
at Sustainsys.Saml2.Saml2P.Saml2PSerializer.ReadAssertion(XmlReader reader)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ReadSaml2Token(String token)
at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Sustainsys.Saml2.Saml2P.Saml2Response.CreateClaims(IOptions options, IdentityProvider idp)+MoveNext()
at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Sustainsys.Saml2.Saml2P.Saml2Response.GetClaims(IOptions options, IDictionary`2 relayData)
at Sustainsys.Saml2.WebSso.AcsCommand.ProcessResponse(IOptions options, Saml2Response samlResponse, StoredRequestState storedRequestState)
at Sustainsys.Saml2.WebSso.AcsCommand.Run(HttpRequestData request, IOptions options)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Service.Provider.Middleware.LanguageHandlingMiddleware.Invoke(HttpContext context) in X:\Projects\Service-Provider\Middleware\LanguageHandlingMiddleware.cs:line 21
at Service.Provider.Middleware.ErrorHandlingMiddleware.Invoke(HttpContext context, ILogger`1 logger) in X:\Projects\Service-Provider\Middleware\ErrorHandlingMiddleware.cs:line 22
Update 2
Thanks for the response @Anders. As we dont have control over the ipd, I have requested the idp developers to consider above change.
But meanwhile we have tried to dig further into the options. I have referred one the documents hosted here: https://media.readthedocs.org/pdf/saml2/latest/saml2.pdf. The section 2.18.1 lists the attributes of Element. It mentions about IgnoreAuthenticationContextInResponse
attribute. Based on the description of the attribute, it seems that making this as true
will solve the above error.
But I cannot find this attribute while configuring the Compatibility element in SPOtions (options.SPOptions.Compatibility.IgnoreAuthenticationContextInResponse
?)
We are using Sustainsys.Saml2.AspNetCore2 package version 2.2.0.
Is it so that the Compatibility.IgnoreAuthenticationContextInResponse
attribute is not yet available in version 2.2.0 ?
Upvotes: 3
Views: 2609
Reputation: 69250
The problem is that the idp supplies a value name/password/uri
for <saml:AuthnContextDeclRef>
. That is a not a valid value, it must be an absolute URI according to the SAML2 specification.
But in this case I think the Idp should omit that element totally.It is already referencing a well known authentication method in the line above: <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
Upvotes: 3