简体   繁体   English

WCF wsHttpBinding证书安全协商异常

[英]WCF wsHttpBinding Certificate Security Negotiation Exception

So after having combed through MSDN, countless articles and even SO - I still have nothing to show for days of struggle. 因此,在梳理了MSDN,无数的文章甚至SO之后,经过几天的努力,我仍然没有什么可显示的。

So I have this: WCF service needs to be consumed by a client and I just keep hitting a SecurityNegotiationException 所以我有这个:WCF服务需要由客户端使用,而我一直不断遇到SecurityNegotiationException

Secure channel cannot be opened because security negotiation with the remote endpoint has failed. 无法打开安全通道,因为与远程端点的安全协商失败。 This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. 这可能是由于在用于创建通道的EndpointAddress中缺少或错误指定了EndpointIdentity所致。 Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint. 请验证EndpointAddress指定或暗示的EndpointIdentity正确标识了远程端点。

I've seen this error all over the net and noone seems to have my exact scenario (with a feasible answer atleast). 我已经在网上看到了这个错误,而且似乎没有人知道我的确切情况(至少有一个可行的答案)。

My setup is local and not hosted by IIS (for time being) but hosted via Visual Studios 2010. My GenericIntegration (WCF service) makes use of wsHttpBinding (Message Mode) authenticated by certificates (I have a very custom username/password authentication + authorization class passed as a parameter by design) and there is no backing out of the security measures. 我的设置是本地的,不是由IIS托管的(暂时),而是通过Visual Studios 2010托管的。我的GenericIntegration(WCF服务)利用通过证书验证的wsHttpBinding(消息模式)(我有一个非常自定义的用户名/密码验证+授权)类通过设计作为参数传递),并且没有退出安全措施。

Host's Config 主机的配置

<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="wsHttpEndpintBinding">
      <security mode ="Message">
        <message clientCredentialType="Certificate" establishSecurityContext="false" negotiateServiceCredential="false"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="wsHttpBehaviour" name="GenericIntegration.GenericService">
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpintBinding" 
      name="wsHttpEndpoint" contract="GenericIntegration.GenInterface" />
    <host>
      <baseAddresses>
        <!--<add baseAddress="http://localhost:59082/GenericService.svc" />-->
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="wsHttpBehaviour">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceCredentials>
        <clientCertificate>
          <certificate findValue="GenIntegrationClient" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
          <authentication certificateValidationMode="PeerTrust" />
        </clientCertificate>

        <serviceCertificate findValue="GenIntegrationClient" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
      </serviceCredentials>
    </behavior>
    <behavior name="metadataBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>    

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

And the Client's config 和客户端的配置

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="endpointBehaviour">
                <clientCredentials>
                    <clientCertificate findValue="GenIntegrationClient" storeLocation="LocalMachine" storeName="My"
                        x509FindType="FindBySubjectName" />
                  <serviceCertificate>
                    <authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck"/>
                  </serviceCertificate>
                </clientCredentials>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <bindings>
        <wsHttpBinding>
            <binding name="wsHttpEndpoint" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
                <security mode="Message">
                    <message clientCredentialType="Certificate" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:59082/GenericService.svc"
            binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint" behaviorConfiguration="endpointBehaviour"
            contract="GenService.GenInterface" name="wsHttpEndpoint">
            <identity>
                <certificate encodedValue="AwAAAAEAAAAUAAAAKdyUELIKMtdh2MFsYQ09ja+vyeEgAAAAAQAAACICAAAwggIeMIIBi6ADAgECAhCFBfF1EXQZhkPKaBpQCl84MAkGBSsOAwIdBQAwJDEiMCAGA1UEAxMZNE1PU1RHZW5JbnRlZ3JhdGlvblNlcnZlcjAeFw0xNjA3MjgxNDQ5MjVaFw0zOTEyMzEyMzU5NTlaMCQxIjAgBgNVBAMTGTRNT1NUR2VuSW50ZWdyYXRpb25DbGllbnQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIwsIlz5nZ3HxeYofTpYKr6RcfQMe/jZxPuHcljT+8pBOZ6KmYcyxeRTO074yP6yF8b1IqFskII+qqmCT8nDsb8xdo5Ee0oqL1LKR+xeTgg2ZXXoocxqR1AdxWFVdlMxMSjKIEGE+MnSDdB6vgXahhpUbAS7cdrNoAFKNIz+vrt1AgMBAAGjWTBXMFUGA1UdAQROMEyAEB4cu6OjBqQHct6przmowGyhJjAkMSIwIAYDVQQDExk0TU9TVEdlbkludGVncmF0aW9uU2VydmVyghD75YH5y52zsU5wcmZLJzPiMAkGBSsOAwIdBQADgYEA2BinUmEfgZKcb1qFD1T5ajc2OWHGLjDLpDi8Y7amM4P3rFGvelx7NmCNUH88iGS9LcbDsmY59HcZwUavtPOr4LMRDhl+5YuGht1fIYEk8QSDIhjevijgDOIVBBAeNIA8tva1faMNtYnFXsj0VxMvlrZ4exeKFVFjv2sib5YNFxY=" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

Now about the certificates (and yes this is for testing only): GenIntegrationServer.cer has been created as a selfsigned CA root certificate with a private key to sign client certificates with. 现在介绍证书(是的,这仅用于测试):GenIntegrationServer.cer已创建为具有私钥的自签名CA根证书,用于与客户端证书进行签名。 Both GenIntegrationServer and GenIntegrationClient certificates were generated with makecert . GenIntegrationServer和GenIntegrationClient证书都是使用makecert生成的。 The client certificate is linked to the private key and is correctly installed in the personal store. 客户端证书链接到私钥,并且已正确安装在个人存储中。

I am still quite new to certificates, private keys and secure comms - I simply cannot reason where I make my mistake. 我对证书,私钥和安全通信还很陌生-我根本无法推理出我犯错的地方。 I didn't find too many posts about specifically using certificates in this manner. 我找不到太多关于以这种方式专门使用证书的文章。

Can anyone assist before I lose more hair or sleep over this? 在我失去更多的头发或睡觉之前,有人可以协助吗?

UPDATE 更新

As per request, I added the logging. 根据要求,我添加了日志记录。 But the most they reveal is: 但他们揭示的最多是:

<s:Body>
    <s:Fault>
        <s:Code>
            <s:Value>s:Sender</s:Value>
            <s:Subcode>
                <s:Value>a:InvalidSecurity</s:Value>
            </s:Subcode>
       </s:Code>
       <s:Reason>
           <s:Text xml:lang="en-ZA">An error occurred when verifying security for the message.</s:Text>
       </s:Reason>
    </s:Fault>
</s:Body>

Sadly, I still do not understand why security validation is failing. 可悲的是,我仍然不明白为什么安全验证失败。 Any Ideas? 有任何想法吗?

Turns out I needed to add the certificates to different stores. 原来我需要将证书添加到其他商店。

In addition to already having the certificates set in the personal stores (as indicated by the config), I had to install the the server's certificate on the client and vice versa. 除了已经在个人存储中设置了证书(如配置所示)之外,我还必须在客户端上安装服务器的证书,反之亦然。 I also had to make sure that the client contained the client certificate's personal key and the same with the server. 我还必须确保客户端包含客户端证书的个人密钥,并且与服务器相同。

This does not sound too complete but I'll post a full article on how I did this. 听起来还不太完整,但是我将发表一篇完整的文章来说明如何做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM