UseWsFederationAuthentication - AuthenticationException:根据验证程序,远程证书无效
UseWsFederationAuthentication - AuthenticationException: The remote certificate is invalid according to the validation procedure
每次尝试通过 VS2015 和 IIS Express 运行 我的开发箱上的 MVC 项目时,我都会收到错误消息。它使用此代码对我们的 ADFS 服务器进行身份验证。
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
这是我在浏览器中遇到的错误。
[AuthenticationException: The remote certificate is invalid according
to the validation procedure.]
System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) +231
System.Net.PooledStream.EndWrite(IAsyncResult asyncResult) +15
System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) +119
[WebException: The underlying connection was closed: Could not
establish trust relationship for the SSL/TLS secure channel.]
System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
+606 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
+64
[HttpRequestException: An error occurred while sending the request.]
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
+28 Microsoft.IdentityModel.Protocols.d__0.MoveNext()
+453
[IOException: Unable to get document from:
https://adfs.DOMAIN.com/FederationMetadata/2007-06/FederationMetadata.xml]
Microsoft.IdentityModel.Protocols.d__0.MoveNext()
+830 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +28 Microsoft.IdentityModel.Protocols.<GetAsync>d__1.MoveNext() +606 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()
+28 Microsoft.IdentityModel.Protocols.d__3.MoveNext()
+1332
[InvalidOperationException: IDX10803: Unable to create to obtain
configuration from:
'https://adfs.DOMAIN.com/FederationMetadata/2007-06/FederationMetadata.xml'.]
Microsoft.IdentityModel.Protocols.d__3.MoveNext()
+2226 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
+28 Microsoft.Owin.Security.WsFederation.d__c.MoveNext()
+772 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Security.Infrastructure.d__b.MoveNext()
+447 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Security.Infrastructure.d__8.MoveNext()
+440 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Security.Infrastructure.d__5.MoveNext()
+266 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +1174 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext()
+287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext()
+287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult()
+26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__2.MoveNext()
+272 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +26 Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() +33
Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult
ar) +150
Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult
ar) +42
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult
ar) +9791593
之前可以用,现在不能用了....为什么?
想知道为什么这不起作用,为什么根据验证程序远程证书无效(该程序在哪里?),以及如何备份和 运行ning?
根据堆栈跟踪,身份验证过程的第一步是您的应用程序需要通过 https 下载 ADFS 的元数据,并且 SSL 证书未通过验证程序。
验证过程是什么可以参考SO中的其他问题:The remote certificate is invalid according to the validation procedure
大概有两种修复方法:
- 绝不能用于生产的 hack 是禁用检查:"The remote certificate is invalid according to the validation procedure." using Gmail SMTP server
- 如果 SSL 证书不是自签名的并且仍然有效(例如,由受信任的 CA 颁发,未过期且尚未撤销),您可能需要检查您的客户端计算机是否信任该 CA .这种情况比较少见。
再次感谢 Thuan 的回答。
从回答中我能够思考到底发生了什么(这对于弄清楚事情总是至关重要的)。关键是意识到问题源于远程证书未通过验证检查,而不是其他原因。所以我发现在 UseWsFederationAuthentication 调用中有一个 BackchannelCertificateValidator 选项可用于验证证书是否有效。然后我发现这个 post 帮助我想出了验证证书的代码。
post 从 Microsoft 站点 (https://msdn.microsoft.com/en-us/library/office/dd633677(v=exchg.80).aspx) 找到了他们的代码。在文章中它说了关于代码的内容。
The certificate validation callback method in this example provides
sufficient security for development and testing of EWS Managed API
applications. However, it may not provide sufficient security for your
deployed application. You should always make sure that the certificate
validation callback method that you use meets the security
requirements of your organization.
所以我必须想办法让它只在调试模式下运行。
代码:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
BackchannelCertificateValidator = new CertificateValidator(),
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
}
class:
public class CertificateValidator : ICertificateValidator
{
public bool Validate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
}
每次尝试通过 VS2015 和 IIS Express 运行 我的开发箱上的 MVC 项目时,我都会收到错误消息。它使用此代码对我们的 ADFS 服务器进行身份验证。
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
这是我在浏览器中遇到的错误。
[AuthenticationException: The remote certificate is invalid according to the validation procedure.]
System.Net.TlsStream.EndWrite(IAsyncResult asyncResult) +231
System.Net.PooledStream.EndWrite(IAsyncResult asyncResult) +15
System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar) +119[WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.]
System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) +606 System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar) +64[HttpRequestException: An error occurred while sending the request.]
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28 Microsoft.IdentityModel.Protocols.d__0.MoveNext() +453[IOException: Unable to get document from: https://adfs.DOMAIN.com/FederationMetadata/2007-06/FederationMetadata.xml] Microsoft.IdentityModel.Protocols.d__0.MoveNext() +830 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter1.GetResult() +28 Microsoft.IdentityModel.Protocols.<GetAsync>d__1.MoveNext() +606 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() +28 Microsoft.IdentityModel.Protocols.d__3.MoveNext() +1332[InvalidOperationException: IDX10803: Unable to create to obtain configuration from: 'https://adfs.DOMAIN.com/FederationMetadata/2007-06/FederationMetadata.xml'.] Microsoft.IdentityModel.Protocols.d__3.MoveNext() +2226 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() +28 Microsoft.Owin.Security.WsFederation.d__c.MoveNext() +772 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__b.MoveNext() +447 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__8.MoveNext() +440 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__5.MoveNext() +266 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +1174 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext() +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Security.Infrastructure.d__0.MoveNext() +937 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__5.MoveNext() +287 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter.GetResult() +26 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.d__2.MoveNext() +272 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +26 Microsoft.Owin.Host.SystemWeb.Infrastructure.ErrorState.Rethrow() +33 Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.StageAsyncResult.End(IAsyncResult ar) +150
Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar) +42
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +9791593
之前可以用,现在不能用了....为什么?
想知道为什么这不起作用,为什么根据验证程序远程证书无效(该程序在哪里?),以及如何备份和 运行ning?
根据堆栈跟踪,身份验证过程的第一步是您的应用程序需要通过 https 下载 ADFS 的元数据,并且 SSL 证书未通过验证程序。
验证过程是什么可以参考SO中的其他问题:The remote certificate is invalid according to the validation procedure
大概有两种修复方法:
- 绝不能用于生产的 hack 是禁用检查:"The remote certificate is invalid according to the validation procedure." using Gmail SMTP server
- 如果 SSL 证书不是自签名的并且仍然有效(例如,由受信任的 CA 颁发,未过期且尚未撤销),您可能需要检查您的客户端计算机是否信任该 CA .这种情况比较少见。
再次感谢 Thuan 的回答。
从回答中我能够思考到底发生了什么(这对于弄清楚事情总是至关重要的)。关键是意识到问题源于远程证书未通过验证检查,而不是其他原因。所以我发现在 UseWsFederationAuthentication 调用中有一个 BackchannelCertificateValidator 选项可用于验证证书是否有效。然后我发现这个 post 帮助我想出了验证证书的代码。
post 从 Microsoft 站点 (https://msdn.microsoft.com/en-us/library/office/dd633677(v=exchg.80).aspx) 找到了他们的代码。在文章中它说了关于代码的内容。
The certificate validation callback method in this example provides sufficient security for development and testing of EWS Managed API applications. However, it may not provide sufficient security for your deployed application. You should always make sure that the certificate validation callback method that you use meets the security requirements of your organization.
所以我必须想办法让它只在调试模式下运行。
代码:
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseWsFederationAuthentication(
new WsFederationAuthenticationOptions
{
BackchannelCertificateValidator = new CertificateValidator(),
Wtrealm = realm,
MetadataAddress = adfsMetadata
});
}
class:
public class CertificateValidator : ICertificateValidator
{
public bool Validate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
return true;
}
else
{
// In all other cases, return false.
return false;
}
}
}