我正在将 Web 服务从 .Net 1.1 升级到 WCF。将连接到我的新 Web 服务的客户端本身就是一个 Web 服务,并且是使用 WSE3 设计的。我无法控制该网络服务,它不会改变。
牢记这一点,我需要保持相同的服务端点和安全性相同,因此我使用 wscf.blue(首先使用 wsdl)设计了这个 WCF 服务,这很有帮助。如果客户端注释掉他们的 X509 消息加密代码,我们的 web 服务可以很好地通信。但是,如果他们保留 X509 加密,他们会收到以下消息:
“名称空间'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'的标题'Security'未被此收件人理解消息,导致消息不被处理。这个错误一般表示这个消息的发送方启用了接收方无法处理的通信协议。请确保客户端绑定的配置与服务的绑定一致。: at System .Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage 消息,WebResponse 响应,流 responseStream,布尔 asyncCall)在 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(字符串方法名,对象 [] 参数)“
在我的服务中,我向自定义端点行为添加了一个消息检查器,并且 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 标头。我还发现了一个网页,它应该会有所帮助,但它留下了更多问题。它声明选择身份验证模式。一种选择是 AnonymousForCertificate 和另一个 Mutual Certificate。如果您在页面上选择其中一个选项进行查看,它会引导您进入枚举类型,而其中一个似乎可能是 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;
}
}