需要 SSL 证书和客户端证书会在 WCF JSON 服务中引发异常
我有一个使用 JSON 的简单 WCF 服务设置。在此服务中,我想使用带有客户端证书的客户端身份验证。我已通过设置文件夹 /site/services/wcf/json/ 将 IIS 6 配置为需要 SSL 并需要客户端证书。此设置通常称为 2 路 SSL。
但每当我尝试使用生成的 SSL 证书测试页面时,都会遇到异常。
服务“None”的 SSL 设置与 IIS“Ssl、SslNegotiateCert、SslRequireCert”的 SSL 设置不匹配。
Stack Trace:
[NotSupportedException: The SSL settings for the service 'None' does not match those of the IIS 'Ssl, SslNegotiateCert, SslRequireCert'.]
System.ServiceModel.Activation.HostedAspNetEnvironment.ValidateHttpsSettings(String virtualPath, Nullable`1& requireClientCertificate) +117347
System.ServiceModel.Channels.HttpsChannelListener.ApplyHostedContext(String virtualPath, Boolean isMetadataListener) +97
System.ServiceModel.Activation.HostedAspNetEnvironment.ApplyHostedContext(TransportChannelListener listener, BindingContext context) +84
System.ServiceModel.Channels.HttpsTransportBindingElement.BuildChannelListener(BindingContext context) +93
System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener(BindingContext context) +67
System.ServiceModel.Channels.WebMessageEncodingBindingElement.BuildChannelListener(BindingContext context) +49
System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
System.ServiceModel.Channels.Binding.BuildChannelListener(Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) +125
System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession) +337
System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) +668
System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +1228
System.ServiceModel.ServiceHostBase.InitializeRuntime() +60
System.ServiceModel.ServiceHostBase.OnBeginOpen() +27
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +50
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +318
System.ServiceModel.Channels.CommunicationObject.Open() +36
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +184
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +615
我已经测试过证书安装正确。我创建了一个需要客户端身份验证的基本虚拟目录。该虚拟目录包含一个简单的 .htm 文件。我已确认它需要 https,并且它会向我提出客户端证书的挑战,当我证明有效的客户端证书时,它会显示 .htm 页面,而当我没有证明有效的证书时,它不会显示。
当将 IIS 中的这些相同设置应用到我的 WCF 服务时,出现上述异常。我尝试将服务配置为还需要 SSL 和客户端身份验证,但我仍然遇到上述异常。
这是我的设置。
<system.serviceModel>
<!-- behaviors -->
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
<clientCredentials>
<clientCertificate findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceCredentials>
<serviceCertificate findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<!-- bindings -->
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<!-- services -->
<services>
<service name="Service1Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service1.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService1" />
</service>
<service name="Service2Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/Services/WCF/json/Service2.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService2" />
</service>
<service name="Service3Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service3.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService3" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I have a simple WCF service setup that uses JSON. In this service I want to use client authentication with a client certificate. I've configured IIS 6 to require SSL and to require client certificates by setting the folder /site/services/wcf/json/. This setup is typically referred to as 2-way SSL.
But I am getting an exception whenever I try to test the page with the generated SSL certificate.
The SSL settings for the service 'None' does not match those of the IIS 'Ssl, SslNegotiateCert, SslRequireCert'.
Stack Trace:
[NotSupportedException: The SSL settings for the service 'None' does not match those of the IIS 'Ssl, SslNegotiateCert, SslRequireCert'.]
System.ServiceModel.Activation.HostedAspNetEnvironment.ValidateHttpsSettings(String virtualPath, Nullable`1& requireClientCertificate) +117347
System.ServiceModel.Channels.HttpsChannelListener.ApplyHostedContext(String virtualPath, Boolean isMetadataListener) +97
System.ServiceModel.Activation.HostedAspNetEnvironment.ApplyHostedContext(TransportChannelListener listener, BindingContext context) +84
System.ServiceModel.Channels.HttpsTransportBindingElement.BuildChannelListener(BindingContext context) +93
System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener(BindingContext context) +67
System.ServiceModel.Channels.WebMessageEncodingBindingElement.BuildChannelListener(BindingContext context) +49
System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener() +63
System.ServiceModel.Channels.Binding.BuildChannelListener(Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters) +125
System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession) +337
System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result) +668
System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost) +1228
System.ServiceModel.ServiceHostBase.InitializeRuntime() +60
System.ServiceModel.ServiceHostBase.OnBeginOpen() +27
System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +50
System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +318
System.ServiceModel.Channels.CommunicationObject.Open() +36
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +184
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +615
I've tested that the certificates are installed properly. I created a basic virtual directory that required client auth. This virtual directory contains a simple .htm file. I've confirmed it requires https and that it challenges me for my client cert and when I proved a valid client cert it displays the .htm page and when I do not proved a valid cert it does not.
When applying these same settings in IIS to my WCF service I get the above exception. I attempted to configure the services to also require SSL and client auth, but I continue to get the exception above.
Here are my settings.
<system.serviceModel>
<!-- behaviors -->
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<enableWebScript />
<clientCredentials>
<clientCertificate findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceCredentials>
<serviceCertificate findValue="*.MyCompany.com" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<!-- bindings -->
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<!-- services -->
<services>
<service name="Service1Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service1.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService1" />
</service>
<service name="Service2Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/Services/WCF/json/Service2.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService2" />
</service>
<service name="Service3Json" behaviorConfiguration="">
<endpoint address="https://www.MyCompany.com/site/services/wcf/json/Service3.svc"
behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="MyCompany.Services.Wcf.IService3" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个问题实际上比我上面描述的更复杂。最终的解决方案非常简单。
上面原始问题中没有提到的是我们有多个端点:1. SOAP 2. JSON。这些都需要使用双向 SSL 进行保护。
我们的错误如下:
这是我们最终得到的最终配置:
如果我们选择让 SOAP 不使用 2 向 SSL 并且 JSON 需要 2 向 SSL,那么配置将会复杂得多。
The problem actually ended up being more complex than I am describing above. And the resulting solution ended up being quite simple.
Not mentioned above in the original problem is that we have multiple endpoints: 1. SOAP 2. JSON. These need to be both secured with 2-way SSL.
Our mistakes were the following:
Here is the final config we ended up with:
Had we chosen to have SOAP not use 2-way SSL and JSON require 2-way SSL the config would have been a lot more complex.