我在我的 ASP.NET 核心应用程序中使用第三方库 (Splunk c# SDK)。我正在尝试通过此 SDK 连接到我的本地主机 Splunk 服务,但出现异常:
System.Net.Http.HttpRequestException:无法建立 SSL 连接,请参阅内部异常。
内部异常说:
根据验证程序,远程证书无效。
此 SDK 在后台使用 HTTP 客户端,但我无权访问此对象来配置 HttpClientHandler。
我在谷歌上的所有搜索最终都使用 ServicePointManager 来绕过 SSL 验证,但这个解决方案在 Asp.Net 核心中不起作用。
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
在 asp.Net core 中有什么方法可以绕过这个验证吗?
是的,您可以使用以下代码绕过证书...
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
// Pass the handler to httpclient(from you are calling api)
HttpClient client = new HttpClient(clientHandler);
当我在我的开发机器上使用身份服务器(.net 核心)和 web api(.net 核心)时,我意识到,我需要信任本地主机的 ssl 认证。该命令为我完成了工作:
dotnet dev-certs https --trust
如果您要添加 IHttpClient 并通过 DI 注入,您可以在 Startup.cs 类上添加配置。
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("yourServerName").ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
});
}
然后从你的依赖注入类中调用它。
public class MyServiceClass
{
private readonly IHttpClientFactory _clientFactory;
public MyServiceClass (IConfiguration configuration, IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task<int> DoSomething()
{
var url = "yoururl.com";
var client = _clientFactory.CreateClient("yourServerName");
var result = await client.GetAsync(url);
}
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) =>
{
// local dev, just approve all certs
if (development) return true;
return errors == SslPolicyErrors.None ;
};
这个博客帮助了我
https://www.khalidabuhakmeh.com/validate-ssl-certificate-with-servicepointmanager
这对我有用,
通过提供自定义 HttpClientHandler 创建一个 Splunk.Client.Context,这将绕过 SSL 无效证书错误。
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
// Create Context
Context context = new Context(Scheme.Https, "localhost", 8089, default(TimeSpan), handler);
// Create Service
service = new Service(context);
安装 .NET Core SDK 会将 ASP.NET Core HTTPS 开发证书安装到本地用户证书存储区。证书已安装,但不受信任。要信任证书,请执行一次性步骤以运行 dotnet dev-certs 工具:
dotnet dev-certs https --trust
有关更多信息,请访问此链接
您收到此错误是因为您的应用无法验证连接证书,并且将此错误用于创建会话/登录令牌的 API 尤其常见。您可以如上所示以危险的方式绕过它,但显然这不是一个好的解决方案,除非您只是在测试。
最好和最简单的解决方案是使用“modernhttpclient-updated”Nuget包,其代码在this GitHub repo中共享,其中还有很多文档。
添加 Nuget 包后,将 NativeMessageHandler 传入 HttpClient(),如图所示并构建:
var httpClient = new HttpClient(new NativeMessageHandler());
现在你会注意到你摆脱了那个错误,并且会得到一个不同的错误信息,像这样
Certificate pinning failure: chain error. ---> Javax.Net.Ssl.SSLPeerUnverifiedException: Hostname abcdef.ghij.kl.mn not verified: certificate: sha256/9+L...C4Dw=
要摆脱这个新的错误消息,您必须将错误中的主机名和证书密钥添加到 Pin,并将其添加到 NativeMessageHandler 的 TLSConfig 中,如下所示:
var pin = new Pin();
pin.Hostname = "abcdef.ghij.kl.mn";
pin.PublicKeys = new string[] { "sha256/9+L...C4Dw=" };
var config = new TLSConfig();
config.Pins = new List<Pin>();
config.Pins.Add(pin);
httpClient = new HttpClient(new NativeMessageHandler(true, config)
请记住,您的其他(非令牌生成)API 调用可能不会实现证书固定,因此他们可能不需要这个,而且他们可能经常使用不同的主机名。在这种情况下,您也需要将它们注册为引脚,或者为它们使用不同的 HttpClient!
我必须关闭我的 vpn 才能摆脱这个错误
这很可能是由于您的代理配置不正确造成的。
不幸的是,一些较新的 Windows 工作站的设置是错误的。
通过在 Windows 命令提示符下运行以下脚本来检查您的系统环境变量。
C:\Users\myuserid cho HTTP_PROXY=%HTTP_PROXY%, HTTPS_PROXY=%HTTPS_PROXY%, NO_PROXY=%NO_PROXY% 最终,如果您的代理值已配置,但没有任何 NO_PROXY 设置,您将在尝试访问内部服务时遇到问题。
一些“坏”输出的例子:HTTP_PROXY=http://web-proxymain.us.bank-dns.com:3128/, HTTPS_PROXY=http://web-proxymain.us.bank-dns.com:3128/ , NO_PROXY=
“良好”输出示例:HTTP_PROXY=、HTTPS_PROXY=、NO_PROXY= 或 HTTP_PROXY=http://web-proxymain.us.bank-dns.com:3128/、HTTPS_PROXY=http://web-proxymain.us。 bank-dns.com:3128/, NO_PROXY=localhost,127.0.0.1,.us.bank-dns.com
最终我建议取消设置 HTTP_PROXY 和 HTTPS_PROXY 变量,除非你知道它们做什么,以及你需要它们做什么。
同样重要的是,检查 no_proxy 的值并与您的同事进行比较,看看是否有任何差异,有时是一个点“.”可以有所作为。