向WCF c#发送X.509证书
本文关键字:证书 发送 WCF | 更新日期: 2023-09-27 18:06:36
我有一个使用这些行为的WCF服务:
<behavior name="WCFServiceCertificate.Service1Behavior">
<!-- 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="false"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</clientCertificate>
<serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
它使用我通过makecert创建的名为"localhost"的证书。首先,我创建了根证书颁发机构,然后创建了证书。我还生成了一个客户端证书,保存在一个文件中。
然后,我有一个使用该web服务的客户端应用程序。
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWS">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
我从一个文件中为客户端加载证书:
X509Certificate2 client = new X509Certificate2("client.pfx", "pass");
所有证书的东西似乎都做得很好,但是当我想从客户端调用任何服务方法时,它说:
调用者未被服务验证
可以有人,请,给我一些建议如何通过SOAP报头证书正确地从客户端到服务器?我错过了什么?
使用证书不是一件容易的事,特别是在WCF中调试它。因此,您可以考虑以下步骤来缩小问题范围。
-
您的服务在嵌入证书后运行吗?测试它是否正常工作的一种方法是尝试在浏览器中访问您的服务。
交货。http://localhost/Path/Service.svc
-
您访问的客户端服务地址是否与CN=localhost证书中描述的相同?
交货。http://location/Path/Service.svc
而不是这个
交货。http://computername/Path/Service.svc
或
交货。http://computername.domain.com/Path/Service.svc
解释:
如果证书通用名称中的名称与颁发给该证书的URL名称不同,则
证书将不起作用
-
你们在同一台机器上吗?CN=localhost的证书只能在同一台机器上工作
-
由于您的服务托管在IIS中,因此您需要配置IIS以使用您创建的证书并将其绑定在端口443
如何?
- 转到您的IIS和客户端默认网站
- 点击右侧的Binding location
- 如果协议HTTPS已经配置尝试编辑它并分配您的证书。如果没有,请添加端口为443的HTTPS协议并分配您的证书。如果您在商店中正确安装了证书,那么证书应该在列表中可见。
通过这些步骤,我们可以知道从哪里开始。可能是服务问题、客户端问题或IIS配置问题。
我一直在努力解决这个问题。我重新配置了客户端和服务器端。
网络。配置(服务器):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WSInfo.WS" behaviorConfiguration="WCFServiceCertificate.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WSInfo.IWS">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFServiceCertificate.Service1Behavior">
<!-- 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="false"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</clientCertificate>
<serviceCertificate findValue="ForServer"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
和App .config (WinForms Client App):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
<binding name="WSHttpBinding_IWS">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://XX.XX.XXX.XXX:XX/WSInfo/WS.svc" behaviorConfiguration="CustomBehavior"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
contract="WSInfo.IWS" name="WSHttpBinding_IWS">
<identity>
<dns value="ForServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="Client" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
我在一个名为XCA的应用程序中生成证书。首先,在服务器上为客户机生成根证书和证书。我导出它并在客户机上导入。然后,我在客户机上生成根证书,并为服务器生成下一个证书。我导出并导入到服务器系统中。我认为配置文件是可以的,但也许证书有问题——当我想从客户端调用一个方法时,我得到"调用者没有通过服务进行身份验证"。我试图用我的证书添加HTTPS,但它导致连接到IIS的问题。现在IIS关闭了…我会查找解决方案,但请验证我的配置是否OK。