37

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.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
bugnuker
  • 3,918
  • 7
  • 24
  • 31
  • Personally, I would choose to use a library bc it saves time. You can use a library like this http://www.componentpro.com/saml.net/ to help you and http://samlcomponent.net/ has code examples. – Alexey Semenyuk Dec 16 '14 at 15:44
  • Need to add the reference to System.IdentityModel.dll and add the System.IdentityModel.Tokens namespace. – Ashish Gupta May 01 '15 at 17:31

2 Answers2

36

.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.

Amitd
  • 4,769
  • 8
  • 56
  • 82
bugnuker
  • 3,918
  • 7
  • 24
  • 31
  • Vote here: https://connect.microsoft.com/VisualStudio/feedback/details/781848/net-4-5-windows-identity-foundation-should-include-samlp-support – rbrayb Mar 21 '13 at 20:27
  • 6
    Instead of inheriting the `Saml2SecurityTokenHandler` just to make a `WriteAssertion` method, you can just use `WriteToken` like this: `handler.WriteToken(writer, new Saml2SecurityToken(assertion));` – John Gibb Jul 11 '13 at 22:05
  • 1
    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. – JustBeingHelpful Nov 05 '13 at 06:46
  • 1
    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? – surfmuggle Apr 01 '15 at 09:34
  • Updated Saml2Assertion documentation link: https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.saml2assertion?view=netframework-4.7.1 – jaycer May 30 '18 at 14:20
4

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.

rbrayb
  • 46,440
  • 34
  • 114
  • 174
  • 1
    Incorrect. SAML2 (actually, WIF) was fully implemented into 4.5 Framework. Here is a link: http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml2.saml2assertion.aspx 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. – bugnuker Mar 20 '13 at 22:33
  • 4
    Look at the namespace - it's Token not Protocol - the list of protocols is here - http://msdn.microsoft.com/en-us/library/ee709285.aspx – rbrayb Mar 20 '13 at 23:26
  • 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! – bugnuker Mar 20 '13 at 23:47
  • Understood. So either write the XML yourself - no helper classes - or look here http://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 Mar 21 '13 at 00:03
  • Yes - Microsoft have removed the stack from the Internet. – rbrayb Mar 01 '16 at 18:15
  • New thinktecture link: https://github.com/IdentityModel/Thinktecture.IdentityModel.45 – Jason D. Apr 29 '16 at 15:57