WCF 客户端使用 WS-Security 连接到 Java SOAP Web 服务

问题描述:

我在使用 SOAP 1.1 连接到 Java Web 服务的 .NET WCF 客户端时遇到问题.该服务需要使用 WS-Security 协议的 SSL 传输级加密和 SOAP 安全性,两者都使用相同的证书.我已经安装了证书并且可以连接到服务器,但是,当我发布请求时,我收到了 HTTP 500 响应.

I'm having a problem with a .NET WCF client connecting to a Java web service using SOAP 1.1. The service requires both transport level encryption over SSL and SOAP security using the WS-Security protocol, both using the same certificate. I have the certificate installed and I can connect to the server however, I get a HTTP 500 response when I post the request.

我已经能够将 WCF 生成的 SOAP 与 Web 服务开发人员的工作示例进行比较.WCF SOAP 消息具有附加的 Timestamp 和 BinarySecurityToken 元素,这些元素在提供的示例中没有出现.我对 WS-Security 几乎一无所知,对 WCF 知之甚少,所以我希望有人能指出我正确的方向.

I have been able to compare the SOAP produced by WCF with a working example from the developers of the web service. The WCF SOAP message has additional Timestamp and BinarySecurityToken elements which don't occur in the supplied example. I know almost nothing about WS-Security and very little about WCF and so I'm hoping that someone can point me in the correct direction.

这是我的应用程序的配置部分:

Here is the configuration section for my application:

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="JavaServiceSoapBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportWithMessageCredential">
            <transport clientCredentialType="Certificate" proxyCredentialType="None"
                realm="" />
            <message clientCredentialType="Certificate" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://service/endpoint"
          binding="basicHttpBinding" bindingConfiguration="JavaServiceSoapBinding"
          contract="MyCode.MyService" name="MyServicePort" behaviorConfiguration="endpointBehavior">
      </endpoint>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="endpointBehavior">
          <clientCredentials>
            <clientCertificate storeLocation="LocalMachine" storeName="My" findValue="A1A1A1A1" x509FindType="FindBySerialNumber"/>
            <serviceCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

这是我从负责服务的合作伙伴那里获得的示例 SOAP 标头:

And this is the example SOAP header I have from the parter responsible for the service:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.connector.speechanalytics.ept.avaya.com/">
  <soapenv:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <ds:Signature Id="Signature-5" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
          <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
          <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
          <ds:Reference URI="#id-6">
            <ds:Transforms>
              <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <ds:DigestValue>blablabla=</ds:DigestValue>
          </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>
          blablabla=
        </ds:SignatureValue>
        <ds:KeyInfo Id="KeyId-blablabla">
          <wsse:SecurityTokenReference wsu:Id="STRId-blablabla" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <ds:X509Data>
              <ds:X509IssuerSerial>
                <ds:X509IssuerName>CN=Dept,OU=Product,O=Company,L=Location,ST=BLA,C=BLA</ds:X509IssuerName>
                <ds:X509SerialNumber>1319578157</ds:X509SerialNumber>
              </ds:X509IssuerSerial>
            </ds:X509Data>
          </wsse:SecurityTokenReference>
        </ds:KeyInfo>
      </ds:Signature>
    </wsse:Security>
  </soapenv:Header>
  <soapenv:Body wsu:Id="id-6" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

这是 WCF 生成的 SOAP 消息:

and this is the SOAP message that WCF is producing:

<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="_0">
        <u:Created>2012-05-21T15:02:36.448Z</u:Created>
        <u:Expires>2012-05-21T15:07:36.448Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-abd451ed-9bff-4cd0-b9a6-38fcd6bf9e8b-1" 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">blablabla==</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="#_0">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
            <DigestValue>+blablabla=</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>blablabla=</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-abd451ed-9bff-4cd0-b9a6-38fcd6bf9e8b-1"/>
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </o:Security>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

您有关于服务器故障原因的任何详细信息吗?消息不必完全相同.尝试查看 http 500 正文是否包含某些内容,或者供应商是否可以从日志中告诉您.

do you have any details on why the server fails? messages do not have to be exactly the same. try to see if the http 500 body contains something, or if the vendor can tell you from the logs.

接下来恢复为自定义绑定而不是基本的http绑定(自动在线)和安全元素绑定添加属性 includeTimestamp="false".

next revert to a custombinding instead of a basichttpbinding (do this online automatically) and on the security element binding add attribute includeTimestamp="false".

先试试这个(并得到消息).workign w/o BinarySecurityToken 也是可能的,但在这个阶段稍微复杂一些.

try with this first (and get message). workign w/o BinarySecurityToken is also possible but slightly more complex at this stage.