在C# .NET 4.5中使用SAML 2.0

37

我希望使用纯.NET(没有外部类、控件、助手)创建一个SAML消息。我在互联网上找到了一些代码,以下是我找到的代码:

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;

}

这里是我正在使用的代码来获取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
    );
}
这似乎会奏效。但是,生成的消息是SAML 1.0版本-我需要使用2.0版本。 我知道我可以做一些马虎的工作,在这里和那里替换一些值,这个系统就能正常工作。消息中几乎没有什么区别,版本是最重要的。 我很难在.NET上找到有关SAML 2.0的信息。我知道SAML 2.0最近被实现到.NET中。我正在使用框架4.5,所以应该可以访问它。SamlAssertion的MSDN页面说“majorVersion”是一个常量,始终设置为“1”。 我猜还有另一个命名空间可以使用,但我还没有找到它。 我的要求只是获取XML SAML消息。我不需要用X509签名,也不需要令牌。只要SAML XML消息即可。 再次说明,这是一个试图找出如何在本地.NET中完成此操作的问题。我已经找到了几个SAML帮助程序和大量代码,介绍了如何手动构建消息-我正在尝试找到正确的解决方案,如果存在的话。 编辑:我发现我可以使用Saml2Assertion。但是,我无法找到将SAML消息写入xml的方法。 编辑2:我已经找到了如何将Saml2Assersion对象写入xml。不幸的是,它不保留SAML语法,而是以纯XML编写,没有标签。

个人而言,我会选择使用库,因为它可以节省时间。您可以使用像http://www.componentpro.com/saml.net/这样的库来帮助您,http://samlcomponent.net/有代码示例。 - Alexey Semenyuk
需要添加 System.IdentityModel.dll 的引用,并添加 System.IdentityModel.Tokens 命名空间。 - Ashish Gupta
2个回答

36

.NET 4.5内置了WIF(Windows Identity Foundation),现在支持SAML 2.0。 要使用SAML 2.0,只需使用.NET 4.5。类名为Saml2XXXX(其中XXXX是令牌、断言、序列化程序等)。这是一个链接到SAML 2.0 Assertion的链接:http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml2.saml2assertion.aspx

这将创建一个SAML 2.0 Assertion对象。 要获取XML,可以使用以下代码:

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

这将把你的断言对象序列化为XML。在这里我遇到了问题。生成的XML不包含saml命名空间(例如<saml:Assertion>)。我没有找到解决办法,所以必须使用Replace("<", "<saml:")


在此处投票:https://connect.microsoft.com/VisualStudio/feedback/details/781848/net-4-5-windows-identity-foundation-should-include-samlp-support - rbrayb
6
不需要继承 Saml2SecurityTokenHandler 就能创建一个 WriteAssertion 方法,只要像这样使用 WriteTokenhandler.WriteToken(writer, new Saml2SecurityToken(assertion)); - John Gibb
1
我能否使用.NET 4.0并使用.NET 4.5进行身份验证?我有一堆.NET 4.0库,因此升级所有这些库需要很多工作。 - Entree
1
我们公司主要使用Java,但我是为数不多的.NET开发人员之一。出于好奇,有没有人知道Java的“标准库/框架”中是否有任何内置类可用于使用SAML 2.0? - surfmuggle
更新的Saml2Assertion文档链接:https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.saml2assertion?view=netframework-4.7.1 - jaycer

4

这是因为Saml2Assertion指的是令牌而不是协议。

WIF中使用的SAML令牌是1.0令牌。

.NET没有SAML 2协议支持。

虽然存在适用于SAML 2的WIF CTP,但它已经很久没有更新了。


1
不正确。SAML2(实际上是WIF)已经完全实现到4.5框架中。这是一个链接:http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.tokens.saml2.saml2assertion.aspx ,此外,SAML2Assertion是断言,并且有一个Saml2Token类用于令牌。到目前为止,一切都运行得非常顺利,除了saml的XML命名空间缺失。一旦我解决了这个问题(可能是XMLWriter问题),我会发布解决方案。 - bugnuker
4
看一下命名空间 - 它是Token而不是Protocol - 协议列表在这里 - http://msdn.microsoft.com/zh-cn/library/ee709285.aspx - rbrayb
感谢提供命名空间链接。我很感激你的回答,没有其他人回答。我不是在寻找协议。我的问题非常清楚。我引用了“我不需要令牌。只需要SAML XML消息。”我只需要XML消息。其余的我会处理。再次感谢! - bugnuker
明白了。那么要么自己编写XML代码 - 不使用任何帮助类 - 要么可以查看这里的网址:http://thinktecture.github.com/Thinktecture.IdentityModel.45/。该网址支持多种令牌,并且是开源的。如果它不支持Token 2.0,它可能会给你一些线索。 - rbrayb
是的 - 微软已经从互联网中删除了堆栈。 - rbrayb
新的 thinktecture 链接:https://github.com/IdentityModel/Thinktecture.IdentityModel.45 - Jason D.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接