Trusting the self signed certificate to enable SSL on dotnet core #226

Closed
opened 2025-12-29 14:25:46 +01:00 by adam · 8 comments
Owner

Originally created by @alastairtree on GitHub (Nov 27, 2019).

In the following code (tested running on dotnet core 3.0/2.2/2.1) I want to start a stub server with SSL enabled and then call it, and for that https call to be trusted and allowed. However, the self signed cert issued by wiremock is not trusted and the call fails with AuthenticationException: The remote certificate is invalid according to the validation procedure.

I assumed that running on port 5001 would use the self signed kestral dev certs installed by default by the dotnet cli and so be trusted but I think not based on the below failing.

What is the easiest "out of the box" way to get SSL to work like in the example below?
Or is there a way to get wiremock to use a self siged cert I already trust or to get the current certificate out of the server so I can validate it easily in the client?

    class Program
    {
        static async Task Main(string[] args)
        {
            var server1 = FluentMockServer.Start(port:5001, ssl: true);
            server1.Given(Request.Create().UsingGet().WithPath("/example"))
                .RespondWith(Response.Create()
                    .WithStatusCode(200)
                    .WithBodyAsJson( new
                {
                    Message = "Hello world"
                }));

            var client = new HttpClient()
            {
                BaseAddress = new Uri(server1.Urls.Single())
            };
            
            var json = await client.GetAsync("example");

            Console.WriteLine(json);
            Console.WriteLine(await json.Content.ReadAsStringAsync());

            Console.ReadLine();
        }
    }
Originally created by @alastairtree on GitHub (Nov 27, 2019). In the following code (tested running on dotnet core 3.0/2.2/2.1) I want to start a stub server with SSL enabled and then call it, and for that https call to be trusted and allowed. However, the self signed cert issued by wiremock is not trusted and the call fails with `AuthenticationException: The remote certificate is invalid according to the validation procedure`. I assumed that running on port 5001 would use the self signed kestral dev certs installed by default by the dotnet cli and so be trusted but I think not based on the below failing. What is the easiest "out of the box" way to get SSL to work like in the example below? Or is there a way to get wiremock to use a self siged cert I already trust or to get the current certificate out of the server so I can validate it easily in the client? ```csharp class Program { static async Task Main(string[] args) { var server1 = FluentMockServer.Start(port:5001, ssl: true); server1.Given(Request.Create().UsingGet().WithPath("/example")) .RespondWith(Response.Create() .WithStatusCode(200) .WithBodyAsJson( new { Message = "Hello world" })); var client = new HttpClient() { BaseAddress = new Uri(server1.Urls.Single()) }; var json = await client.GetAsync("example"); Console.WriteLine(json); Console.WriteLine(await json.Content.ReadAsStringAsync()); Console.ReadLine(); } } ```
adam added the bug label 2025-12-29 14:25:46 +01:00
adam closed this issue 2025-12-29 14:25:46 +01:00
Author
Owner

@StefH commented on GitHub (Nov 27, 2019):

Do you only have this issue in .net core 3?

@StefH commented on GitHub (Nov 27, 2019): Do you only have this issue in .net core 3?
Author
Owner

@alastairtree commented on GitHub (Nov 27, 2019):

No it appears in core 2.1/2.2 also.

I think it because you are passing in a hardcoded cert PublicCertificateHelper.GetX509Certificate2() in AspNetCoreSelfHost to kestrel. If you leave the certificate blank and run on 5001 then kestral should load with the default development certificate if you have already installed it (installed with dotnet dev-certs https --trust). That way it would work with trusted SSL out of the box if you run it under core with the cli.

Alternatively you could make the certificate public so that you can choose to trust it like this:

        var _clientHandler = new HttpClientHandler();
        var trustedWiremockCert = PublicCertificateHelper.GetX509Certificate2();
        _clientHandler.ClientCertificates.Add(trustedWiremockCert);
        _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
        var client = new HttpClient(_clientHandler)

All of the above is untested but might work in theory

@alastairtree commented on GitHub (Nov 27, 2019): No it appears in core 2.1/2.2 also. I think it because you are passing in a hardcoded cert `PublicCertificateHelper.GetX509Certificate2()` in `AspNetCoreSelfHost` to kestrel. If you leave the certificate blank and run on 5001 then kestral should load with the default development certificate if you have already installed it (installed with `dotnet dev-certs https --trust`). That way it would work with trusted SSL out of the box if you run it under core with the cli. Alternatively you could make the certificate public so that you can choose to trust it like this: var _clientHandler = new HttpClientHandler(); var trustedWiremockCert = PublicCertificateHelper.GetX509Certificate2(); _clientHandler.ClientCertificates.Add(trustedWiremockCert); _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; var client = new HttpClient(_clientHandler) All of the above is untested but might work in theory
Author
Owner

@StefH commented on GitHub (Nov 28, 2019):

I see your point.

Currently I'm using a self-signed certificate in WireMock when using netstandard or net core.

