【问题标题】:Sending X.509 certificates to WCF c#将 X.509 证书发送到 WCF c#
【发布时间】:2015-08-05 06:00:54
【问题描述】:

我有一个使用此类行为的 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 标头中的证书正确地从客户端传递到服务器给我一些建议吗?我错过了什么?

【问题讨论】:

  • 您是如何托管服务的? IIS、窗口服务还是自托管?您是否在商店中正确安装了 CA 和证书?
  • 服务托管在 IIS 上。证书按照此处所述完成:jayway.com/2014/09/03/…我将不胜感激任何建议..
  • 您是否已将 IIS 配置为使用该证书?
  • 我想要实现的是客户端在向服务器发送请求时使用证书。服务器授权这些请求。服务器无需在客户端获得授权。如果我使用消息授权,您能否解释一下是否必须在 IIS 中配置更多内容?
  • 试试这个codeproject.com/Articles/18601/…。可能会有所帮助。

标签: c# web-services wcf


【解决方案1】:

使用证书并不是一件容易的事,特别是在 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 并分配您的证书。如果您在商店中正确安装,证书应该会显示在列表中。

通过这些步骤,我们或许能够知道从哪里开始。可能是服务问题、客户端问题或 IIS 配置问题。希望这能帮助我们双方解决您的问题。

【讨论】:

    【解决方案2】:

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

    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 已关闭...我将查找解决方案,但请验证我的配置是否正常。

    【讨论】:

      猜你喜欢
      • 2012-07-14
      • 2011-07-03
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      相关资源
      最近更新 更多