【问题标题】:Using client certificates for authentication使用客户端证书进行身份验证
【发布时间】:2012-01-10 10:08:05
【问题描述】:

客户端机器在当前用户的“My”存储中拥有“TicketSalesClient”证书,在当前用户的“TrustedPeople”存储中拥有“TicketSalesServer”证书。服务器机器在本地机器的“TrustedPeople”存储中具有“TicketSalesClient”证书,在本地机器的“My”存储中具有“TicketSalesServer”证书。

服务在 IIS 7 下运行。下面是 web.config 文件:

<system.serviceModel> 
<services>
  <service behaviorConfiguration="secureBehavior" name="InternetRailwayTicketSales.TicketSalesImplementations.TicketSalesService">
    <endpoint address="TicketSalesService" 
              binding="basicHttpBinding" 
              bindingConfiguration="secureHttpBinding" contract="InternetRailwayTicketSales.TicketSalesInterface.ITicketSales" />

    <endpoint address="TicketSalesServiceSecureMex" 
              binding="basicHttpBinding" 
              bindingConfiguration="secureHttpBinding" 
              contract="IMetadataExchange" />

    <host>
      <baseAddresses>
        <add baseAddress="https://localhost:443/TicketSales/" />            
      </baseAddresses>
    </host>

  </service>
</services>
<bindings>
  <basicHttpBinding>
    <binding name="secureHttpBinding">
      <security mode="Transport">
        <transport clientCredentialType="Certificate"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="secureBehavior">
      <serviceThrottling maxConcurrentInstances="5000" maxConcurrentSessions="5000" />
      <serviceMetadata httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="True" />
      <serviceCredentials>
        <serviceCertificate findValue="TicketSalesServer" 
                            storeLocation="LocalMachine"
                            storeName="My"
                            x509FindType="FindBySubjectName"/>
        <clientCertificate>
          <authentication certificateValidationMode="PeerTrust"/>
        </clientCertificate>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

IIS 中的服务配置为 SSL 和证书要求。

1)现在,当我尝试在客户端中添加服务引用时,我收到:“HTTP 请求被客户端身份验证方案‘匿名’禁止。远程服务器返回错误:(403) Forbidden。”

2)如果我尝试使用浏览器请求元数据端点,我首先应用 SSL 证书,然后收到“凭据不授予查看此目录或页面的权限”的错误。据我了解,这是因为我无法通过浏览器提供客户端凭据。

3)我尝试将 svcutil 与包含客户端凭据的配置文件一起使用:

    <configuration>
  <system.serviceModel>
    <client>
      <endpoint 
        behaviorConfiguration="ClientCertificateBehavior"
        binding="basicHttpBinding"
        bindingConfiguration="Binding1" 
        contract="IMetadataExchange"
        name="https" />
    </client>
    <bindings>
      <basicHttpBinding>
        <binding name="Binding1">
          <security mode="Transport">
            <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCertificateBehavior">
          <clientCredentials>
            <clientCertificate findValue="TicketSalesClient"
                               storeLocation="CurrentUser"
                               storeName="My"
                               x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
    </configuration>

然后:

svcutil https://veryLongAddress.svc?wsdl /config:svcutilConf.config

响应是“底层连接已关闭:无法为 SSL/TLS 安全通道建立信任关系。根据验证程序,远程证书无效”

那我做错了什么?

【问题讨论】:

  • 一个证书用于客户端认证,第二个用于服务认证。我应该在客户端上使用 TicketSalesServer 证书做什么?我应该使用客户自己的证书作为凭证。

标签: wcf client certificate anonymous


【解决方案1】:

在 IIS 中托管服务时,所有端点必须具有相同的传输安全配置。我之前玩过这个,最后我重新定义了 WSDL GET 的绑定(是的,它也定义了内部绑定)。因此,将您对服务的绑定修改为:

  <basicHttpBinding>
    <binding name="secureHttpBinding">
      <security mode="Transport">
        <transport clientCredentialType="Certificate" />
      </security>
    </binding>
  </basicHttpBinding>
  <customBinding>
    <binding name="wsdlBinding">
      <textMessageEncoding messageVersion="None" />
      <httpsTransport requireClientCertificate="true" />
    </binding>
  </customBinding> 

在服务行为中使用:

  <serviceMetadata httpsGetEnabled="true" 
                   httpsGetBinding="customBinding" 
                   httpsGetBindingConfiguration="wsdlBinding" />

这应该强制 WSDL 获取客户端证书,并且它“应该”在浏览器中工作(除非有其他问题)。

【讨论】:

  • 我的元数据交换端点配置有什么问题?
  • 从浏览器访问 WSDL 时不使用 MEX ednpoint。
【解决方案2】:

您的证书安装似乎很好。您可以尝试如下所示并查看输出。尝试从 IE 浏览到该服务,您应该能够看到该服务及其 wsdl。

转到IE,然后

工具 --> Internet 选项 --> 安全 --> Internet --> 自定义级别

工具 --> Internet 选项 --> 安全 --> Intranet --> 自定义级别

现在向下滚动到“杂项”部分以找到禁用选项“当不存在证书或仅存在一个证书时不提示客户端证书选择”。

现在重新启动 IE 并浏览到服务,IE 应该会要求您从个人存储中选择一个客户端证书,您需要选择 mvc.localhost。

如果 TicketSalesClient 证书不可见,则您的客户端证书不在相应的存储中。

这样做的原因是您用于安装证书的文件以及创建证书的目的很重要。当您在证书存储中双击它们时,您可以找到每个证书的用途,您有一个名为 Intended Purpose 的列。确保它用于您的客户端证书。

【讨论】:

  • IE 没有要求我选择证书。客户端证书适用于所有目的。 IIS应该如何配置?在服务和服务器级别应该选择哪种身份验证模式?有很多模式。哪些模式应该开启,哪些模式应该关闭?
  • 如果您按照上述步骤在 IE 中更改 Internet 和 Intranet 中的选项,它应该会提示您选择客户端证书。您可以启用匿名身份验证模式。
  • 好的。我已经更改了 Intranet 的设置。同样的错误。但后来我决定将证书添加到根存储。它有所帮助。现在来自 IE 的请求涉及到客户端证书的确认。当我确认它时,我收到新错误:“此服务的安全设置需要'匿名'身份验证,但托管此服务的 IIS 应用程序未启用它”。
  • 如果我尝试从客户端连接,我会收到“客户端身份验证方案‘匿名’禁止 HTTP 请求。从服务器“协商,NTLM”收到的身份验证标头”。
  • 好的。我在 IIS 中打开了匿名身份验证,现在一切正常。但问题是为什么客户端证书必须在根存储中而不是在 TrustedPeople 中。为什么?
【解决方案3】:

当我们在具有安全类型传输和客户端凭据类型证书的 IIS 中托管 WCF 服务时,然后将您的客户端证书放在根存储中并在 IIS 中启用匿名身份验证。 Enable anonymous authentication in IIS But most important, add your certificate to root store.

【讨论】:

    猜你喜欢
    • 2015-10-29
    • 2018-07-05
    • 2019-01-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多