如何以编程方式分配 WCF ClientCredentials ServiceCertificate 属性?
我有一个使用自签名证书通过 https 托管的 WCF 服务。我在以编程方式创建绑定时遇到问题:特别是端点行为的部分。
我的服务配置如下所示:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="DisableServiceCertificateValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"
revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="ContactEmail.Web.EmailService.customBinding0">
<binaryMessageEncoding />
<httpsTransport/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="ContactEmail.Web.EmailService">
<endpoint address="https://xxxxxxxxxxxxxx/EmailService/EmailService.svc" binding="customBinding" bindingConfiguration="ContactEmail.Web.EmailService.customBinding0" contract="ContactEmail.Web.EmailService" behaviorConfiguration="DisableServiceCertificateValidation" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
当我使用“添加服务引用”功能时,生成的客户端按预期工作。鉴于我像这样调用设置证书验证回调:
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
但是,我需要以编程方式设置它,而不是通过客户端上的配置文件提供服务配置,因为该调用将是公共共享库的一部分。因此,我尝试通过向客户端构造函数提供自己的参数来实现此目的,例如:
var myClient = new EmailServiceClient(GetBinding(), new EndpointAddress(Strings.EmailServiceEndpointAddress));
在 GetBinding() 中,我使用 BindingElement 创建 CustomBinding,例如 HttpsTransportBindingElement、BinaryMessageEncodingBindingElement 和 SecurityBindingElement.CreateSecureConversationBindingElement(SecurityBindingElement.CreateUserNameOverTransportBindingElement())。
你知道我如何指定诸如certificateValidationMode =“None”和revocationMode =“NoCheck”之类的内容,或者我是否做错了什么?
I have a WCF service being hosted over https with a self-signed certificate. I'm having trouble programatically creating the binding: specifically the portion of the endpoint behavior.
My Service config looks like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="DisableServiceCertificateValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"
revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="ContactEmail.Web.EmailService.customBinding0">
<binaryMessageEncoding />
<httpsTransport/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="ContactEmail.Web.EmailService">
<endpoint address="https://xxxxxxxxxxxxxx/EmailService/EmailService.svc" binding="customBinding" bindingConfiguration="ContactEmail.Web.EmailService.customBinding0" contract="ContactEmail.Web.EmailService" behaviorConfiguration="DisableServiceCertificateValidation" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
And when I use the "Add Service Reference" feature, the generated client works as expected. Given that I call set up a Cert Validation Callback like this:
System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
However, rather than feed the service configuration through a config file on the client, I need to set it programmatically, because the call will be part of a commonly shared library. So, I'm trying to do this by providing my own parameters to the client constructor like:
var myClient = new EmailServiceClient(GetBinding(), new EndpointAddress(Strings.EmailServiceEndpointAddress));
In GetBinding(), I create CustomBinding with BindingElements like HttpsTransportBindingElement, BinaryMessageEncodingBindingElement and SecurityBindingElement.CreateSecureConversationBindingElement(SecurityBindingElement.CreateUserNameOverTransportBindingElement()).
Do you know how I can specify things like certificateValidationMode="None" and revocationMode="NoCheck" or if I'm doing anything wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
SecureConversation
是 WS-SecureConversation => 的实现高级消息级安全性,其中在首次调用服务期间创建特殊安全令牌(通过作为参数传递给绑定元素创建的消息安全模式进行身份验证),并且此令牌用于保护后续消息。这种安全性还形成了所谓的安全上下文或安全会话。您当前在配置文件中的绑定未使用
SecureConversation
,因此您在代码中定义的绑定与您的服务不兼容。SecureConversation
is implementation of WS-SecureConversation => advanced message level security where special security token is created during first call to the service (authenticated by the message security mode passed as parameter to the binding element creation) and this token is used to secure subsequent messages. This security also forms something know as security context or security session.Your current binding in config file is not using
SecureConversation
so your binding defined in code is not compatible with your service.您的 ClientBase (EmailServiceClient) 上应该有一个 Credentials 属性(类型为 ClientCredentials)(http://msdn.microsoft.com/en-us/library/ms733836.aspx)...并且应该有一个 ServiceCertificate 属性:
http://msdn.microsoft.com/en -us/library/system.servicemodel.description.clientcredentials.servicecertificate.aspx
You should have a Credentials property (of type ClientCredentials) (http://msdn.microsoft.com/en-us/library/ms733836.aspx) on your ClientBase (EmailServiceClient)...and that should have a ServiceCertificate property:
http://msdn.microsoft.com/en-us/library/system.servicemodel.description.clientcredentials.servicecertificate.aspx