我正在尝试在客户端和服务器上设置具有证书身份验证的 WCF 服务。我正在经历地狱,遍历所有可能的错误消息。
这里的最终目标是使用证书对双方进行身份验证。我将为每个客户颁发一个特定的证书(希望)让我能够将他们区分开来。
到目前为止,我有以下配置文件:
服务器配置文件
<configuration>
<system.serviceModel>
<services>
<service name="ServiceApiImplementation" behaviorConfiguration="myBehaviour">
<host>
<baseAddresses><add baseAddress="http://localhost:9110/MyService"/></baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="IServiceAPI" bindingName="SOAP12Binding">
<identity>
<certificateReference findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/>
</identity>
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SOAP12Binding" receiveTimeout="00:02:00" closeTimeout="00:01:00" openTimeout="00:01:00" sendTimeout="00:01:00">
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="myBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
客户端配置文件
<system.serviceModel>
<client>
<endpoint address="http://localhost:9110/MyService" binding="wsHttpBinding"
bindingConfiguration="SOAP12Binding_IServiceAPI" contract="IServiceAPI"
behaviorConfiguration="behaviour1" name="SOAP12Binding_IServiceAPI">
<identity>
<!-- Value obtained when "Adding a Service Reference in visual studio" -->
<certificate encodedValue="xxxxxxxxxxxxx" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="behaviour1">
<clientCredentials>
<clientCertificate findValue="ClientCertificate" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName"/>
<serviceCertificate>
<defaultCertificate findValue="ServerCertificate" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
<authentication certificateValidationMode="ChainTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="SOAP12Binding_IServiceAPI">
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
我已经为客户端和服务器生成了一个 rootCA 和几个证书,获得了适当的权限并将它们放入存储中(LocalMachine 和 CurrentUSer 都绝望了)。据我所知,这一点是有效的。
调用服务时会出现问题。最新的错误是:
从另一方收到不安全或不正确安全的故障。有关故障代码和详细信息,请参阅内部 FaultException。
无法处理该消息。这很可能是因为操作“http://tempuri.org/IServiceAPI/MyMethod”不正确,或者因为消息包含无效或过期的安全上下文令牌,或者因为绑定之间存在不匹配。如果服务由于不活动而中止通道,则安全上下文令牌将无效。要防止服务过早中止空闲会话,请增加服务端点绑定的接收超时。
甚至(上一个错误)
传出消息的身份检查失败。预期的身份是'身份( http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn )' 用于 'http://localhost:9110/MyService' 目标端点。
错误消息根据我在配置文件中的实验而有所不同。现在,客户端和服务器都在同一台机器上运行,因此,至少,我希望每个应用程序都会通过 rootCA 对另一个应用程序进行身份验证。
请注意,我正在使用 Message Security 和 wsHttpBinding,因为它们似乎是正确的选择。除了发布标准 JAVA 框架可以使用的服务外,我没有任何大的限制。
谁能帮我解决这个烂摊子?
任何帮助将不胜感激
问候,