如何以正确的方式实施客户端证书身份验证?

Posted

技术标签:

【中文标题】如何以正确的方式实施客户端证书身份验证?【英文标题】:How do I implement Client Certificate authentication the right way? 【发布时间】:2013-01-18 21:10:07 【问题描述】:

WCF 具有极强的可扩展性,并且有很多现成的功能,但是我仍然在为一些主题而苦苦挣扎,而且我阅读的文档越多,我就越感到困惑。

我希望从社区中得到一些答案。非常欢迎对任何假设或问题提供反馈。

郑重声明:要真正接受一个答案,我应该将这篇文章分成多个问题,但这会导致更多混乱。 我很确定在线上有一些真正的 WCF 专家可以一次性回答本文档中的几个问题,因此我可以接受一个答案作为使用 IIS 正确设置客户端证书身份验证的真正交易。

让我简述一下情况和合作伙伴的要求:

1:合作伙伴要求和使用客户端证书的问题。

合作伙伴 X 需要在我的后端调用 API,并且他们明确要求使用 Clientcertificate 身份验证。 他们创建了 clientcertificate 并向我们提供了仅带有公钥的证书,因为他们将私钥实际上保持在他们自己的系统中似乎是唯一的逻辑。 证书是在本地计算机帐户上导入的,并查看有效的证书路径。所有中间证书颁发机构以及最终的根证书颁发机构都是受信任的。

2:我们的 WCF 服务器端配置

我的 serviceBehavior 配置如下:

<behavior name="ClientCertificateBehavior">
    <serviceMetadata httpsGetEnabled="true" />
        <serviceCredentials>
        <serviceCertificate findValue="<serialnumber here>" x509FindType="FindBySerialNumber" />
        <clientCertificate>
          <authentication certificateValidationMode="PeerTrust" />
        </clientCertificate>
    </serviceCredentials>
</behavior>

我想我在这里犯了第一个错误,应该使用 ChainTrust 使用证书路径来实际验证证书。你怎么看?

服务配置如下:

<service behaviorConfiguration="ClientCertificateBehavior" name="<Full service namespace and servicename>">
    <endpoint binding="basicHttpBinding" bindingConfiguration="Soap11CertificateBasicHttpBinding"
        contract="<The interface>"></endpoint>
</service>

绑定如下所示:

强制SOAP1.1是basicHttpBinding(根据合作伙伴的规范)。

<binding name="Soap11CertificateBasicHttpBinding">
  <security mode="Transport">
    <transport clientCredentialType="Certificate" />
  </security>
</binding>

3:在 IIS 中托管 WCF 服务以及 IIS 配置

我们在 IIS7 中托管 WCF 服务。 我们将服务所在的文件夹配置为需要 SSL 并接受客户端证书。 身份验证匿名身份验证已启用。


问题是来自合作伙伴的通信正常,我们确信一切正常,但是将 IIS 设置切换为“需要”客户端证书向我们表明,突然之间不再可能成功调用我们的服务.

我认为以下事情没有正确完成是否正确:

serviceBehavior 中的 serviceCerticate 并不是必需的。这是客户端使用的设置。或者是否有必要为服务端点提供此证书信息以匹配客户端发送的证书?

要使客户端证书身份验证在 IIS 中真正起作用,证书需要映射到用户。应授予此用户对包含服务的文件夹的权限,并且应禁用所有身份验证机制(匿名、Windows 等)。 这样 IIS 将处理实际的握手并验证服务通信。 还是更多地将证书映射到用户的额外安全问题?

通过在 IIS 上设置“接受”,我们绕过了客户端和服务器之间的实际证书验证。

必须在 IIS 上为保存服务的文件夹禁用所有身份验证机制,如“匿名”和“Windows”。

【问题讨论】:

【参考方案1】:

在您的场景中,您不需要在 WCF 中配置证书,IIS 会为您处理这些。您可以清除整个&lt;serviceCredentials&gt; 块,因为:

&lt;serviceCertificate&gt; of &lt;serviceCredentials&gt; 指定一个 X.509 证书,该证书将用于向使用 消息安全模式 的客户端验证服务,您不使用该证书,&lt;clientCertificate&gt; of &lt;serviceCredentials&gt; 定义一个 X。 509 证书用于对发送给客户端的消息进行签名和加密,从而形成双工通信模式的服务。

请参阅here 如何将客户端证书映射到用户帐户。

【讨论】:

这是一个明确的声明,谢谢你。您能否回答我是否必须设置“要求”证书而不是“接受”证书才能进行实际的证书验证? 还有一个问题,您可能能够以同样清晰的方式回答。证书身份验证是否需要此用户映射并禁用匿名身份验证才能按预期工作? @GuillaumeSchuermans 我在接受/要求方面找不到明确的来源。至于映射:如果您不映射证书,IIS 将不知道谁在使用给定证书进行身份验证,因此如果没有其他安全措施,任何拥有链接到服务器上受信任根的有效证书的人都可以访问该服务到位。 客户端(合作伙伴)使用具有私钥的证书进行通信。他们为我们提供了一个证书,可以安装在只有公钥的 IIS 上。我想我可以保证只有拥有私钥证书的人才能与我的服务通信? 如果您愿意,您也可以回答这个问题:***.com/questions/14440777/…,因为在一个问题中提出很多问题实际上很奇怪,您应该得到更多代表来深入研究这个问题。它还将帮助其他人更轻松地找到证书映射问题的答案。

以上是关于如何以正确的方式实施客户端证书身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

智能卡如何用于客户端证书身份验证?

Azure 中的客户端证书身份验证和 CA 证书

如何使用 WKWebView 正确实施身份验证质询?

WCF与相互身份验证

使用 Swift 4 和 Alamofire 获取客户端证书以用于 Https 调用身份验证

Web 服务客户端证书/身份验证最佳实践的解决方案