简体   繁体   English

将X.509证书发送到WCF C#

[英]Sending X.509 certificates to WCF c#

I have a WCF service which uses such behaviors: 我有使用这种行为的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>

It uses a certficate named "localhost" which I created by makecert. 它使用由makecert创建的名为“ localhost”的证书。 First I created Root Certification Authority and then a certificate. 首先,我创建了根证书颁发机构,然后创建了证书。 I generated also a client certificate which was saved in a file. 我还生成了一个客户端证书,该证书保存在文件中。

Then, I have a client application which consumes that webservice. 然后,我有一个使用该Web服务的客户端应用程序。 App.config consists of: App.config包含:

 <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IWS">
                <security>
                    <message clientCredentialType="Certificate" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>

And I load the cerificate for client from a file: 我从文件加载客户端证书:

  X509Certificate2 client = new X509Certificate2("client.pfx", "pass");

All certificates' stuff seem to be done properly, but when I want to invoke any service method from the client, it says: 所有证书的内容似乎都正确完成,但是当我想从客户端调用任何服务方法时,它说:

The caller was not authenticated by the service 呼叫者未通过服务认证

Could someone, please, give me some advice on how to pass the certificate in SOAP header properly from the client to server? 有人可以给我一些有关如何正确地将SOAP标头中的证书从客户端传递到服务器的建议吗? What do I miss? 我想念什么?

Working with certificate is not an easy task specially for debugging it in WCF. 专门使用WCF调试证书并非易事。 For this reason you may consider the following steps to narrow down your problem. 因此,您可以考虑采取以下步骤来缩小问题范围。

  1. Does your Service run after you embed certificate? 嵌入证书后,您的服务是否运行? One way to test if it is working properly is to try hitting your service in your browser. 测试它是否正常运行的一种方法是尝试在浏览器中启动您的服务。

    Ex. 防爆。 http://localhost/Path/Service.svc HTTP://localhost/Path/Service.svc

  2. Are you accessing the service address in your client same as what is describe in CN=localhost certificate? 您是否正在访问客户端中与CN = localhost证书中描述的地址相同的服务地址?

    Ex. 防爆。 http://location/Path/Service.svc HTTP://location/Path/Service.svc

    And not this : 不是这个:

    Ex. 防爆。 http://computername/Path/Service.svc HTTP://computername/Path/Service.svc

    Or 要么

    Ex. 防爆。 http://computername.domain.com/Path/Service.svc http://computername.domain.com/Path/Service.svc

    Explanation : 说明:

    Certificate will not work if the name in the Common Name of certificate is different in the URL name issued to that certificate. 如果证书的通用名称中的名称与颁发给该证书的URL名称不同,则证书将不起作用。

  3. Are you in the same machine? 您在同一台机器上吗? Certificate with CN=localhost will only work in same machine. CN = localhost的证书只能在同一台计算机上使用。

  4. Since you host your Service in IIS you need to configure your IIS to use the certificate you created and bind it in port 443. 由于将服务托管在IIS中,因此需要将IIS配置为使用创建的证书并将其绑定在端口443中。

    How? 怎么样?

    1. Go to you IIS and Client Default Web Site 转到IIS和客户端默认网站
    2. Click Binding location at the right side 单击右侧的绑定位置
    3. If protocol HTTPS is already configure try to edit it and assign your certificate. 如果已配置协议HTTPS,请尝试对其进行编辑并分配证书。 If not, Add the protocol HTTPS with port 443 and assign your certificate. 如果没有,请添加带有端口443的协议HTTPS并分配您的证书。 Certificate should visible in the list if you installed properly in the store. 如果您在商店中正确安装了证书,则证书应该在列表中可见。

Through these steps we may able to know where to start. 通过这些步骤,我们也许可以知道从哪里开始。 It could be at service problem, client problem or IIS configuration. 可能是服务问题,客户端问题或IIS配置问题。 Hope this will help us both to solve your problem. 希望这能帮助我们双方解决您的问题。

I am struggling with the issue all the time. 我一直在为这个问题而苦苦挣扎。 I reconfigured both client and the server side. 我重新配置了客户端和服务器端。

Web.config (server): Web.config(服务器):

<?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>

And app.config (WinForms Client App): 和app.config(WinForms客户端应用程序):

<?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>

I generated certificates in an application called XCA. 我在名为XCA的应用程序中生成了证书。 First, on the server I generated the root cerificate and a certficate for client. 首先,在服务器上,我为客户端生成了根证书和证书。 I exported it and imported on client machine. 我将其导出并导入到客户端计算机上。 Then I generated the root certificate on the client machine and the next certificate for server. 然后,我在客户端计算机上生成了根证书,并为服务器生成了下一个证书。 I exported it and imported in server's system. 我将其导出并导入到服务器的系统中。 I think the configuration files are OK, but maybe something's wrong with certificates - when I want to invoke a method from the client I get "The caller was not authenticated by the service". 我认为配置文件还可以,但是证书可能有问题-当我想从客户端调用方法时,我收到“服务未验证调用方”。 I tried to add HTTPS with my certificate but it resulted in problems with connection to IIS. 我试图用证书添加HTTPS,但导致与IIS的连接出现问题。 Now IIS is off... I'll look up the solution but please verify if my configs are OK. 现在IIS已关闭...我将查找解决方案,但请验证我的配置是否正常。

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

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