客户端证书通过ARR和AuthorizationContext

时间:2017-10-10 18:35:59

标签: wcf ssl iis ssl-client-authentication

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

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

  1. X-Arr-ClientCert - 使用ARR时包含证书的标头。
  2. X509CertificateClaimSet - 直接发布到IIS时,这是检索客户端证书的方法
  3. 要验证是否允许请求,我会将证书的指纹与某处配置的预期指纹相匹配。令我惊讶的是,当通过不同的方法获得证书时,相同的证书具有不同的指纹。

    为了验证发生了什么,我将两个证书上的“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;
      }
    

2 个答案:

答案 0 :(得分:0)

不确定您的确切方案是什么,但我一直都喜欢使用Octopus Deploy方法来保护服务器&lt; - &gt;触手(客户)沟通。它在Octopus Tentacle communication article中有描述。它们基本上使用SslStream类,自签名X.509证书以及在服务器和触手上配置的可信指纹。

-Marco -

答案 1 :(得分:0)

当再次为同事进行同行评审设置测试时,我的问题似乎已经消失。我不确定是否犯了错误(可能)或重启我的机器有帮助,但无论如何,Thumbprint现在对两种身份验证方法都是可靠的。