2

我不是 WCF 专家,我只知道服务安全的基础知识,所以我要指出的大部分内容可能都是错误的。也就是说,我需要调用 3d 方服务,该服务需要 SOAP 标头的特定格式。他们要求soap标头提供:1)时间戳块2)二进制令牌3)摘要(要加密的部分数据的校验和)

他们向我提供了这个请求示例(我已经删除了合理的部分)

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
                                wsu:Id="...omissis...">
      </wsse:BinarySecurityToken>

      <ds:Signature Id="SIG-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <ec:InclusiveNamespaces PrefixList="S" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          </ds:CanonicalizationMethod>
          <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <ds:Reference URI="#TS-5">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                <ec:InclusiveNamespaces PrefixList="wsse S" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
              </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>...omissis...</ds:DigestValue>
          </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>
          ....
          ...omissis...
          ....
        </ds:SignatureValue>
        <ds:KeyInfo Id="KI-...omissis...">
          <wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="STR-...omissis..." xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
            <wsse:Reference URI="#X509-...omissis..." ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/>
          </wsse:SecurityTokenReference>
        </ds:KeyInfo>
      </ds:Signature>
      <wsu:Timestamp wsu:Id="TS-5">
        <wsu:Created>2013-03-27T15:10:18.523Z</wsu:Created>
        <wsu:Expires>2013-03-27T15:26:58.523Z</wsu:Expires>
      </wsu:Timestamp>
    </wsse:Security>
  </S:Header>
<S:Body>
    ...clear (not encrypted) body of the soap request
</S:Body>
</S:Envelope>

他们还给了我一个 WSDL 和一个 xsd。我所做的是创建一个新的 Web 应用程序,使用 wsdl 作为服务参考。检查web.config,我可以看到这已经创建了一个这样的basicHttpBinding

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="CPBinding">
          <security mode="Transport" />
        </binding>
        <binding name="CPBinding1" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://...omissis"
        binding="basicHttpBinding" bindingConfiguration="CPBinding"
        contract="BTClient.CPCUVPortType" name="CPCUVPort" />
    </client>
  </system.serviceModel>

但是这个绑定不使用任何类型的安全策略,所以我创建了一个考虑到证书(对于相互证书)这样的行为

 <behaviors>
      <endpointBehaviors>
        <behavior name="CustomBehaviorForCertificates">
          <clientCredentials>
            <clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="...omissis..." />
            <serviceCertificate>
              <scopedCertificates>
                <add targetUri="https://...omissis..." storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindByThumbprint" findValue="...omissis..." />
              </scopedCertificates>
              <authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck" />
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

并在绑定上引用了这个。通过检查传出消息(使用自定义检查器的 BeforeSendRequest 方法),我可以看到它完全忽略了证书,发送与没有行为的请求相同的请求。3d 派对服务对我的请求的回答如下:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsu:Timestamp wsu:Id="Timestamp-..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        <wsu:Created>2013-09-06T14:31:28Z</wsu:Created>
        <wsu:Expires>2013-09-06T14:36:28Z</wsu:Expires>
      </wsu:Timestamp>
      <wsse:BinarySecurityToken wsu:Id="SecurityToken-...." EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
        ...omissis...
      </wsse: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="#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>...omissis...</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>...omissis...</SignatureValue>
            <KeyInfo>
                <wsse:SecurityTokenReference xmlns="">
                    <wsse:Reference URI="#SecurityToken-...omissis..." 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-ENV:Header>
  <SOAP-ENV:Body wsu:Id="..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <SOAP-ENV:Fault>
      <faultcode>wsse:FailedCheck</faultcode>
      <faultstring>The signature or decryption was invalid</faultstring>
      <detail>
        <e:myfaultdetails xmlns:e="Some-URI">
          <errorCode>500</errorCode>
          <message>INTERNAL_SERVER_ERROR</message>
        </e:myfaultdetails>
      </detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

