如何配置WCF服务以结束由wse3客户端生成的“收件人不理解wcf头安全性”错误?

时间:2013-01-22 21:08:18

标签: wcf soap x509 wse3.0

我正在将.Net 1.1的Web服务升级到WCF。将连接到我的新Web服务的客户端本身就是一个Web服务,并使用WSE3进行设计。我无法控制该网络服务,也不会改变。

记住这一点,我需要保持相同的服务端点和安全性,所以我使用wscf.blue(wsdl first)设计了这个WCF服务,这很有帮助。如果客户端注释了他们的X509消息加密代码,我们的网络服务可以很好地进行通信。但是,如果他们将X509加密保留,他们会收到消息:

“命名空间'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'中的标题'安全'不是此消息的接收者理解,导致消息不被处理。此错误通常表示此消息的发送者已启用接收者无法处理的通信协议。请确保客户端绑定的配置与service的绑定。:在System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage消息,WebResponse响应,Stream responseStream,布尔asyncCall)处于System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName,Object []参数) “

在我的服务上,我向自定义端点行为添加了一个消息检查器,并且触发了AfterReceiveRequest,但它从未进入实际Web服务的方法调用。

我假设我的web.config需要更改,但我不知道要将其更改为什么,以便传统的WSE3 Web服务能够理解。任何想法都会有所帮助:

<configuration>    
<system.web>
    <compilation debug="true" targetFramework="4.0" />
</system.web>
  <system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehaviorUnsecure">
      <serviceCredentials>
        <serviceCertificate storeLocation="LocalMachine"     x509FindType="FindByThumbprint" findValue="xx 11 bb xx as bd ef ag r2 xx xx xx xx xx xx    12    34 56 78 90"/>
      </serviceCredentials>
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="true"/>          
    </behavior>
  </serviceBehaviors>      
  <endpointBehaviors>
    <behavior name="TestContextEndpointBehavior">
      <TestContextEndpointBehaviorExtensionElement />
    </behavior>
  </endpointBehaviors>      
</behaviors>
<bindings>
  <basicHttpBinding>
    <binding name="WebSoap" 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="None" />
    </binding>
  </basicHttpBinding>
      </bindings>
<services>     
  <service name="MyWebservice.MyNamespace.WebSoap"     behaviorConfiguration="ServiceBehaviorUnsecure">       
    <endpoint address="http://localhost:6380/WebSoap.svc" behaviorConfiguration="TestContextEndpointBehavior"
        binding="basicHttpBinding" bindingConfiguration="WebSoap"
        contract="IWebSoap" />

    <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
  </service>
</services>
<extensions>
  <behaviorExtensions>
    <add name="TestContextEndpointBehaviorExtensionElement"
         type="MyWebService.TestContextEndpointBehaviorExtensionElement,     MyLibrary,     Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </behaviorExtensions>
</extensions>
  </system.serviceModel>
</configuration>

**编辑* *

我能够从客户端获取一部分代码,了解他们为连接保护旧Web服务中的soap标头所做的工作。我还发现web page可以提供帮助,但它会留下更多问题。它声明选择身份验证模式。一个选项是AnonymousForCertificate和另一个相互证书。如果您在页面上选择其中一个选项进行查看,则会引导您进入枚举类型,而看起来可能是CertificateOverTransport。如果这三个中的任何一个都有帮助我就不会。例如,我们使用SSL,因此CertificateOverTransport似乎可行,但它表示它需要X.509版本3证书。我怎么想知道什么版本的X509?也许以下代码可以帮助您:

    public bool EncryptAndSignMessage(string sSigningMachine, string sEncryptingMachine, ref SoapContext scSoapContext)
    {
       //sSigningMachine is the WSE client's machine name and sEncryptingMachine is my WCF's IIS server machine.

   //For breavity, removed code to get byHasCodeSigning and byHashCodeEncrypting values. These are essentially the thumprints for the WSE's server's certificate and my WCF's server certificate.

                    X509SecurityToken securityTokenForSigning = this.GetSecurityTokenForSigning(byHashCodeSigning);
        X509SecurityToken securityTokenForEncrypting = this.GetSecurityTokenForEncrypting(byHashCodeEncryption);

        // SPECIFY TIME-TO-LIVE (TTL) FOR SOAP MESSAGE TO MINIMIZE RISK OF SOMEONE INTERCEPTING AND REPLAYING IT 
        scSoapContext.Security.Timestamp.TtlInSeconds = 60;

        // ADD THE CLIENT'S X.509 CERTIFICATES TO THE WS-SECURITY SOAP HEADER 
        scSoapContext.Security.Tokens.Add(securityTokenForSigning);
        scSoapContext.Security.Tokens.Add(securityTokenForEncrypting);

        // CREATE NEW INSTANCE OF THE MESSAGE SIGNATURE CLASS AND ADD THE DIGITAL SIGNATURE TO THE WS-SECURITY SOAP HEADER 
        MessageSignature sig = new MessageSignature(securityTokenForSigning);
        scSoapContext.Security.Elements.Add(sig);

        // CREATE NEW INSTANCE OF THE ENCRYPTED DATA CLASS AND ADD THE SECURITY TOKEN FOR ENCRYPTING TO THE WS-SECURITY SOAP HEADER 
        EncryptedData enc = new EncryptedData(securityTokenForEncrypting);
        scSoapContext.Security.Elements.Add(enc);
        return true;
    }

}

0 个答案:

没有答案