2

我有一个 WCF 服务在 IIS 7 over SSL 中运行,使用 basicHttpBinding。这是绑定标签在客户端和服务器上的样子:

<basicHttpBinding>
    <binding name="BasicHttpBinding_IMyService"
             messageEncoding="Mtom"
             transferMode="Buffered">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" />
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
      </security>
    </binding>
</basicHttpBinding>

在服务器端,这是行为标签:

<behaviors>
  <serviceBehaviors>
    <behavior name="myServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

一切正常。

现在,我想切换到证书凭据类型来验证客户端,这就是我卡住的地方。

我做了以下事情:

  1. 在受信任的根证书颁发机构中为当前用户和本地计算机安装了根 CA。
  2. 在上述根 CA 下创建了一个证书,并将其安装在当前用户和本地计算机的个人存储中。
  3. 在运行 IIS 的机器上创建本地用户之间的映射(它实际上与客户端是同一台机器,它是我的开发机器),如此处所述
  4. system.webServer/security/access 中网站的 IIS 配置的 SSL 标志是:SslNegotiateCert(这是默认设置)
  5. 在 IIS 中为网站和我的应用程序设置“接受”客户端证书(这些设置是否需要?据我了解,IIS 与 WCF 用于对客户端进行身份验证的证书无关。)
  6. 我的应用程序在 IIS 中的应用程序池在 LocalService 帐户下运行。我使用 WinHttpCertCfg.exe 工具授予对 LocalService 的访问权限,以获取安装在本地计算机存储中的证书: WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s "Jackson Michael" -a "LocalService"

客户端和服务器的绑定标签现在看起来像这样:

<basicHttpBinding>
    <binding name="BasicHttpBinding_IMyService"
             messageEncoding="Mtom"
             transferMode="Buffered">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate" />
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
      </security>
    </binding>
</basicHttpBinding>

对于客户:

<behaviors>
    <endpointBehaviors>
        <behavior name="clientCertificateEndpointBehavior">
            <clientCredentials>
                <clientCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindBySubjectName" findValue="Jackson Michael" />
            </clientCredentials>
        </behavior>
    </endpointBehaviors>
</behaviors>

在服务器端:

<behaviors>
  <serviceBehaviors>
    <behavior name="myServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceCredentials>
            <clientCertificate>
                <authentication mapClientCertificateToWindowsAccount="true" certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
            </clientCertificate>
        </serviceCredentials>
    </behavior>
</behaviors>

客户端收到 System.ServiceModel.Security.MessageSecurityException:收到来自另一方的不安全或安全错误。有关故障代码和详细信息,请参阅内部 FaultException。

使用 Trace Viewer 查看跟踪输出,我发现:

System.IdentityModel.Tokens.SecurityTokenValidationException:X.509 证书 SN=Jackson,G=Michael,OID.2.5.4.41=Jackson Michael,E=michaeljackson5@jacksons.com,CN=Jackson Michael,C=LK 链构建失败。使用的证书具有无法验证的信任链。更换证书或更改 certificateValidationMode。正确处理了证书链,但其中一个 CA 证书不受策略提供者的信任。

如果我编辑 serviceBehavior 标签并设置 certificateValidationMode="None",我会得到相同的结果。

问题是:

  1. 为什么 certificateValidationMode="None" 被忽略?
  2. 通过使用默认的certificateValidationMode =“ChainTrust”甚至PeerOrChainTrust,我缺少什么来使身份验证工作?

谢谢你。

4

0 回答 0