Ashish Gamit
Ashish Gamit

Reputation: 55

Sustainsys: error: "IDX13102: Exception thrown while reading '[PII is hidden]' for Saml2SecurityToken. Inner exception: 'System.ArgumentException'."

Nuget Packages in use:

  1. Microsoft.AspNetCore.App - 2.1.1
  2. Microsoft.NETCore.App - 2.1.0
  3. Sustainsys.Saml2.AspNetCore2 - 2.2.0

Dotnet Core version: 2.1.302

Implementation

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

Answers (1)

Anders Abel
Anders Abel

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

Related Questions