Search code examples
c#xmlsamlxmlreader

Read XML element with XSD of "anyType" and attribute xsi:type="string"


I'm trying to read an XML document (which is a SAML token, but its not specifically a SAML related problem). The XSD (see here) specifies the < saml:AttributeValue> element on the 3rd last line of the XSD like this:

 <element name="AttributeValue" type="anyType" nillable="true"/>

It says it can be anyType which is fine.

But the actual XML has tried to specify the namespace and type and my XMLReader is struggling to read it before its not formatted correctly.

<saml:AttributeStatement>
   <saml:Attribute Name="Town">
      <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="string">
                Glasgow
      </saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>

When I try to read the XML using this code...

//This code just simulates the XmlReader navigating over the document, rather than a specific function.
var sr = new StringReader(xmlString);
var reader = XmlReader.Create(sr);
var output = reader.ReadSubTree();

I get this error...

{"ID4254: The AttributeValueXsiType of a SAML Attribute must be a string of the form 'prefix#suffix', where prefix and suffix are non-empty strings.\r\nParameter name: value"}

This is thrown by the System.IdentityModel.Tokens.SamlAttribute class, see the code here

I believe it is the format of the xsi:type="string" which is causing a problem. If I include xs: in the type attribute of xsi:type="string" (see below), it seems to work fine.

      <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="xs:string">
                Glasgow
      </saml:AttributeValue>
  1. Which is valid XML? xsi:type="string" or xsi:type="xs:string"

  2. Am I missing a namespace reference?

(This XML message is generated by a third party, so I can't change it and want to know if its valid or not).

Update

The root element does contain the following namespace references:

<Request xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns="http://thirdparty.co.uk/schema">
  1. I presume from this, the default namespace is "http://thirdparty.co.uk/schema"??

Solution

  • The problem is simply with scope of the type value you're using. As per your last update in question the default schema is http://thirdparty.co.uk/schema.

    Considering scenario:

     <saml:AttributeValue
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="string">
                    Glasgow
     </saml:AttributeValue>
    

    means the parser will try to find the string type in default schema where ofcourse string is not defined.

    Now when you change it to xs:string means you're explicitly telling that look for string in namespace alias xs. That's why below is the correct one:

     <saml:AttributeValue
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="xs:string">
                    Glasgow
     </saml:AttributeValue>
    

    Although the error message you're getting is a validation error which might be applied to strict the usage of namespace alias with value.