在做了一些研究之后,我读到要根据要求提供 BinarySecurityToken,我需要实现一个 customBinding。我尝试了不同的方法和组合,但我总是无法取得进展。

例如,通过使用此自定义行为:

  <customBinding>
    <binding name="cb">
      <security authenticationMode="MutualCertificateDuplex" requireDerivedKeys="false" includeTimestamp="true"
        messageProtectionOrder="EncryptBeforeSign" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" />
      <textMessageEncoding messageVersion="Soap11" />
      <httpsTransport />
    </binding>
  </customBinding>

我收到这样的内部服务器错误:

ExceptionType: System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.InnerException: System.ServiceModel.FaultException:Internal Error

而且,最重要的是......我的传出请求始终与 basicHttpBinding 相同!显然我还没有很好地理解一些东西。我可以看到,使用 basicHttpBindig 我可以与他们正确通信,但我无法提供所需的安全片段。如果我尝试使用任何其他绑定之王(例如 wsHttpBinding 或 customBinding),我会收到一条错误消息。有人可以帮我理解做这项工作的正确方法吗?任何帮助将不胜感激。

非常感谢。

编辑:

我正在添加传出请求:

<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>
    <ActivityId CorrelationId="dd479557-7e51-41de-822b-d2ac669ff827" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">bbd2f92b-33d5-4ec0-87b6-690f2142cdf5</ActivityId>
    <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-7b22e181-f551-4821-91e0-cf8c9b8d9eef-1">
        <u:Created>2013-09-09T12:24:03.563Z</u:Created>
        <u:Expires>2013-09-09T12:29:03.563Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken>
        <!-- Removed-->
      </o:BinarySecurityToken>
      <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="#_1">
            <Transforms>
              <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>...omissis...</DigestValue>
          </Reference>
          <Reference URI="#uuid-7b22e181-f551-4821-91e0-cf8c9b8d9eef-1">
            <Transforms>
              <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>...omissis...=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>...omissis...</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-e31a3eed-6ac7-4dcb-bfb2-2384764acd93-2"></o:Reference>
          </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">
    <CPCUValidityRequest xmlns="http://......omissis...">
      <serviceType>3</serviceType>
      <arg1>arg1</arg1>
      <arg2>arg2</arg2>
      ...omissis...
    </CPCUValidityRequest>
  </s:Body>
</s:Envelope>

解决方案:实际上,由于错误,我无法成功调用远程服务(如已接受解决方案的评论中所述。但我可以说这个问题得到了回答,因为我主要设法创建了一个请求类似于所需的。非常感谢 Yaron。

PS:(对于那些将遇到类似问题的人的提示,要检查传出/传入请求,请尝试使用 Microsoft Trace Viewer,按照此答案中的建议启用跟踪https://stackoverflow.com/a/11678740/2274007(请记住也遵循评论中的建议))

4

2 回答 2

3

请发布您的传出请求。在您的绑定中,我将更改为 authenticationMode="mutualCertificate"。否则看起来不错。

此外,为了发送刚刚签名的消息而不是加密的消息,请在您的数据合同 (reference.cs) 顶部添加此属性:

[System.ServiceModel.ServiceContractAttribute(ConfigurationName="ServiceReference1.SimpleServiceSoap", ProtectionLevel=System.Net.Security.ProtectionLevel.Sign)]

此wcf 安全提示文章中有关此方法的更多详细信息。

于 2013-09-06T15:16:54.930 回答
0

试试这个customBinding:

 <customBinding>
    <binding name="cb">
      <security authenticationMode="MutualCertificateDuplex" 
                defaultAlgorithmSuite="Basic128Rsa15" 
                requireDerivedKeys="false"
                enableUnsecuredResponse="true"
                messageProtectionOrder="EncryptBeforeSign" 
                messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
      </security>
      <textMessageEncoding messageVersion="Soap11WSAddressing10"/>
    <httpsTransport />
    </binding>
  </customBinding>
于 2015-07-18T09:30:22.210 回答