客户端和服务器上都有证书的WCF(消息安全性和wsHttpBinding)

时间:2012-08-23 14:36:20

标签: wcf certificate wshttpbinding

我正在尝试在客户端和服务器上使用证书身份验证设置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框架使用的服务之外,我没有任何大的限制。

任何人都可以帮我解决这个烂摊子吗?

任何帮助都会受到赞赏

此致

2 个答案:

答案 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节点错误地指向了错误的位置。自生成证书以来,您是否更改了服务的位置?如果你事后感动了它就无效了。