我正在尝试在客户端和服务器上使用证书身份验证设置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和几个证书,给定了相应的权限并将它们放在商店中(LocalPachine和CurrentUSer都绝望了)。据我所知,这一点有效。
调用服务时会出现问题。最新的错误是:
从另一方收到了不安全或不正确安全的故障 派对。请参阅内部FaultException以获取故障代码和详细信息。
无法处理邮件。这很可能是因为 行动'http://tempuri.org/IServiceAPI/MyMethod'是 不正确或因为邮件包含无效或过期 安全上下文令牌或因为之间存在m匹配 绑定。如果服务,安全上下文令牌将无效 由于不活动而中止了频道。防止服务 中止空闲会话过早地增加接收超时 服务端点的绑定。
甚至(上一个错误)
传出消息的身份检查失败。预期的 身份是 “身份(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,因为它们似乎是正确的chouices。除了发布可以由标准JAVA框架使用的服务之外,我没有任何大的限制。
任何人都可以帮我解决这个烂摊子吗?
任何帮助都会受到赞赏
此致
答案 0 :(得分:1)
我设法解决了原来的问题。
关于双向证书身份验证,我发现以下代码项目文章提供了一个工作演示:http://www.codeproject.com/Articles/36683/9-simple-steps-to-enable-X-509-certificates-on-WCF#Step%201:-%20Create%20client%20and%20server%20certificates
虽然这个例子使用了同伴信任,但到目前为止,无论如何我都无法使用正常工作的原型。从这一点开始,我认为唯一的缺陷就是将证书链存储在适当的位置,并为您的项目运行的用户提供私钥。有关如何授予证书的私钥权限的说明,请参阅此文章:http://msdn.microsoft.com/en-us/library/ff647171.aspx#Step6
对于问题的第二部分:如何在WCF服务中区分客户端证书?,您可以使用以下代码获取客户端的证书指纹:
X509Certificate2 certificate = null;
if(ServiceSecurityContext.Current.AuthorizationContext.ClaimSets == null)
throw new Exception("No claim set");
foreach(var claim in ServiceSecurityContext.Current.AuthorizationContext.ClaimSets)
if(claim is X509CertificateClaimSet)
{
X509CertificateClaimSet xcset = claim as X509CertificateClaimSet;
certificate = xcset.X509Certificate;
break;
}
if(certificate == null)
throw new Exception("No X509 certificate found");
string clientCertificateThumbprint = certificate.Thumbprint;
这将获得客户的指纹,这些指纹对于您颁发证书的每个客户都会有所不同。当然,所有其他证书数据都可用。
答案 1 :(得分:0)
无法处理邮件。这很可能是因为“http://tempuri.org/IServiceAPI/MyMethod”操作不正确,或者因为邮件包含无效或过期的安全上下文令牌,或者因为绑定之间存在m匹配。如果服务因不活动而中止通道,则安全上下文令牌将无效。要防止服务中止空闲会话,请过早增加服务端点绑定的接收超时。
这表示服务请求超时。请参阅Windows事件查看器或启用服务登录。请参阅:http://msdn.microsoft.com/en-us/library/ms732023.aspx
传出消息的身份检查失败。对于'http:// localhost:9110 / MyService'目标,预期的身份是'身份(http://schemas.xmlsoap.org/ws/2005/05/identity/right/possessproperty:http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn)'端点。
这表示您的indentity
节点错误地指向了错误的位置。自生成证书以来,您是否更改了服务的位置?如果你事后感动了它就无效了。