Working with SAML 2.0 in C# .NET 4.5

96,834

Solution 1

.NET 4.5 has WIF (Windows Identity Foundation) built into it. This now supports SAML 2.0. To make use of SAML 2.0, just use .NET 4.5. The class name is Saml2XXXX (where XXXX is the token, assertion, serializer etc) Here is a link to SAML 2.0 Assertion: http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml2.saml2assertion.aspx

This will create a SAML 2.0 Assertion object. To get the XML, this is the code I used:

using System.Xml;
using System.IdentityModel.Tokens;

namespace YOUR.SPACE
{
    public class Saml2Serializer : Saml2SecurityTokenHandler
    {
        public Saml2Serializer()
        {
            Configuration = new SecurityTokenHandlerConfiguration()
                {

                };
        }

        public void WriteSaml2Assertion(XmlWriter writer, Saml2Assertion data)
        {
            base.WriteAssertion(writer, data);
        }
    }
}

This will serialize your assertion object into XML. This is where I ran into problems. The XML is will create does NOT contain the saml namespace (e.g. <saml:Assertion>). I was not able to find a solution for this, so a Replace("<", "<saml:") had to be used.

Solution 2

That's because Saml2Assertion refers to the token not the protocol.

The SAML token used in WIF is a 1.0 token.

There is no SAML 2 protocol support in .NET.

There is a WIF CTP for SAML 2 but it hasn't been upgraded for ages.

Share:
96,834
bugnuker
Author by

bugnuker

.NET Developer Creator of www.autharmor.com

Updated on March 04, 2020

Comments

  • bugnuker
    bugnuker about 4 years

    I am trying to use pure .NET (no external classes, controls, helpers) to create a SAML message. I found some code on the interwebs; this is what I have:

    private static SamlAssertion createSamlAssertion()
    {
        // Here we create some SAML assertion with ID and Issuer name. 
        SamlAssertion assertion = new SamlAssertion();
        assertion.AssertionId = "AssertionID";
        assertion.Issuer = "ISSUER";
        // Create some SAML subject. 
       SamlSubject samlSubject = new SamlSubject();
        samlSubject.Name = "My Subject";
    
        // 
        // Create one SAML attribute with few values. 
        SamlAttribute attr = new SamlAttribute();
        attr.Namespace = "http://daenet.eu/saml";
        attr.AttributeValues.Add("Some Value 1");
        //attr.AttributeValues.Add("Some Value 2");
    
        attr.Name = "My ATTR Value";
    
        // 
        // Now create the SAML statement containing one attribute and one subject. 
        SamlAttributeStatement samlAttributeStatement = new SamlAttributeStatement();
        samlAttributeStatement.Attributes.Add(attr);
        samlAttributeStatement.SamlSubject = samlSubject;
    
        // Append the statement to the SAML assertion. 
        assertion.Statements.Add(samlAttributeStatement);
    
        //return assertion
        return assertion;
    
    }
    

    and here is the code I am using to get the XML:

    var sb = new StringBuilder();
    var settings = new XmlWriterSettings
    {
        OmitXmlDeclaration = true,
        Encoding = Encoding.UTF8
    };
    using (var stringWriter = new StringWriter(sb))
    using (var xmlWriter = XmlWriter.Create(stringWriter, settings))
    using (var dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter(xmlWriter))
    {
        var samlAssertSerializer = new SamlSerializer();
        var secTokenSerializer = new WSSecurityTokenSerializer();
        assertion.WriteXml(
            dictionaryWriter,
            samlAssertSerializer,
            secTokenSerializer
        );
    }
    

    This seemed like it was going to work. However, the message is produces is SAML version 1.0 - I need to work with 2.0.

    I know I can do some sloppy work and replace some values here and there and this system would work fine. There are very little differences in the message, version being the most important. I am having a hard time finding information on SAML 2.0 for .NET. I do know SAML 2.0 was implemented into .NET recently. I am using Framework 4.5 so I should have access to it. The MSDN page for SamlAssertion says the "majorVersion" is a constant, always set to '1'.

    I'm guessing there is another namespace I could be working with, but I haven't found it. My requirement is just to get the XML SAML message. I don't need to sign with X509, I don't need the token. Just the SAML XML message.

    Again, this is a question trying to find out how to do this in native .NET. I have found several SAML helpers and lots of code on how to build the message manually- I'm trying to find the CORRECT solution, if it exists.

    EDIT: I have found I can use Saml2Assertion. However, I am unable to find a way to get the SAML message written to xml now.

    EDIT2: I have found how to write the Saml2Assersion object to xml. Sadly, it does not keep the SAML syntax, it writes in pure XML without <saml> tags.

  • bugnuker
    bugnuker about 11 years
    Incorrect. SAML2 (actually, WIF) was fully implemented into 4.5 Framework. Here is a link: msdn.microsoft.com/en-us/library/… Also, SAML2Assertion is the assersion, and there is a Saml2Token class for the token. So far, everything is working pretty good except XML namespace of saml is missing. Once I figure that out (XMLWriter issue probably) I'll post the solution.
  • rbrayb
    rbrayb about 11 years
    Look at the namespace - it's Token not Protocol - the list of protocols is here - msdn.microsoft.com/en-us/library/ee709285.aspx
  • bugnuker
    bugnuker about 11 years
    Thanks for the namespace link. I do appreciate you answering, no one else has. I am not looking for a protocol. My question was pretty clear. I quote "I don't need the token. Just the SAML XML message." I just need the xml message. The rest I am taking care of. Thanks again!
  • rbrayb
    rbrayb about 11 years
    Understood. So either write the XML yourself - no helper classes - or look here thinktecture.github.com/Thinktecture.IdentityModel.45. This supports a variety of tokens and is open source. If it doesn't support the Token 2.0 stuff, it may give you some leads.
  • rbrayb
    rbrayb about 11 years
  • John Gibb
    John Gibb almost 11 years
    Instead of inheriting the Saml2SecurityTokenHandler just to make a WriteAssertion method, you can just use WriteToken like this: handler.WriteToken(writer, new Saml2SecurityToken(assertion));
  • MacGyver
    MacGyver over 10 years
    Can I use .NET 4.0 and authenticate using .NET 4.5? I have a bunch of .NET 4.0 libraries, so it would take a lot of work to upgrade all of them.
  • surfmuggle
    surfmuggle about 9 years
    Our company is mainly a java shop but i am one of the few .net guys. Out of curiosity does anybody know if the java "standard library / framework" has any built in classes to use SAML 2.0?
  • rbrayb
    rbrayb about 8 years
    Yes - Microsoft have removed the stack from the Internet.
  • Jason D.
    Jason D. about 8 years
  • jaycer
    jaycer almost 6 years
    Updated Saml2Assertion documentation link: docs.microsoft.com/en-us/dotnet/api/…