我有一个 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>
一切正常。
现在,我想切换到证书凭据类型来验证客户端,这就是我卡住的地方。
我做了以下事情:
- 在受信任的根证书颁发机构中为当前用户和本地计算机安装了根 CA。
- 在上述根 CA 下创建了一个证书,并将其安装在当前用户和本地计算机的个人存储中。
- 在运行 IIS 的机器上创建本地用户之间的映射(它实际上与客户端是同一台机器,它是我的开发机器),如此处所述
- system.webServer/security/access 中网站的 IIS 配置的 SSL 标志是:SslNegotiateCert(这是默认设置)
- 在 IIS 中为网站和我的应用程序设置“接受”客户端证书(这些设置是否需要?据我了解,IIS 与 WCF 用于对客户端进行身份验证的证书无关。)
- 我的应用程序在 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",我会得到相同的结果。
问题是:
- 为什么 certificateValidationMode="None" 被忽略?
- 通过使用默认的certificateValidationMode =“ChainTrust”甚至PeerOrChainTrust,我缺少什么来使身份验证工作?
谢谢你。