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

时间:2015-08-05 06:00:54

标签: c# web-services wcf

我有一个使用此类行为的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>

它使用由makecert创建的名为“localhost”的证书。首先,我创建了根证书颁发机构,然后是证书。我还生成了一个保存在文件中的客户端证书。

然后,我有一个客户端应用程序,它使用该Web服务。 App.config包含:

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

我从文件中加载客户端的证书:

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

所有证书的内容似乎都已正确完成,但当我想从客户端调用任何服务方法时,它说:

  

未通过服务

验证来电者

请有人就如何正确地将SOAP头中的证书从客户端传递到服务器给我一些建议吗?我错过了什么?

2 个答案:

答案 0 :(得分:0)

使用证书并不是一项特别适合在WCF中进行调试的任务。因此,您可以考虑采取以下步骤来缩小问题范围。

  1. 嵌入证书后,您的服务是否运行?测试它是否正常工作的一种方法是尝试在浏览器中访问您的服务。

    实施例。 http://localhost/Path/Service.svc

  2. 您是否正在访问客户端中与CN = localhost证书中描述的服务地址相同的服务地址?

    实施例。 http://location/Path/Service.svc

    而不是这个:

    实施例。 http://computername/Path/Service.svc

    实施例。 http://computername.domain.com/Path/Service.svc

    说明:

    如果证书的公用名称中的名称与颁发给该证书的URL名称不同,则证书将无效。

  3. 你在同一台机器上吗? CN = localhost的证书只能在同一台机器上使用。

  4. 由于您在IIS中托管服务,因此需要将IIS配置为使用您创建的证书并将其绑定到端口443中。

    如何?

    1. 转到IIS和客户端默认网站
    2. 点击右侧的绑定位置
    3. 如果协议HTTPS已配置,请尝试编辑并分配您的证书。如果没有,请使用端口443添加HTTPS协议并分配您的证书。如果您在商店中正确安装,证书应该在列表中可见。
  5. 通过这些步骤,我们可以知道从哪里开始。它可能是服务问题,客户端问题或IIS配置。希望这有助于我们解决您的问题。

答案 1 :(得分:0)

我一直在努力解决这个问题。我重新配置了客户端和服务器端。

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>

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

我在名为XCA的应用程序中生成了证书。首先,在服务器上,我为客户端生成了根证书和证书。我导出它并在客户机上导入。然后我在客户端计算机上生成了根证书,并为服务器生成了下一个证书。我导出它并导入服务器系统。我认为配置文件没问题,但证书可能有问题 - 当我想从客户端调用一个方法时,我得到“调用者没有被服务认证”。我尝试使用我的证书添加HTTPS,但是它导致了与IIS连接的问题。现在IIS已关闭......我会查找解决方案,但请验证我的配置是否正常。