wcf - 客户端证书通过 ARR 和 AuthorizationContext 具有不同的指纹

标签 wcf ssl iis ssl-client-authentication

我目前正在为将使用客户端证书身份验证的 WCF 服务开发原型(prototype)。我们希望能够直接将我们的应用程序发布到 IIS,但也允许使用 IIS ARR(应用程序请求路由)进行 SSL 卸载。

在深入阅读文档后,我已经能够成功测试这两种配置。我能够从以下位置检索用于身份验证的客户端证书:

  1. X-Arr-ClientCert - 使用 ARR 时包含证书的 header 。
  2. X509CertificateClaimSet - 当直接发布到 IIS 时,这是检索客户端证书的方法

为了验证请求是否被允许,我将证书的指纹与某处配置的预期指纹进行匹配。令我惊讶的是,当通过不同的方式获取证书时,同一个证书有不同的指纹。

为了验证发生了什么,我已将两个证书上的“RawData”属性转换为 Base64,发现它是相同的,除了在 X509CertificateClaimSet 的情况下,有空格证书数据,而在 ARR 的情况下,则没有。否则,两个字符串相同:

comparison of base64 strings

我的问题: 有没有其他人遇到过这个,我真的可以依靠指纹吗?如果没有,我的备份计划是对主题和发行者进行检查,但我愿意接受其他建议。

我在下面包含了一些(简化的)示例代码:

  string expectedThumbprint = "...";
  if (OperationContext.Current.ServiceSecurityContext == null ||
    OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets == null ||
    OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets.Count <= 0)
  {
    // Claimsets not found, assume that we are reverse proxied by ARR (Application Request Routing). If this is the case, we expect the certificate to be in the X-ARR-CLIENTCERT header
    IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
    string certBase64 = request.Headers["X-Arr-ClientCert"];
    if (certBase64 == null) return false;
    byte[] bytes = Convert.FromBase64String(certBase64);
    var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(bytes);
    return cert.Thumbprint == expectedThumbprint;
  }
  // In this case, we are directly published to IIS with Certificate authentication.
  else 
  {
    bool correctCertificateFound = false;
    foreach (var claimSet in OperationContext.Current.ServiceSecurityContext.AuthorizationContext.ClaimSets)
    {
      if (!(claimSet is X509CertificateClaimSet)) continue;
      var cert = ((X509CertificateClaimSet)claimSet).X509Certificate;
      // Match certificate thumbprint to expected value
      if (cert.Thumbprint == expectedThumbprint)
      {
        correctCertificateFound = true;
        break;
      }
    }
    return correctCertificateFound;
  }

最佳答案

不确定您的确切场景是什么,但我一直喜欢 Octopus Deploy 方法来保护服务器 <-> 触手(客户端)通信。在他们的 Octopus Tentacle communication article 中有描述.他们基本上使用 SslStream 类、自签名 X.509 证书和在服务器和触手上配置的可信指纹。

-马可-

关于wcf - 客户端证书通过 ARR 和 AuthorizationContext 具有不同的指纹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46673656/

相关文章:

c# - Entity Framework 运行转换代码时抛出异常

asp.net - Microsoft EDGE - 访问此资源所需的安全证书无效

java - SSL 握手异常 : Received fatal alert: handshake_failure followup

iis - Asp.net 将 DLL 重新安装到 GAC 中

http - IIS 7 友好 URL 重写

c# - RESTful WCF Web 服务 POST 问题

swift - 在 Swift 中进行身份验证的 Azure Api 应用

asp.net - 如何忽略证书的错误

iis - 是否可以使用 Microsoft.Web.Administration 在基于云的 Appharbor 或 Azure 上操作 IIS 7?

c# - 无法使用 SSL 访问 WCF 服务