But, I can't remember why I created an own self-signed, and not just use the default development certificate like https://www.hanselman.com/blog/DevelopingLocallyWithASPNETCoreUnderHTTPSSSLAndSelfSignedCerts.aspx.

So I think I need to update the current code to make it an option:

  1. Use the current internal self-signed
  2. Use the default development certificate
  3. Let the developer/user from WireMock provide his own certificate.

What do you think?

@StefH commented on GitHub (Nov 28, 2019): I see your point. Currently I'm using a self-signed certificate in WireMock when using netstandard or net core. But, I can't remember why I created an own self-signed, and not just use the default development certificate like https://www.hanselman.com/blog/DevelopingLocallyWithASPNETCoreUnderHTTPSSSLAndSelfSignedCerts.aspx. So I think I need to update the current code to make it an option: 1. Use the current internal self-signed 2. Use the default development certificate 3. Let the developer/user from WireMock provide his own certificate. What do you think?
Author
Owner

@alastairtree commented on GitHub (Nov 28, 2019):

My preference would be to follow the same defaults as kestrel, as that is what developers are most likely to be familiar with. This means the default should be to leave the cert blank and pick up the dev cert, and to host on 5001 by default if SSL is enabled and no port is specified. That way most users will find SSL just works and follows the idioms of regular aspnet development. Then I suggest we also allow the user to pass an Action<KestrelServerOptions> options param on the settings/server setup somewhere and apply this action/callback when calling into kestral. This will allow the user to directly configure Kestral themselves. That way they have full scope to pass filename/password or custom certificate or any other setup if they need to. something like this:

wireMockSettings.ConfigureKestrel(serverOptions =>
{
 //do some custom config here. 
}

We then hold the Action<KestrelServerOptions> value in a property somewhere and apply it at the right time during kestrel setup.

The options aspnet core/Kestrel allows are detailed at
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0#configurehttpsdefaultsactionhttpsconnectionadapteroptions

If you then make PublicCertificateHelper.GetX509Certificate2() public, (and perhaps mark obsolete?) it would be easy for a user to pass something like this to maintain the existing behaviour if they really need to:

wireMockSettings.ConfigureKestrel(serverOptions =>
{
    serverOptions.ConfigureHttpsDefaults(listenOptions =>
    {
        listenOptions.ServerCertificate = PublicCertificateHelper.GetX509Certificate2();
    });
});

Although this seems like a breaking change, at the moment I can't see any way a way for wiremock users on dotnet core to use HTTPS without disabling all certificate validation anyway, so those users would not be affected.

@alastairtree commented on GitHub (Nov 28, 2019): My preference would be to follow the same defaults as kestrel, as that is what developers are most likely to be familiar with. This means the default should be to leave the cert blank and pick up the dev cert, and to host on 5001 by default if SSL is enabled and no port is specified. That way most users will find SSL just works and follows the idioms of regular aspnet development. Then I suggest we also allow the user to pass an `Action<KestrelServerOptions> options` param on the settings/server setup somewhere and apply this action/callback when calling into kestral. This will allow the user to directly configure Kestral themselves. That way they have full scope to pass filename/password or custom certificate or any other setup if they need to. something like this: ``` c# wireMockSettings.ConfigureKestrel(serverOptions => { //do some custom config here. } ``` We then hold the `Action<KestrelServerOptions>` value in a property somewhere and apply it at the right time during kestrel setup. The options aspnet core/Kestrel allows are detailed at https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0#configurehttpsdefaultsactionhttpsconnectionadapteroptions If you then make `PublicCertificateHelper.GetX509Certificate2()` public, (and perhaps mark obsolete?) it would be easy for a user to pass something like this to maintain the existing behaviour if they really need to: ``` c# wireMockSettings.ConfigureKestrel(serverOptions => { serverOptions.ConfigureHttpsDefaults(listenOptions => { listenOptions.ServerCertificate = PublicCertificateHelper.GetX509Certificate2(); }); }); ``` Although this seems like a breaking change, at the moment I can't see any way a way for wiremock users on dotnet core to use HTTPS without disabling all certificate validation anyway, so those users would not be affected.
Author
Owner

@StefH commented on GitHub (Nov 29, 2019):

I'll follow default development certificate for .NET Core 2.x for now.

Preview version from MyGet is WireMock.Net.1.0.37-ci-12243 and I'll create a new NuGet this weekend.

@StefH commented on GitHub (Nov 29, 2019): I'll follow default development certificate for .NET Core 2.x for now. Preview version from MyGet is `WireMock.Net.1.0.37-ci-12243` and I'll create a new NuGet this weekend.
Author
Owner

@StefH commented on GitHub (Dec 26, 2019):

@alastairtree Did this work for you?

@StefH commented on GitHub (Dec 26, 2019): @alastairtree Did this work for you?
Author
Owner

@alastairtree commented on GitHub (Dec 26, 2019):

Yes it did, Thanks!

@alastairtree commented on GitHub (Dec 26, 2019): Yes it did, Thanks!
Author
Owner

@StefH commented on GitHub (Mar 12, 2020):

Closing issue

@StefH commented on GitHub (Mar 12, 2020): Closing issue
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#226