Missing prefix "saml:" when Using "Microsoft.IdentityModel.Tokens.Saml2" to make SAML V2.0

Unanswered Missing prefix "saml:" when Using "Microsoft.IdentityModel.Tokens.Saml2" to make SAML V2.0

  • Thursday, October 11, 2012 4:31 PM
     
     

    why can SAML2 produce a SAML where it use the prefix "SAML:" Like in this exemple:

       <?xml version="1.0" encoding="utf-8"?>
       <saml:Assertion ID="_51bc8a37-0b6d-4e13-81e9-e1778a9b4dd3" IssueInstant="2012-10-10T19:32:07.526Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
        <saml:Issuer>someidentifier</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="#_51bc8a37-0b6d-4e13-81e9-e1778a9b4dd3">
           <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" />
           <ds:DigestValue>N3UrIhpT+EXn+CeMiaq98v4n6vWw=</ds:DigestValue>
          </ds:Reference>
         </ds:SignedInfo>
    <ds:SignatureValue>ACDCBN55g2FTo82jWjfN67BQB7XyC1UxUIqr6iAGfu85O2P7WCkqDxPhsaveOOVkNgz1r4KkSEAdFdv5sh4xCumooUVAiQXYFMgGz6QSNjdsxUurrmetyrDLQOtU2phuAykY9bF4kNYuYBgvDygCq6gbv8DR+M83WbKFMHRy7nYkrHZg0DJw56aiHnZvZQr/VyIsSvxGU7ra9ED4Tbe26oWte8ysb71yAZKqcEzzFKZU1BmMoApwJU3DLVqHo5r335ayPYxcsvm3LJ3vIDx+ql3tEKFSlt2OLBYSMlhCGYbyxMwAmzWzgv53zx1DiXrBxsSFzrbqk7y4PNx2eE0NciA==</ds:SignatureValue>
         <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <o:KeyIdentifier ValueType="kdkT3iOnlm4C8J3oa4/KPHOyqngc=</o:KeyIdentifier">http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">kdkT3iOnlm4C8J3oa4/KPHOyqngc=</o:KeyIdentifier>
          </o:SecurityTokenReference>
         </KeyInfo>
        </ds:Signature>
        <saml:Subject>
         <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">12345</saml:NameID>
         <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
         </saml:SubjectConfirmation>
        </saml:Subject>
        <saml:Conditions NotBefore="2012-10-10T19:31:37.526Z" NotOnOrAfter="2012-10-10T19:32:37.526Z">
        </saml:Conditions>
        <saml:AttributeStatement>
         <saml:Attribute Name="userud">
          <saml:AttributeValue>999999</saml:AttributeValue>
         </saml:Attribute>
        </saml:AttributeStatement>
       </saml:Assertion>

     

     

    but all I can produce is (where's the "SAML" prefix?):


       <?xml version="1.0" encoding="utf-8"?>
       <Assertion ID="_51bc8a37-0b6d-4e13-81e9-e1778a9b4dd3" IssueInstant="2012-10-10T19:32:07.526Z" Version="2.0" xmlns="urn:oasis:names:tc:2.0:assertion">
        <Issuer>someidentifier</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="#_51bc8a37-0b6d-4e13-81e9-e1778a9b4dd3">
           <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" />
           <ds:DigestValue>N3UrIhpT+EXn+CeMiaq98v4n6vWw=</ds:DigestValue>
          </ds:Reference>
         </ds:SignedInfo>
         <ds:SignatureValue>ACDCBN55g2FTo82jWjfN67BQB7XyC1UxUIqr6iAGfu85O2P7WCkqDxPhsaveOOVkNgz1r4KkSEAdFdv5sh4xCumooUVAiQXYFMgGz6QSNjdsxUurrmetyrDLQOtU2phuAykY9bF4kNYuYBgvDygCq6gbv8DR+M83WbKFMHRy7nYkrHZg0DJw56aiHnZvZQr/VyIsSvxGU7ra9ED4Tbe26oWte8ysb71yAZKqcEzzFKZU1BmMoApwJU3DLVqHo5r335ayPYxcsvm3LJ3vIDx+ql3tEKFSlt2OLBYSMlhCGYbyxMwAmzWzgv53zx1DiXrBxsSFzrbqk7y4PNx2eE0NciA==</ds:SignatureValue>
         <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <o:KeyIdentifier ValueType="kdkT3iOnlm4C8J3o4/KPHOyqngc=</o:KeyIdentifier">http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">kdkT3iOnlm4C8J3o4/KPHOyqngc=</o:KeyIdentifier>
          </o:SecurityTokenReference>
         </KeyInfo>
        </ds:Signature>
        <Subject>
         <NameID Format="urn:oasis:names:tc:2.0:attrname-format:unspecified">12345</NameID>
         <SubjectConfirmation Method="urn:oasis:names:tc:2.0:cm:bearer">
         </SubjectConfirmation>
        </Subject>
        <Conditions NotBefore="2012-10-10T19:31:37.526Z" NotOnOrAfter="2012-10-10T19:32:37.526Z">
        </Conditions>
        <AttributeStatement>
         <Attribute Name="userud">
          <AttributeValue>999999</AttributeValue>
         </Attribute>
        </AttributeStatement>
       </Assertion>

     

     

     

     

     

     

     

     

     

    Here is my code:


     
       Saml2NameIdentifier assertionNameIdentifier = new Saml2NameIdentifier("someidentifier");
       Saml2Assertion assertion = new Saml2Assertion(assertionNameIdentifier);
       assertion.Id = new Saml2Id(SamlAssertionID);
       assertion.IssueInstant = dtIssueInstant;
       assertion.Conditions = new Saml2Conditions();
       assertion.Conditions.NotBefore = dtNotBefore;
       assertion.Conditions.NotOnOrAfter = dtNotOnOrAfter;
       //
       // Create some SAML subject.
       assertion.Subject = new Saml2Subject();
       assertion.Subject.NameId = new Saml2NameIdentifier("12345");
       assertion.Subject.NameId.Format = new Uri("urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified");
       
       //
       // Now create the SAML statement containing one attribute and one subject.
       Saml2AttributeStatement samlAttributeStatement = new Saml2AttributeStatement();
       
       //
       // Create one SAML attribute with few values.
       Saml2Attribute attr = null;
       
       attr = new Saml2Attribute("userid");
       attr.FriendlyName = "userid";
       attr.Values.Add("999999");
       samlAttributeStatement.Attributes.Add(attr);
       
       // Append the statement to the SAML assertion.
       assertion.Statements.Add(samlAttributeStatement);
       
       
       /**************************************************************
       * END createSamlAssertion()
       **************************************************************/
       
       //
       // Signing credentials are consisted
       // of private key in the certificate (see above),
       // the signature algorithm, security algortihm and key identifier.
       assertion.SigningCredentials =
       new SigningCredentials(signingKey, SecurityAlgorithms.RsaSha1Signature,
                       SecurityAlgorithms.Sha1Digest,
                       new SecurityKeyIdentifier(new X509ThumbprintKeyIdentifierClause(SigningCert)));
       
       
       
       // Finally create the SamlSecurityToken from the assertion
       Saml2SecurityToken samlToken = new Saml2SecurityToken(assertion);
       
       
       var tokenhandler = new Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler();
       
       var settings = new XmlWriterSettings();
       settings.Indent = false;
       settings.Encoding = Encoding.UTF8;
       
       using (var xWriter = XmlWriter.Create(@"c:\saml2.xml", settings))
       {
          
           Debug.WriteLine(xWriter.LookupPrefix("urn:oasis:names:tc:SAML:2.0:assertion"));
           tokenhandler.WriteToken(xWriter, samlToken);
           xWriter.Flush();
           xWriter.Close();
       }

     

All Replies

  • Monday, October 15, 2012 2:38 AM
     
     
  • Friday, October 19, 2012 4:00 PM
     
     
    Youhou, microsoft ? Aren't you suppose to answer within 2 business days for MSDN Subscriber ?
  • Saturday, October 20, 2012 3:34 AM
     
     
    My reply couldn't help?

    Go go Doraemon!

  • Monday, October 22, 2012 3:04 AM
    Moderator
     
     

    Hi Shebert,

    How does Dorado's reply work for you? If you still have any further question, please feel free to let us know. We will be glad to be of assistance.

    "If you don't get an answer from the community in select MSDN Forums, our Microsoft engineers will respond within two business days."

    We may not jump into a thread if we think the poster is getting helped. Thanks for your understanding and support!


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us

  • Monday, October 22, 2012 2:24 PM
     
     

    Dorado's reply doesn't explain how to set the SAML to display the prefix, but in is opinion it is not necessary, that with there SAML component, the prefix is optional.

    My experience with the partners we are establishing an SAML connection (partner who's doing SAML far longer than us), require the prefix. Even those who use COMPONENTSPACE. Might be how there set up, but it's there setup and it's working for them.

    SO I go back to my original question: why can't SAML2 produce a SAML who use the prefix "SAML?

    How to make .NET code create an SAML V2 that use the prefixes?

  • Tuesday, October 23, 2012 6:15 AM
     
     
  • Tuesday, October 23, 2012 2:38 PM
     
     
    No! Don't need help on how to create the SAML2 using the .NET classes. I Need help in making the SAML2 .NET Classes to use the prefix "SAML:" so my other partner can READ the SAML2 the classes produces. The only difference between what the SAML2 .NET classes produce and what my partner needs, is the prefix. I got the same SAML as desired but without the PREFIX.
  • Wednesday, November 07, 2012 9:06 PM
     
     
    anyone with an answer ? Microsoft?
  • Thursday, November 08, 2012 6:30 AM
     
      Has Code

    Hi SHEBERT,

    I've tried the code you provided and did found the behavior you mentioned. The saml token generated by the WIF api use default namespace (instead of namespace prefix) for elements under "urn:oasis:names:tc:SAML:2.0:assertion" namespace.

    From xml representation perspective, both ones are correct and xml processing tools/engine should treat them as exactly the same one. But I understand that for your case, your service provider has already done their processing code logic which expect an "saml" prefix for those elements.

    Based on my research, this behavior seems be controlled within the internal code logic of the saml token/handler implementation which doesn't use namespace prefix when serializing those elements into xml stream. Since we cannot change the WIF component's code logic, what I can get so far is to customize the xmlWriter which is used by saml token handler to serialize the token. For example, we can just create a custom XmlWriter class derived from the XmlTextWriter class (System.Xml namespace). then, we override the "WriteStartElement" method and intercept all the method calls for elements under "urn:oasis:names:tc:SAML:2.0:assertion" namespace and manually apply the "saml" namespace prefix for the call. Here is the test code for demonstration.

    //using (var xWriter = XmlWriter.Create(@"saml2.xml", settings))
    using(var xWriter = new MyXmlWriter(@"saml2.xml"))
    { 
                     
        Debug.WriteLine(xWriter.LookupPrefix("urn:oasis:names:tc:SAML:2.0:assertion"));
        tokenhandler.WriteToken(xWriter, samlToken);
        xWriter.Flush();
        xWriter.Close();
    }
    class MyXmlWriter : System.Xml.XmlTextWriter
    {
        public MyXmlWriter(string fileName)
            : base(fileName, Encoding.UTF8)
        {}
        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            if ( ns == "urn:oasis:names:tc:SAML:2.0:assertion")
            {
                base.WriteStartElement("saml", localName, ns);
            }
            else
            {
                base.WriteStartElement(prefix, localName, ns);
            }
        }
            
    }



    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Putting communities in your palms. Launch the browser on your phone now, type aka.ms/msforums and get connected!