我正在将.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;
}
}