问题描述
我正在做一个大型项目,该项目广泛使用 WCF 进行各种通信.作为新要求的一部分,我们需要与第三方开发的 SOAP Web服务进行通信.他们的服务是使用Java开发的,具有两个安全要求:
-
它在传输和
上需要 BASIC身份验证 -
必须使用 WS-Security(OASIS)标准对邮件进行签名(未加密)并使用X509证书. p>
我遇到的问题是WCF提供的绑定允许使用传输安全性或消息安全性,但不能同时使用两者.结果,我可以签名SOAP消息或发送BASIC身份验证凭据,但是到目前为止,我还无法按照我的要求完成这两项工作.
几天来我一直在寻找解决方案,到目前为止,我得出的结论是,我最好的选择可能是以编程方式进行自定义绑定.现在,使用几种来源,这就是我的目的:
var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
UserNameSecurityTokenParameters tokenParamenters = new UserNameSecurityTokenParameters();
tokenParamenters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
tokenParamenters.RequireDerivedKeys = false;
b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement());
WSClient svc = new WSClient(b, new EndpointAddress(new Uri("https://serviceurl.com/SoapWS"), new DnsEndpointIdentity("CertificateIdentity"), new AddressHeaderCollection()));
svc.ClientCredentials.UserName.UserName = "username";
svc.ClientCredentials.UserName.Password = "password";
svc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
string resp = svc.DoSomething();
虽然这似乎是在使用证书对消息进行签名(无法完全检查),但基本的身份验证部分并未发生.服务器的响应是:
任何有关我如何获得此绑定以使用BASIC身份验证通过传输进行身份验证的见解都将非常有帮助.预先感谢.
PS:请注意,我无法控制要与之通信的Web服务.
配置https传输通道:
HttpsTransportBindingElement h = new HttpTransportBindingElement();
h.AuthenticationScheme = AuthenticationSchemes.Digest;
h.realm = ...
如果您遇到麻烦,我建议您首先设置一个工作传输基本的HTTP绑定,这样您就可以看到您通过了服务器https传输(您应该期望得到一个肥皂故障b/c缺乏签名)./p>
I'm working in a big project that makes extensive use of WCF for different kinds of communication. As a part of a new requirement, we need to communicate with a SOAP Web Service developed by a third party. Their service is developed with Java and has two security requirements:
it needs BASIC authentication over transport and
the message has to be signed (not encrypted) with a X509 certificate using the WS-Security (OASIS) standard for non-repudiation.
The problem I have is that the bindings provided by WCF allow using either transport or message security, but not both at the same time. As a result I can either sign the SOAP message or send BASIC authentication credentials, but so far I haven't been able to do both as I require.
I have been trying to find a solution for days, and so far I have concluded that probably my best shot is to make a custom binding programmatically. Using several sources, this is what I have right now:
var b = new CustomBinding();
var sec = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
UserNameSecurityTokenParameters tokenParamenters = new UserNameSecurityTokenParameters();
tokenParamenters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
tokenParamenters.RequireDerivedKeys = false;
b.Elements.Add(sec);
b.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8));
b.Elements.Add(new HttpsTransportBindingElement());
WSClient svc = new WSClient(b, new EndpointAddress(new Uri("https://serviceurl.com/SoapWS"), new DnsEndpointIdentity("CertificateIdentity"), new AddressHeaderCollection()));
svc.ClientCredentials.UserName.UserName = "username";
svc.ClientCredentials.UserName.Password = "password";
svc.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("Certificate.p12", "password");
svc.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
string resp = svc.DoSomething();
While this seems to be signing the message with the certificate (haven't been able to fully check), the basic authentication part is not happening. The response from the server is:
Any insights on how I could get this binding to authenticate over transport with BASIC authentication would be very helpful. Thanks in advance.
PS: please note that I have no control over the web service I am trying to communicate with.
Configure the https transport channel:
HttpsTransportBindingElement h = new HttpTransportBindingElement();
h.AuthenticationScheme = AuthenticationSchemes.Digest;
h.realm = ...
If you get into trouble I suggest to first set up a workign transport basic http binding just so you would see you pass throguh the server https transport (you should expect to get a soap fault b/c lack of signature).
这篇关于具有传输和消息安全性的WCF绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!