0
votes

I am sending a SAML response to Ping Federate . If the SAML response contains SAML attributes , then it works correctly , whereas if the SAML response does not contain the SAML attributes , it throws the below error :

Response XML is invalid. Errors: [error: cvc-complex-type.2.4c: Expected elements 'Attribute@urn:oasis:names:tc:SAML:2.0:assertion EncryptedAttribute@urn:oasis:names:tc:SAML:2.0:assertion' before the end of the content in element AttributeStatement@urn:oasis:names:tc:SAML:2.0:assertion].

Below is the SAML response (without the SAML attributes) which is throwing this error :

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://test/sp/ACS.saml2" ID="frtgckggfpwphf_vxeatxzlvgrq" IssueInstant="2018-08-30T11:50:38.183Z" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">Test</saml2:Issuer>
    <saml2p:Status>
        <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </saml2p:Status>
    <saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="_4947dc191f01c1e98d448c2fadd5c289" IssueInstant="2018-08-30T11:50:38.183Z" Version="2.0">
        <saml2:Issuer>Test</saml2:Issuer>
        <saml2:Subject>
            <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">testUser</saml2:NameID>
            <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
                <saml2:SubjectConfirmationData NotOnOrAfter="2018-08-30T11:52:38.183Z" Recipient="https://test/sp/ACS.saml2"/>
            </saml2:SubjectConfirmation>
        </saml2:Subject>
        <saml2:Conditions NotBefore="2018-08-30T11:50:38.183Z" NotOnOrAfter="2018-08-30T11:52:38.183Z">
            <saml2:AudienceRestriction>
                <saml2:Audience>TestAudience</saml2:Audience>
            </saml2:AudienceRestriction>
        </saml2:Conditions>
        <saml2:AuthnStatement AuthnInstant="2018-08-30T11:50:38.184Z" SessionIndex="_4947dc191f01c1e98d448c2fadd5c289">
            <saml2:AuthnContext>
                <saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef>
            </saml2:AuthnContext>
        </saml2:AuthnStatement>
        <saml2:AttributeStatement/>
    </saml2:Assertion>
</saml2p:Response>

I believe this may be because of

<saml2:AttributeStatement/>

but the online tools say that the above XML is valid.

Does the Ping Federate requires a specific format of SAML response (i.e. without 'saml2:AttributeStatement ' if no SAML attributes are present) , or is this completely different issue altogether ?

Thanks

1

1 Answers

1
votes

The SAML core spec (https://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf) says:

2.7.3 Element <AttributeStatement>

The <AttributeStatement> element describes a statement by the SAML authority asserting that the assertion subject is associated with the specified attributes. Assertions containing <AttributeStatement> elements MUST contain a <Subject> element. It is of type AttributeStatementType, which extends StatementAbstractType with the addition of the following elements: <Attribute> or <EncryptedAttribute> [One or More] The <Attribute> element specifies an attribute of the assertion subject. An encrypted SAML attribute may be included with the <EncryptedAttribute> element. The following schema fragment defines the <AttributeStatement> element and its AttributeStatementType complex type:

<element name="AttributeStatement" type="saml:AttributeStatementType"/>
<complexType name="AttributeStatementType">
  <complexContent>
    <extension base="saml:StatementAbstractType">
      <choice maxOccurs="unbounded">
        <element ref="saml:Attribute"/>
        <element ref="saml:EncryptedAttribute"/>
      </choice>
    </extension>
  </complexContent>
</complexType>

The online tools that you have used are incorrect (they probably just validate XML instead of validating against the SAML schema): you must include a <Subject> and "One or More" Attribute(s) or EncryptedAttribute(s) in an AttributeStatement.

FWIW: if you don't intend to send any attributes, you can leave out the AttributeStatement all together, it is just that sending an empty one is violating the spec.