ADFS令牌加密证书链验证失败
本文关键字:验证 失败 证书链 加密 令牌 ADFS | 更新日期: 2023-09-27 18:14:20
我有ASP。. NET MVC网站,我将其配置为通过Active Directory联合服务进行身份验证。一切都很好,直到我尝试启用令牌加密。像往常一样,我在IIS上创建了一个自签名证书,将其添加到我的web服务器和ADFS服务器上的受信任根权限,并运行应用程序来了解它是如何工作的。
我的应用程序正确地将我重定向到ADFS服务页面输入凭据。但是当我提交我的登录名和密码时,我立即在同一登录页面上得到"An error occured
"消息,其中没有非常有用的详细信息部分:
Activity ID: 00000000-0000-0000-b039-0080010000e4
Relying party: [My relying party name]
Error time: Fri, 21 Oct 2016 18:48:24 GMT
Cookie: enabled
User agent string: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36
我没有被重定向到我的网站之后,网络面板不包含任何请求。
但是我发现,如果我把下面的设置添加到我的网站的网页。配置,它又开始工作了:
<certificateValidation certificateValidationMode="None" />
所以这个错误一定与我的证书是自签名的这个事实有关。但是我已经将它添加到web服务器和ADFS服务器上的可信根权威(以及其他一些"可疑"证书)。
有没有人知道可能缺少什么和我能做些什么来使我的测试环境与自签名证书一起工作,同时验证证书链?
似乎要解决错误,只需在我的web服务器上添加ADFS令牌签名证书作为受信任的根证书颁发机构即可。
PS:我不确定为什么令牌签名证书链验证在禁用加密时没有引发错误,它与加密有什么关系,但事实是它对我们用于测试的两个环境都有帮助。
我用一个api处理程序做了类似的事情,它作为一个通道,必须询问证书。
可以帮助您排除故障。
将证书验证回调设置为如下内容:
// validate server cert
ServicePointManager.ServerCertificateValidationCallback += ValidateServerCertificate;
然后在验证方法中,您可以询问链:
private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// default validation bool to false
var isValid = false;
// If the certificate is a valid, signed certificate, return true to short circuit any add'l processing.
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
else
{
// cast cert as v2 in order to expose thumbprint prop
var requestCertificate = (X509Certificate2)certificate;
// init string builder for creating a long log entry
var logEntry = new StringBuilder();
// capture initial info for the log entry
logEntry.AppendFormat("Certificate Validation Error - SSL Policy Error: {0} - Cert Issuer: {1} - SubjectName: {2}",
sslPolicyErrors.ToString(),
requestCertificate.Issuer,
requestCertificate.SubjectName.Name);
//init special builder for thumprint mismatches
var thumbprintMismatches = new StringBuilder();
// load valid certificate thumbs for comparison later
var validThumbprints = new string[] { "thumbprint A", "thumbprint N" };
// else if a cert name mismatch then assume api pass thru issue and verify thumb print
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateNameMismatch)
{
// compare thumbprints
var hasMatch = validThumbprints.Contains(requestCertificate.Thumbprint, StringComparer.OrdinalIgnoreCase);
// if match found then we're valid so clear builder and set global valid bool to true
if (hasMatch)
{
thumbprintMismatches.Clear();
isValid = true;
}
// else thumbprint did not match so append to the builder
else
{
thumbprintMismatches.AppendFormat("|Thumbprint mismatch - Issuer: {0} - SubjectName: {1} - Thumbprint: {2}",
requestCertificate.Issuer,
requestCertificate.SubjectName.Name,
requestCertificate.Thumbprint);
}
}
// else if chain issue, then iterate over the chain and attempt find a matching thumbprint
else if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) //Root CA problem
{
// check chain status and log
if (chain != null && chain.ChainStatus != null)
{
// check errors in chain and add to log entry
foreach (var chainStatus in chain.ChainStatus)
{
logEntry.AppendFormat("|Chain Status: {0} - {1}", chainStatus.Status.ToString(), chainStatus.StatusInformation.Trim());
}
// check for thumbprint mismatches
foreach (var chainElement in chain.ChainElements)
{
// compare thumbprints
var hasMatch = validThumbprints.Contains(chainElement.Certificate.Thumbprint, StringComparer.OrdinalIgnoreCase);
// if match found then we're valid so break, clear builder and set global valid bool to true
if (hasMatch)
{
thumbprintMismatches.Clear();
isValid = true;
break;
}
// else thumbprint did not match so append to the builder
else
{
thumbprintMismatches.AppendFormat("|Thumbprint mismatch - Issuer: {0} - SubjectName: {1} - Thumbprint: {2}",
chainElement.Certificate.Issuer,
chainElement.Certificate.SubjectName.Name,
chainElement.Certificate.Thumbprint);
}
}
}
}
// if still invalid and thumbprint builder has items, then continue
if (!isValid && thumbprintMismatches != null && thumbprintMismatches.Length > 0)
{
// append thumbprint entries to the logentry as well
logEntry.Append(thumbprintMismatches.ToString());
}
// log as WARN here and not ERROR - if method ends up returning false then it will bubble up and get logged as an ERROR
LogHelper.Instance.Warning((int)ErrorCode.CertificateValidation, logEntry.ToString().Trim());
}
// determine env
var isDev = EnvironmentHelper.IsDevelopment();
var isTest = EnvironmentHelper.IsTest();
// if env is dev or test then ignore cert errors and return true (reference any log entries created from logic above for troubleshooting)
if (isDev || isTest)
isValid = true;
return isValid;
}
注意:你需要禁用/更改一些自定义代码-拇指指纹的东西,日志等
将证书添加到CA受信任存储区仅意味着您信任证书的颁发者,在本例中是证书本身,因为它是自签名证书。缺少的是证书验证执行链检查和撤销检查,并且这两个检查中有一个失败。请注意,即使您信任一个证书,它仍然可能最近被撤销,因此不应该再被信任。因此,撤销检查总是必要的。对于测试,禁用撤销检查是一种方法。在ADFS方面,您可以禁用每个依赖方的撤销检查。如果检查发生在您自己的代码中,您可以完全禁用检查或使用Stinky Towel的代码选择性地只允许某些证书。