web-dev-qa-db-fra.com

Utilisation de SAML 2.0 dans C # .NET 4.5

J'essaie d'utiliser du .NET pur (pas de classes externes, de contrôles, d'aides) pour créer un message SAML. J'ai trouvé du code sur les interwebs; voici ce que j'ai:

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;

}

et voici le code que j'utilise pour obtenir le 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
    );
}

C'était comme si ça allait marcher. Cependant, le message est produit est SAML version 1.0 - je dois travailler avec 2.0.

Je sais que je peux faire un travail bâclé et remplacer certaines valeurs ici et là et ce système fonctionnerait bien. Il y a très peu de différences dans le message, la version étant la plus importante. J'ai du mal à trouver des informations sur SAML 2.0 pour .NET. Je sais que SAML 2.0 a été récemment implémenté dans .NET. J'utilise Framework 4.5, je devrais donc y avoir accès. La page MSDN pour SamlAssertion indique que "majorVersion" est une constante, toujours définie sur "1".

Je suppose qu'il y a un autre espace de noms avec lequel je pourrais travailler, mais je ne l'ai pas trouvé. Mon exigence est juste d'obtenir le message XML SAML. Je n'ai pas besoin de signer avec X509, je n'ai pas besoin du token. Juste le message XML SAML.

Encore une fois, c'est une question qui tente de savoir comment procéder dans .NET natif. J'ai trouvé plusieurs assistants SAML et beaucoup de code sur la façon de créer le message manuellement - j'essaie de trouver la bonne solution, si elle existe.

EDIT: J'ai trouvé que je peux utiliser Saml2Assertion. Cependant, je n'arrive pas à trouver un moyen d'obtenir le message SAML écrit en xml maintenant.

EDIT2: J'ai trouvé comment écrire l'objet Saml2Assersion en xml. Malheureusement, il ne conserve pas la syntaxe SAML, il écrit en XML pur sans <saml> Mots clés.

33
bugnuker

.NET 4.5 intègre WIF (Windows Identity Foundation). Cela prend désormais en charge SAML 2.0. Pour utiliser SAML 2.0, utilisez simplement .NET 4.5. Le nom de la classe est Saml2XXXX (où XXXX est le jeton, l'assertion, le sérialiseur, etc.) Voici un lien vers l'assertion SAML 2.0: http://msdn.Microsoft.com/en-us/library/Microsoft.identitymodel. tokens.saml2.saml2assertion.aspx

Cela créera un objet d'assertion SAML 2.0. Pour obtenir le XML, voici le code que j'ai utilisé:

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);
        }
    }
}

Cela sérialisera votre objet d'assertion en XML. C'est là que j'ai rencontré des problèmes. Le fichier XML créé ne contient PAS l'espace de noms saml (par exemple <saml:Assertion>). Je n'ai pas pu trouver de solution pour cela, donc une Replace("<", "<saml:") a dû être utilisée.

34
bugnuker

En effet, Saml2Assertion fait référence au jeton et non au protocole.

Le jeton SAML utilisé dans WIF est un jeton 1.0.

Il n'y a pas de prise en charge du protocole SAML 2 dans .NET.

Il y a un WIF CTP pour SAML 2 mais il n'a pas été mis à jour depuis des lustres.

4
nzpcmad