签名的SOAP标头具有两个BinarySecurityTokens(实际上,它可以并且应该具有一个) [英] Signed SOAP header has two BinarySecurityTokens (when in fact it could and should have one)

查看:115
本文介绍了签名的SOAP标头具有两个BinarySecurityTokens(实际上,它可以并且应该具有一个)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从STS服务请求安全令牌.该服务是第三方,因此我无法对其进行修改,检查日志等.

I'm trying to requests a security token from a STS service. The service is 3rd party, so I can't modify it, check logs, etc.

生成的请求SOAP消息看起来几乎与我的示例请求相同.仅有两个BinarySecurityToken元素添加了具有相同的值,而正确的请求仅包含一个令牌.

The resulting request SOAP message looks almost identical to a sample request I have. It's only that there are two BinarySecurityToken elements added with identical values, while the proper request contains only one token.

SOAP消息如下:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="uuid-4db59a59-9180-4efe-92d0-14aefcbf68d5-1">
        <u:Created>2014-08-22T07:51:45.763Z</u:Created>
        <u:Expires>2014-08-22T08:51:45.763Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-54e35db8-29dc-4d3c-bba2-c6eacb7cf4e9-4" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">...</o:BinarySecurityToken>
      <o:BinarySecurityToken u:Id="uuid-54e35db8-29dc-4d3c-bba2-c6eacb7cf4e9-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">...</o:BinarySecurityToken>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <Reference URI="#_1">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>...</DigestValue>
          </Reference>
          <Reference URI="#uuid-4db59a59-9180-4efe-92d0-14aefcbf68d5-1">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>...</DigestValue>
          </Reference>
          <Reference URI="#uuid-54e35db8-29dc-4d3c-bba2-c6eacb7cf4e9-2">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>...</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>.../SignatureValue>
        <KeyInfo>
          <o:SecurityTokenReference>
            <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-54e35db8-29dc-4d3c-bba2-c6eacb7cf4e9-4"/>
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </o:Security>
  </s:Header>
  <s:Body u:Id="_1">
    <trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
      <trust:Claims Dialect="http://docs.oasis-open.org/wsfed/authorization/200706/authclaims" xmlns:auth="http://docs.oasis-open.org/wsfed/authorization/200706">
        <auth:ClaimType Uri="custom claim" Optional="true">
          <auth:Value>...</auth:Value>
        </auth:ClaimType>
      </trust:Claims>
      <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey</trust:KeyType>
      <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
      <trust:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</trust:TokenType>
    </trust:RequestSecurityToken>
  </s:Body>
</s:Envelope>

安全绑定元素以及绑定的配置如下:

The security binding element as well as the binding are configured like this:

AsymmetricSecurityBindingElement messageSecurity = SecurityBindingElement.CreateMutualCertificateDuplexBindingElement(
    MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10
);

messageSecurity.IncludeTimestamp = true;
messageSecurity.LocalClientSettings.TimestampValidityDuration = TimeSpan.FromHours(1);
messageSecurity.ProtectTokens = true;
messageSecurity.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
messageSecurity.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
messageSecurity.EnableUnsecuredResponse = true;

X509SecurityTokenParameters initiatorParams = new X509SecurityTokenParameters
{
    InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient,
    ReferenceStyle = SecurityTokenReferenceStyle.Internal,
    RequireDerivedKeys = false,
    X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial
};

X509SecurityTokenParameters recipientParams = new X509SecurityTokenParameters
{
    InclusionMode = SecurityTokenInclusionMode.Never,
    ReferenceStyle = SecurityTokenReferenceStyle.Internal,
    RequireDerivedKeys = false,
    X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial
};

X509SecurityTokenParameters endpointParams = new X509SecurityTokenParameters
{
    InclusionMode = SecurityTokenInclusionMode.Once,
    ReferenceStyle = SecurityTokenReferenceStyle.Internal,
    RequireDerivedKeys = false,
    X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial
};

messageSecurity.InitiatorTokenParameters = initiatorParams;
messageSecurity.RecipientTokenParameters = recipientParams;
messageSecurity.EndpointSupportingTokenParameters.Signed.Add(endpointParams);

HttpsTransportBindingElement elem = new HttpsTransportBindingElement();
CustomBinding binding = new CustomBinding(messageSecurity, new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8), elem);

return binding;

我还专门配置了WSTrustChannelFactory只签名消息(不签名和加密):

I also have specifically configured the WSTrustChannelFactory to only sign messages (not sign & encrypt):

var factory = new WSTrustChannelFactory(binding, endpoint);
factory.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;

唯一的问题是,当我使用X509SecurityTokenParameters时,服务的安全策略提到发起者令牌应该是SAML令牌.这主要是因为我不知道如何添加SAML令牌,但是我不确定这会带来什么变化.

The only thing is that the service's security policy mentions that the initiator token should be a SAML token, while I'm using an X509SecurityTokenParameters. This is mostly because I have no idea how to add a SAML token, but I'm not sure what difference this would make.

作为参考,WS-Security策略是:

For reference, the WS-Security policy is:

<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
    xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> 
        <sp:AsymmetricBinding>
        <wsp:Policy> 
            <sp:InitiatorToken>
                <wsp:Policy>
                    <sp:SamlToken
                    sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> 
                        <wsp:Policy>
                            <sp:WssSamlV11Token10/>
                        </wsp:Policy>
                    </sp:SamlToken>
                </wsp:Policy>
            </sp:InitiatorToken>
        <sp:RecipientToken>
            <wsp:Policy>
                <sp:X509Token
                sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
            <wsp:Policy>
                <sp:WssX509V3Token10/>
            </wsp:Policy>
                </sp:X509Token>
            </wsp:Policy>
        </sp:RecipientToken>
        <sp:AlgorithmSuite>
            <wsp:Policy>
                <sp:Basic256/>
            </wsp:Policy>
        </sp:AlgorithmSuite>
        <sp:Layout>
            <wsp:Policy>
                <sp:Lax/>
            </wsp:Policy>
        </sp:Layout>
        <sp:IncludeTimestamp/>
        <sp:ProtectTokens/>
        <sp:OnlySignEntireHeadersAndBody/>
        </wsp:Policy>
    </sp:AsymmetricBinding>
    <sp:Wss10>
        <wsp:Policy>
            <sp:MustSupportRefKeyIdentifier/>
            <sp:MustSupportRefIssuerSerial/>
        </wsp:Policy>
    </sp:Wss10>
    <sp:SignedParts>
        <sp:Body/>
    </sp:SignedParts>
</wsp:Policy>

最终,我正在寻找一种使消息仅包含一个二进制令牌的方法.如果唯一的方法是在发送SOAP XML之前手动对其进行更改,那么也应如此.

Ultimately, I'm after a way to have the message contain only one binary token. If the only way is to manually alter the SOAP XML just before it is being sent, then so be it.

推荐答案

通过使用以下代码创建绑定,我已经成功地从STS服务中获取了令牌.

I have successfully managed to get a token back from the STS service by using the following code for creating the binding.

当在InitiatorTokenParametersRecipientTokenParametersEndpointSupportingTokenParameters.Signed之一上将X509SecurityTokenParameters.InclusionMode设置为除SecurityTokenInclusionMode.Never以外的任何其他值时,似乎添加了额外的令牌.

It appears that the extra token was being added when X509SecurityTokenParameters.InclusionMode was set to anything else than SecurityTokenInclusionMode.Never on the either of InitiatorTokenParameters, RecipientTokenParameters or EndpointSupportingTokenParameters.Signed.

下面是用于创建绑定的代码,以防其他人需要它:

The code for creating the binding is below, in case anyone else needs it:

var messageSecurity = new AsymmetricSecurityBindingElement
{
    MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10,
    InitiatorTokenParameters = new X509SecurityTokenParameters
    {
        InclusionMode = SecurityTokenInclusionMode.Never,
        ReferenceStyle = SecurityTokenReferenceStyle.Internal,
    },
    RecipientTokenParameters = new X509SecurityTokenParameters
    {
        InclusionMode = SecurityTokenInclusionMode.Never,
        ReferenceStyle = SecurityTokenReferenceStyle.Internal
    },
    MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt,
    SecurityHeaderLayout = SecurityHeaderLayout.Lax,
    EnableUnsecuredResponse = true,
    IncludeTimestamp = true
};
messageSecurity.SetKeyDerivation(false);
messageSecurity.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256;
messageSecurity.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters());
messageSecurity.LocalClientSettings.TimestampValidityDuration = TimeSpan.FromHours(1);
messageSecurity.RequireSignatureConfirmation = true;
messageSecurity.AllowSerializedSigningTokenOnReply = true;

HttpsTransportBindingElement elem = new HttpsTransportBindingElement { RequireClientCertificate = true };
CustomBinding binding = new CustomBinding(messageSecurity, new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8), elem);

我在SOAP正文中的RequestSecurityToken序列化方面也遇到了问题. WCF在这里使用了另一个名称空间:

I also had an issue with the RequestSecurityToken serialization in the SOAP body. WCF was using a different namespace here:

<auth:ClaimType Uri="..." xmlns:auth="http://schemas.xmlsoap.org/ws/2006/12/authorization">

我用一个客户端消息检查器解决了这个问题,在这里我在命名空间被签名和发送之前立即对其进行调整.

I solved this with a client message inspector, where I adjust the namespaces right before they are being signed and sent.

这篇关于签名的SOAP标头具有两个BinarySecurityTokens(实际上,它可以并且应该具有一个)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