概述
我似乎有 this post 中列出的问题的变体。然而,那里的答案并没有真正帮助我,而且我的情况有所不同。
我在一家大公司工作,他们决定信任自己作为根证书颁发机构。我开发了一个 Web 应用程序,需要链接到 Azure 中的 VM 中托管的 API。
我的方法
由于我无法在受信任的存储中安装证书,因此我尝试通过代码来执行此操作。我使用的是 ASP.NET Web API v2,并且已将以下代码添加到启动部分:
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
var options = CorsOptions.AllowAll;
app.UseCors(options);
// Override certificate check
ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
}
我的回调如下所示:
public bool MyRemoteCertificateValidationCallback(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
switch (sslPolicyErrors)
{
case SslPolicyErrors.RemoteCertificateChainErrors:
return IsTheCertificateOriginAcceptable(chain);
case SslPolicyErrors.None:
return true;
default:
return false;
}
}
证书来源可接受的功能正在检查问题是否是由于未知根引起的,然后查看未知根是否是代码知道的额外根(因为我无法将受信任根添加到 Azure Web 应用程序 - 如果我有一个安装证书的虚拟机,那就是可行的方法)。
如果没有,它会抛出一个网络异常:
bool IsTheCertificateOriginAcceptable(X509Chain chain)
{
// checks to see if the initail problem is an untrusted root,
// and to extract the origin certificate
if (certificate.IssuerName.Name == expectedIsserName)
{
return true;
}
else
{
throw new WebException($"Certificate origin unacceptable Actual Issue Name '{certificate.IssuerName.Name}', expected issuer name '{expectedIssuerName}'");
}
计划是从虚拟机中查找颁发者名称,然后将其放入代码中 - 这是探索性代码,以找出如何完成连接。
本地运行
然后我用 IIS 设置了两个网站。一个运行此代码,另一个在不同的端口上运行,默认的自签名证书运行我尝试调用的 API 的简单模拟。
当我这样做时,如果我不使用上面的代码,我会得到与 Azure 上相同的错误:
The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
如果我使用该代码,我会收到以下消息
Certificate origin unacceptable Actual Issue Name 'CN=localhost', expected issuer name ''
在 Azure Web 应用程序中
当我将上述代码部署到 Azure 时,我总是收到证书信任错误,这表明回调未被调用。
我无法轻松检查远程服务器的 SSL 设置,因为它未连接到 Internet(我已将我的 Azure Web 应用程序连接到托管 VM 的 VNET)。
考虑到所有这些,除了建议远程服务器从已知且可信的 RCA 获取正确的证书之外,我该如何连接?
最佳答案
事实证明,框架的行为不是我所期望的。
我遇到的情况是自签名根证书和该自签名证书的子证书。在本例中,我原本希望将一个证书标记为 UntrustedRoot
。
但是,在这种情况下,框架的行为仅提供叶证书,因此链的长度为 1。然后该链被分类为 PartialChain
。
我的逻辑是寻找 UntrustedRoot,而不是 PartialChain,因此尽管调用了回调,但我之前返回时缺乏权限。
所以我的逻辑是错误的 - 我通过将回调设置为始终返回 true 来确认这一点。然后,我设置了两个自签名证书,并在本地主机上使用了第二个网站 - 它复制了错误并允许我查看逻辑错误在哪里。
感谢那些发表评论的人,我应该在发布之前检查设置为 true 的回调是否解决了问题。
关于c# - 无法覆盖 Azure Web App 中的服务器证书验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44827738/