SAML 1.1 C#中的格式错误的引用

时间:2016-11-21 10:30:31

标签: c# xml saml

我正在尝试在C#中为我正在尝试连接的Web服务构建SAML断言。我使用SamlAssertion和X509 Cert作为SigningCredentials

这会生成SamlSecurityToken,然后我会序列化。当我尝试验证签名时,我收到一条错误消息,说明

  

格式错误的参考元素。

要序列化的代码

        var result = new StringBuilder();
        using (var writer = XmlWriter.Create(result))
        {
            var serializer = new WSSecurityTokenSerializer(SecurityVersion.WSSecurity11, true);
            serializer.WriteToken(writer, obj); //Obj is the SamlSecurityToken
        }

        var xml = result.ToString();

生成签名:

<Signature 
    xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
        <Reference URI="#_caeceed6-7006-4354-a398-75a8e4c52818">
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
            <DigestValue>SOME VALUE</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>SOME VALUE</SignatureValue>
</Signature>

这几乎就是我从网络服务提供商那里得到的例子。部分示例:

<ds:Transforms>
    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="code ds kind rw saml samlp typens #default xsd xsi"></ec:InclusiveNamespaces>
</ds:Transform>

除了一些前缀和 InclusiveNamespaces 标记外,示例和生成的XML看起来几乎相同。

我也看过人们使用SignedXml代替WSSecurityTokenSerializer的例子,为什么会这样?更多地控制生成的XML?或者我可以不使用WSSecurityTokenSerializer来创建令牌吗?

1 个答案:

答案 0 :(得分:1)

我根据Thuan发布的示例创建了一个类来返回正确的元素,我不得不用自定义搜索AssertionID来覆盖SignedXml类,以返回要验证的正确元素。

public class SignedSamlXml : SignedXml
{
    public SignedSamlXml()
    {
    }

    public SignedSamlXml(XmlDocument doc)
        : base(doc)
    {
    }

    public override XmlElement GetIdElement(XmlDocument document, string idValue)
    {
        var idElement = base.GetIdElement(document, idValue);
        if (idElement == null)
        {
            var attributes = document.SelectNodes("//@AssertionID");
            if (attributes == null) return null;

            foreach (XmlAttribute attr in attributes)
            {
                if (attr.Value == idValue)
                {
                    return attr.OwnerElement;
                }
            }
        }

        return idElement;
    }
}