【问题标题】:Need signature after SAML token in client request客户端请求中的 SAML 令牌后需要签名
【发布时间】:2014-04-09 01:17:43
【问题描述】:

我有一个带有 SAML 令牌持有者密钥的序列化 SOAP 请求消息,该消息适用于供应商服务。我想用 C# 创建一个演示程序来产生类似的请求。为此,我想编写一个创建自己的 SAML 令牌的客户端。

我已经从自签名证书成功创建了一个 SAML2 令牌,并且我能够使用 ChannelFactoryOperations.CreateChannelWithIssuedToken 方法(.Net 4.0)将它与请求相关联。一切都很好,但我无法弄清楚在断言之后放置签名并使用 SAML 令牌作为签名 KeyIdentifier 来签署时间戳所需的 C#。我什至不确定我在问什么,但似乎令牌本身之后的签名应该是简单的部分。但是,我在请求中获取 SAML 的唯一方法是将其声明为 BearerKey 类型。但是 BearerKey 似乎在断言之后省略了签名。看来我想要 SymmetricKey,但令牌“没有密钥”。如何让这样的签名元素出现在断言之后?

这里的 URI="#_1" 指的是上面的 WS-Security 时间戳(未显示)。

【问题讨论】:

    标签: c# wcf interop saml self-signed


    【解决方案1】:

    大家好,我不敢相信我终于弄明白了这一切。此代码加载自签名证书,生成 SAML 令牌,然后使用 SAML 令牌为消息背书。我遇到的问题是“令牌没有密钥”错误。这是通过创建 issuerToken 和密钥并将其传递给令牌构造函数来解决的。见下文。我认为我在网上找到的最有用的信息是这里的这篇很棒的帖子http://devproconnections.com/development/generating-saml-tokens-wif-part-2

            X509Certificate2 cert = new X509Certificate2("C:\\Users\\foobar\\desktop\\test.pfx", "test", X509KeyStorageFlags.MachineKeySet);
            RSACryptoServiceProvider rsa = cert.PrivateKey as RSACryptoServiceProvider;
            RsaSecurityKey rsaKey = new RsaSecurityKey(rsa);
            RsaKeyIdentifierClause rsaClause = new RsaKeyIdentifierClause(rsa);
            SecurityKeyIdentifier signingSki = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[] { rsaClause });
            SigningCredentials signingCredentials = new SigningCredentials(rsaKey, SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest, signingSki);
            Saml2NameIdentifier saml2NameIdentifier = new Saml2NameIdentifier("C=US,O=hi mom,CN=test", new System.Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"));
            Saml2Assertion saml2Assertion2 = new Saml2Assertion(saml2NameIdentifier);
            saml2Assertion2.SigningCredentials = signingCredentials;
            Saml2Subject saml2Subject = new Saml2Subject();
            saml2NameIdentifier = new Saml2NameIdentifier("foo@bar.edu", new System.Uri("urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName"));
            saml2Subject.NameId = saml2NameIdentifier;
            Saml2SubjectConfirmationData subjectConfirmationData = new Saml2SubjectConfirmationData();
            Saml2SubjectConfirmation subjectConfirmation = new Saml2SubjectConfirmation(new Uri("urn:oasis:names:tc:SAML:2.0:cm:holder-of-key"));
            subjectConfirmation.SubjectConfirmationData = subjectConfirmationData;
            subjectConfirmationData.KeyIdentifiers.Add(signingSki);
            saml2Subject.SubjectConfirmations.Add(subjectConfirmation);
            saml2Assertion2.Subject = saml2Subject;
            Saml2AuthenticationContext saml2AuthCtxt = new Saml2AuthenticationContext(new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:X509"));
            Saml2AuthenticationStatement saml2AuthStatement = new Saml2AuthenticationStatement(saml2AuthCtxt);
            saml2AuthStatement.SessionIndex = "123456";
            saml2Assertion2.Statements.Add(saml2AuthStatement);
            Saml2AttributeStatement saml2AttStatement = new Saml2AttributeStatement();
            Saml2Attribute saml2Attribute = new Saml2Attribute("urn:oasis:names:tc:xspa:1.0:subject:subject-id", "foo bar test");
            saml2AttStatement.Attributes.Add(saml2Attribute);
            saml2Attribute = new Saml2Attribute("urn:oasis:names:tc:xspa:1.0:subject:organization", "urn:oid:"+senderOid);
            saml2AttStatement.Attributes.Add(saml2Attribute);
            saml2Attribute = new Saml2Attribute("urn:oasis:names:tc:xspa:1.0:subject:organization-id", "urn:oid:" + senderOid);
            saml2AttStatement.Attributes.Add(saml2Attribute);
            saml2Attribute = new Saml2Attribute("urn:nhin:names:saml:homeCommunityId", "urn:oid:" + senderOid);
            saml2AttStatement.Attributes.Add(saml2Attribute);
            saml2Attribute = new Saml2Attribute("urn:oasis:names:tc:xacml:2.0:subject:role");
            saml2AttStatement.Attributes.Add(saml2Attribute);
            saml2Assertion2.Statements.Add(saml2AttStatement);
            List<SecurityKey> keyList = new List<SecurityKey>();
            keyList.Add(rsaKey);
            ReadOnlyCollection<SecurityKey> keys = new ReadOnlyCollection<SecurityKey>(keyList);
            X509SecurityToken issuerToken = new X509SecurityToken(cert);
            Saml2SecurityToken token2 = new Saml2SecurityToken(saml2Assertion2,keys,issuerToken);
            XcpdRespondingGatewaySyncService.RespondingGatewaySyncClient myClient = new XcpdRespondingGatewaySyncService.RespondingGatewaySyncClient("IRespondingGatewaySync2");   
            CustomBinding customBinding = myClient.Endpoint.Binding as CustomBinding;
            SecurityBindingElement element = customBinding.Elements.Find<SecurityBindingElement>();
            IssuedSecurityTokenParameters tokenParameters = element.EndpointSupportingTokenParameters.Signed[0].Clone() as IssuedSecurityTokenParameters;
            tokenParameters.TokenType = System.IdentityModel.Tokens.SecurityTokenTypes.Saml;
            tokenParameters.RequireDerivedKeys = false;
            tokenParameters.KeyType = SecurityKeyType.SymmetricKey;
            element.EndpointSupportingTokenParameters.Signed.Clear();
            element.EndpointSupportingTokenParameters.Endorsing.Add(tokenParameters);
            myClient.ChannelFactory.Credentials.SupportInteractive = false;
            myClient.ChannelFactory.ConfigureChannelFactory();
            XcpdRespondingGatewaySyncService.IRespondingGatewaySync myChannel = ChannelFactoryOperations.CreateChannelWithIssuedToken(myClient.ChannelFactory, token2); 
    

    【讨论】:

    • 这非常有帮助,感谢 Doug 给另一个人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-24
    • 1970-01-01
    相关资源
    最近更新 更多