66

I am using a third party library (Splunk c# SDK ) in my ASP.NET core application. I am trying to connect to my localhost Splunk service via this SDK, but I get an exception saying:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.

And The inner exception says:

The remote certificate is invalid according to the validation procedure.

This SDK uses HTTP client under the hood, but I don't have access to this object to configure HttpClientHandler.

All my search on google ends up using ServicePointManager to bypass the SSL validation, but this solution doesn't work in Asp.Net core.

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Is there any way to bypass this validation in asp.Net core?

Saamer
  • 4,451
  • 1
  • 10
  • 47
MVafa
  • 721
  • 1
  • 6
  • 6
  • 3
    Can't you register the certificate of the localhost service with your machine, so that it becomes valid? – DiplomacyNotWar Oct 23 '18 at 00:37
  • 1
    @John How can I register that? Can you please elaborate? – MVafa Oct 23 '18 at 05:25
  • 1
    Is your localhost server ASP.NET too? Or? – DiplomacyNotWar Oct 23 '18 at 05:27
  • 1
    @John No it is not. The server is Splunk Enterprise, I just download and install it, it hosts the service on localhost:8089 – MVafa Oct 23 '18 at 05:30
  • 1
    You'll need to find some way to export the SSL certificate it's using, or use your own self-signed certificate. Then you can add it to Windows through `certmgr.msc` – DiplomacyNotWar Oct 23 '18 at 05:53
  • 1
    For `HttpClient`from `Asp.Net Core`, you could try `ServerCertificateCustomValidationCallback `, refer [bypass invalid SSL certificate in .net core](https://stackoverflow.com/questions/38138952/bypass-invalid-ssl-certificate-in-net-core), but it seems you could not pass `HttpClientHandler`, you may check whether `Splunk c# SDK ` could exposes this. – Edward Oct 24 '18 at 06:21

8 Answers8

142

Yes, you can Bypass the certificate using below code...

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);
Daniel Williams
  • 8,464
  • 12
  • 65
  • 100
Rohit Jangid
  • 1,729
  • 1
  • 10
  • 9
20

As I worked with the identity server (.net core) and a web api (.net core) on my developer machine, I realized, that I need to trust the ssl certification of localhost. That command does the job for me:

dotnet dev-certs https --trust
6

This worked for me,

Create a Splunk.Client.Context by providing custom HttpClientHandler, that will bypass SSL invalid cert errors.

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);
Piyush Sagar
  • 2,691
  • 22
  • 26
5

If you are adding an IHttpClient and injecting through DI, u can add the configuration on the Startup.cs class.

public void ConfigureServices(IServiceCollection services)
        {
services.AddHttpClient("yourServerName").ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
            {
               ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }

            });
}

And then call it from your dependency injected class.

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);
}
Yamil Ortega
  • 123
  • 2
  • 10
4
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) =>
{
    // local dev, just approve all certs
    if (development) return true;
    return errors == SslPolicyErrors.None ;
};

This blog helped me

https://www.khalidabuhakmeh.com/validate-ssl-certificate-with-servicepointmanager

4

You get this error because your app isn't able to validate the certificate of the connection, and it's especially common to use this for the API that creates the session/login tokens. You can bypass it in a dangerous way as shown above, but obviously that's not a good solution unless you're just testing.

The best and easiest solution is to use the "modernhttpclient-updated" Nuget package, whose code is shared in this GitHub repo where there's also a lot of documentation.

As soon as you add the Nuget package, pass in a NativeMessageHandler into you HttpClient() as shown and build: var httpClient = new HttpClient(new NativeMessageHandler());

Now you will notice that you got rid of that error and will get a different error message like this Certificate pinning failure: chain error. ---> Javax.Net.Ssl.SSLPeerUnverifiedException: Hostname abcdef.ghij.kl.mn not verified: certificate: sha256/9+L...C4Dw=

To get rid of this new error message, you have to do add the hostname and certificate key from the error to a Pin and add that to the TLSConfig of your NativeMessageHandler as shown:

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)

Keep in mind that your other (non token generating) API calls may not implement certificate pinning so they may not need this, and frequently they may use a different Hostname. In that case you will need to register them as pins too, or just use a different HttpClient for them!

Saamer
  • 4,451
  • 1
  • 10
  • 47
  • 2
    I've been using HttpWebRequest for a while now on this server without an issue, and just starting to get the Remote Validation error, even though the app has no validation procedure, it's just a HttpWebRequest. Are you saying the library above gives more information than what HttpWebRequest provides? – Dan Chase Oct 02 '21 at 18:33
  • 1
    Hey @DanChase did you update your backend or front end framework version? That’s probably the reason why you’re seeing it. Also it seems like you are using HTTPWebRequest instead of an HTTPclient. I don’t have experience with the former, and the question also uses an httpclient – Saamer Oct 03 '21 at 22:41
  • 2
    turned out to be the expired Let's Encrypt Root Certificate that's in the news that caused it, had to remove from the machine. Would have never figured it out, I wish there was some diagnostic with it. I pulled the source on .net mono and looked at the validation, but it didn't really help because it looks like it's just walking up the chain. Removing the expired Root Cert was a hail Mary and it worked. I didn't even see that cert in the chain for the site's cert. Only messed up connecting to itself via FQDN/etc, not to yahoo or google, etc. Scary thing everyone is disabling validation now. – Dan Chase Oct 05 '21 at 02:10
2

Installing the .NET Core SDK installs the ASP.NET Core HTTPS development certificate to the local user certificate store. The certificate has been installed, but it's not trusted. To trust the certificate, perform the one-time step to run the dotnet dev-certs tool:

dotnet dev-certs https --trust

for more information visit this link

MertHaddad
  • 307
  • 3
  • 13
0

I had to turn off my vpn to get rid off this error

Muhammad Awais
  • 1,110
  • 16
  • 17