Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
alastairtree opened this issue Nov 27, 2019 · 8 comments
Closed
Labels

Comments

@alastairtree
Copy link
Collaborator

alastairtree commented 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();
        }
    }
@StefH
Copy link
Collaborator

StefH commented Nov 27, 2019

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

@alastairtree
Copy link
Collaborator Author

alastairtree commented 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 alastairtree changed the title Trusting the self signed certificate to enable SSL on core 3.0 Trusting the self signed certificate to enable SSL on dotnet core Nov 27, 2019
@StefH
Copy link
Collaborator

StefH commented 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?

@alastairtree
Copy link
Collaborator Author

alastairtree commented 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.

@StefH
Copy link
Collaborator

StefH commented 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
Copy link
Collaborator

StefH commented Dec 26, 2019

@alastairtree Did this work for you?

@alastairtree
Copy link
Collaborator Author

Yes it did, Thanks!

@StefH StefH added the bug label Mar 12, 2020
@StefH
Copy link
Collaborator

StefH commented Mar 12, 2020

Closing issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants