如何使WCF客户端签署SecurityTokenReference:参考

时间:2012-11-19 12:33:15

标签: wcf digital-signature bea

我需要创建一个调用bea webservice的WCF客户端。

我不断收到来自网络服务的回复:

无法使用任何支持的令牌类型验证签名

所以我将注意力转向客户端< - >服务通信的签名部分:

来自webservice的部分wsdl:

<s0:Policy s1:Id="Sign.xml">
<wssp:Integrity xmlns:wls="http://www.bea.com/wls90/security/policy/wsee#part"
                xmlns:wssp="http://www.bea.com/wls90/security/policy"
                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <wssp:SignatureAlgorithm URI="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
  <wssp:CanonicalizationAlgorithm URI="http://www.w3.org/2001/10/xml-exc-c14n#"/>
  <wssp:Target>
    <wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part"> 
    wls:SystemHeaders()
  </wssp:MessageParts>
  </wssp:Target>
  <wssp:Target>
    <wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <wssp:MessageParts Dialect="http://www.bea.com/wls90/security/policy/wsee#part"> 
    wls:SecurityHeader(wsu:Timestamp)
  </wssp:MessageParts>
  </wssp:Target>
  <wssp:Target>
    <wssp:DigestAlgorithm URI="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
  wsp:Body()
  </wssp:MessageParts>
  </wssp:Target>
  <wssp:SupportedTokens>
    <wssp:SecurityToken 
      IncludeInMessage="true" 
      TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">
      <wssp:TokenIssuer>REMOVED</wssp:TokenIssuer>
    </wssp:SecurityToken>
  </wssp:SupportedTokens>
</wssp:Integrity>
<wssp:MessageAge Age="60" xmlns:wssp="http://www.bea.com/wls90/security/policy"/>

从wsdl我明白我必须签名:

  1. SystemHeaders(我真正的问题)
  2. 时间戳(那样做)
  3. Body(做过那个,也加密了)
  4. 我有生产这种肥皂的工作代码(使用microsoft.web.services3):

    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <ds:CanonicalizationMethod 
            Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"
            xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
          <Reference URI="#Timestamp-fc23bf88-381b-4f2b-b992-ff07b41b5c38"> <!--This is the timestamp-->
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>Removed</DigestValue>
          </Reference>
          <Reference URI="#Id-4b4f1377-eac0-4db0-b334-384d7b14e286"> <!--This is the encrypted body-->
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>Removed</DigestValue>
          </Reference>
          <Reference URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117"> <!--This is the SecurityTokenReference:Reference-->
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>Removed</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>Removed</SignatureValue>
        <KeyInfo>
          <wsse:SecurityTokenReference>
            <wsse:Reference 
              URI="#SecurityToken-dcb8a392-5907-4432-80c6-cbe8f29a6117" 
              ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
          </wsse:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </wsse:Security>
    </soap:Header>
    <soap:Body wsu:Id="Id-4b4f1377-eac0-4db0-b334-384d7b14e286">
    <xenc:EncryptedData 
     Id="Enc-8b5b4ef4-1c12-409b-8159-dec2889a8fa8" 
     Type="http://www.w3.org/2001/04/xmlenc#Content" 
     xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
      <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
      <xenc:CipherData>
        <xenc:CipherValue>Removed<xenc:CipherValue>
      </xenc:CipherData>
    </xenc:EncryptedData>
    </soap:Body>
    

    我承诺使用WCF进行此工作,因此microsoft.web.services3不是一个选项。遗憾。

    我使用svcutil创建了代理。没有汗水。只有手动更改我已经附加

    , ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign
    

    到System.ServiceModel.ServiceContractAttribute

    我当前的代码产生了这个标志部分:

    <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"> <!--This is the body-->
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>Removed</DigestValue>
          </Reference>
          <Reference URI="#uuid-e7f22d2b-5a91-421a-aced-df7ab8a92f8d-1"> <!--This is the timestamp-->
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>Removed</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>Removed</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-3b0e28b3-d47f-4eb2-ab0a-77f94dd76af0-2"/>
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </o:Security>
    </s:Header>
    <s:Body u:Id="_1" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <e:EncryptedData 
      Id="_2" 
      Type="http://www.w3.org/2001/04/xmlenc#Content" 
      xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
      <e:CipherData><e:CipherValue>Removed</e:CipherValue></e:CipherData>
    </e:EncryptedData>
    </s:Body>
    </s:Envelope>
    
    来自我的app.config:

      <system.serviceModel>
        <bindings>
          <customBinding>
            <binding name="testBinding">
              <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" 
                                   messageVersion="Soap11" writeEncoding="utf-8">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" 
                              maxArrayLength="16384" maxBytesPerRead="4096" 
                              maxNameTableCharCount="16384"/>
              </textMessageEncoding>
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288" 
                             maxReceivedMessageSize="65536" allowCookies="false" 
                             authenticationScheme="Anonymous" bypassProxyOnLocal="false" 
                             hostNameComparisonMode="StrongWildcard" keepAliveEnabled="true" 
                             maxBufferSize="65536" proxyAuthenticationScheme="Anonymous" 
                             realm="" transferMode="Buffered" 
                             unsafeConnectionNtlmAuthentication="false" useDefaultWebProxy="true"/>
            </binding>
          </customBinding>
        </bindings>
        <client>
          <endpoint address="http://url.com/testservice/testservicePort" binding="customBinding" 
                    bindingConfiguration="testBinding" 
                    contract="testservicePortType" 
                    name="testservicePort"/>
        </client>
      </system.serviceModel>
    

    我在代码中配置CustomBinding:

        private static CustomBinding CreateCustomBinding()
        {
            var customBinding = new CustomBinding();
    
            SecurityBindingElement securityBindingElement = SecurityBindingElement.CreateMutualCertificateBindingElement(
                    MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
    
            AsymmetricSecurityBindingElement asymmetricSecurityBindingElement =
                (AsymmetricSecurityBindingElement)securityBindingElement;
    
            asymmetricSecurityBindingElement.SetKeyDerivation(false);
    
            asymmetricSecurityBindingElement.EnableUnsecuredResponse = true;
    
            asymmetricSecurityBindingElement.AllowInsecureTransport = true;
            asymmetricSecurityBindingElement.AllowSerializedSigningTokenOnReply = true;
    
            asymmetricSecurityBindingElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;
    
            asymmetricSecurityBindingElement.IncludeTimestamp = true;
            asymmetricSecurityBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
            asymmetricSecurityBindingElement.RequireSignatureConfirmation = false;
    
            asymmetricSecurityBindingElement.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;
    
            customBinding.Elements.Clear();
    
            customBinding.Elements.Add(asymmetricSecurityBindingElement);
    
            customBinding.Elements.Add(new TextMessageEncodingBindingElement()
            {
                MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11,
                AddressingVersion.None),
                WriteEncoding = new System.Text.UTF8Encoding()
            });
    
            HttpTransportBindingElement httpbinding = new HttpTransportBindingElement();
            httpbinding.AuthenticationScheme = AuthenticationSchemes.Anonymous;
            httpbinding.MaxReceivedMessageSize = 1024 * 1024;
            customBinding.Elements.Add(httpbinding);
            return customBinding;
        }
    

    我试图了解microsoft.web.services3代码中发生了什么(我还没写过),似乎作者完全重写了securityheader。这似乎不是最好的解决方案(但可能是唯一的?)

    有人可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

终于想通了: - )

使用这篇文章:

How to make WCF Client conform to specific WS-Security - sign UsernameToken and SecurityTokenReference

在我写上面的问题之前已经阅读了几次(因此标题非常相似),并且真的不明白为什么它应该起作用。但确实如此!

我的自定义绑定现在看起来像这样:

System.ServiceModel.Channels.AsymmetricSecurityBindingElement 
  asymmetricSecurityBindingElement = new AsymmetricSecurityBindingElement();
asymmetricSecurityBindingElement.MessageSecurityVersion = 
          MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;

asymmetricSecurityBindingElement.InitiatorTokenParameters = new
  System.ServiceModel.Security.Tokens.X509SecurityTokenParameters 
    { InclusionMode = SecurityTokenInclusionMode.Never };
asymmetricSecurityBindingElement.RecipientTokenParameters = new
  System.ServiceModel.Security.Tokens.X509SecurityTokenParameters
    { InclusionMode = SecurityTokenInclusionMode.Never };
asymmetricSecurityBindingElement.MessageProtectionOrder =
  System.ServiceModel.Security.MessageProtectionOrder.SignBeforeEncrypt;

asymmetricSecurityBindingElement.SecurityHeaderLayout = SecurityHeaderLayout.LaxTimestampFirst;
asymmetricSecurityBindingElement.EnableUnsecuredResponse = true;
asymmetricSecurityBindingElement.IncludeTimestamp = true;

asymmetricSecurityBindingElement.SetKeyDerivation(false);
asymmetricSecurityBindingElement.DefaultAlgorithmSuite = 
  System.ServiceModel.Security.SecurityAlgorithmSuite.TripleDesRsa15;

asymmetricSecurityBindingElement.EndpointSupportingTokenParameters.Signed.Add(
  new X509SecurityTokenParameters());

customBinding.Elements.Clear();
customBinding.Elements.Add(asymmetricSecurityBindingElement);