客户端证书通过 ARR 和 AuthorizationContext 具有不同的指纹
Client certificate has different thumprint via ARR and AuthorizationContext
我目前正在开发将使用 client-certificate 身份验证的 WCF 服务原型。我们希望能够直接将我们的应用程序发布到 IIS,但也允许使用 IIS ARR(应用程序请求路由)进行 SSL 卸载。
在仔细阅读文档后,我已经成功地测试了这两种配置。我能够从以下位置检索用于身份验证的客户端证书:
- X-Arr-ClientCert - 使用 ARR 时包含证书的 header。
- X509CertificateClaimSet - 当直接发布到 IIS 时,这是检索客户端证书的方法
为了验证请求是否被允许,我将证书的指纹与某处配置的预期指纹进行了匹配。令我惊讶的是,当通过不同的方式获取证书时,同一个证书有不同的指纹。
为了验证发生了什么,我将两个证书上的 "RawData" 属性 转换为 Base64,发现它是相同的,除了在 X509CertificateClaimSet 的情况下,有 spaces 在证书数据中,而在 ARR 的情况下,没有。否则,两个字符串相同:
我的问题:
还有其他人 运行 参与其中吗?我真的可以依靠指纹吗?如果没有,我的备份计划是对主题和发行者进行检查,但我愿意接受其他建议。
我在下面包含了一些(简化的)示例代码:
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 class、自签名 X.509 证书和在服务器和触手上配置的可信指纹。
-马可-
在为同事的同行评审再次设置测试时,我的问题似乎已经消失了。我不确定我是否犯了错误(可能)或者重启我的机器是否有帮助,但无论如何,指纹现在在两种身份验证方法中都是可靠的。
我目前正在开发将使用 client-certificate 身份验证的 WCF 服务原型。我们希望能够直接将我们的应用程序发布到 IIS,但也允许使用 IIS ARR(应用程序请求路由)进行 SSL 卸载。
在仔细阅读文档后,我已经成功地测试了这两种配置。我能够从以下位置检索用于身份验证的客户端证书:
- X-Arr-ClientCert - 使用 ARR 时包含证书的 header。
- X509CertificateClaimSet - 当直接发布到 IIS 时,这是检索客户端证书的方法
为了验证请求是否被允许,我将证书的指纹与某处配置的预期指纹进行了匹配。令我惊讶的是,当通过不同的方式获取证书时,同一个证书有不同的指纹。
为了验证发生了什么,我将两个证书上的 "RawData" 属性 转换为 Base64,发现它是相同的,除了在 X509CertificateClaimSet 的情况下,有 spaces 在证书数据中,而在 ARR 的情况下,没有。否则,两个字符串相同:
我的问题: 还有其他人 运行 参与其中吗?我真的可以依靠指纹吗?如果没有,我的备份计划是对主题和发行者进行检查,但我愿意接受其他建议。
我在下面包含了一些(简化的)示例代码:
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 class、自签名 X.509 证书和在服务器和触手上配置的可信指纹。
-马可-
在为同事的同行评审再次设置测试时,我的问题似乎已经消失了。我不确定我是否犯了错误(可能)或者重启我的机器是否有帮助,但无论如何,指纹现在在两种身份验证方法中都是可靠的。