Search code examples
asp.net-core.net-coreoauth-2.0kestrelself-signed-certificate

How do I allow self-signed certificates to be accepted by Kestrel by using native .Net Core OAuth Authorization?


I am currently developing a Web Application that requires to retrieve data from an IDM system which in Dev Environment uses a Self-Signed certificate (I don't know the reason). It uses OAuth as Authorization method, so I am currently using .Net Core 3.1 OAuth libraries which throws a SSL Exception after successful redirection from the IDM. I was given the self-signed certificate (PFX file) from the IDM but I don't know where to add it.

public void ConfigureServices(IServiceCollection services)
{
    //services.Configure<KestrelServerOptions>(pConfiguration.GetSection("Kestrel"));
    services.AddControllers();
    services.AddControllersWithViews();
    services
        .AddAuthentication(authenticationOptions => {
            authenticationOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authenticationOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            authenticationOptions.DefaultChallengeScheme = "the_scheme_challenge";
        })
        .AddCookie()
        .AddOAuth(authenticationScheme: "the_scheme", configureOptions: oauthOptions => {
            oauthOptions.ClientId = pConfiguration["the_scheme:ClientId"];
            oauthOptions.ClientSecret = pConfiguration["the_scheme:ClientSecret"];
            oauthOptions.CallbackPath = new PathString(pConfiguration["the_scheme:CallbackURL"]);
            oauthOptions.AuthorizationEndpoint = "https://the.idm.dev/idm/oauth/authorize";
            oauthOptions.TokenEndpoint = "https://the.idm.dev/idm/oauth/token";
            oauthOptions.UserInformationEndpoint = "https://the.idm.dev/idm/oauth/userinfo";
            oauthOptions.Scope.Add(pConfiguration["the_scheme:Scope"]);
            oauthOptions.SaveTokens = true;
        });
}

Any advice would be accepted, I don't want to write all the HTTP Requests and Logic from scratch with some insecure code (like allowing any certificate to be accepted).

I've tested the code against other OpenID providers and it worked.


Solution

  • I like Gary's answer, installing the certificates seems like the best option.

    But, I believe you can use BackchannelHttpHandler to set your own certificate validation.

    .AddOAuth(authenticationScheme: "the_scheme", configureOptions: oauthOptions => {
        oauthOptions.ClientId = pConfiguration["the_scheme:ClientId"];
        oauthOptions.ClientSecret = pConfiguration["the_scheme:ClientSecret"];
        oauthOptions.CallbackPath = new PathString(pConfiguration["the_scheme:CallbackURL"]);
        oauthOptions.AuthorizationEndpoint = "https://the.idm.dev/idm/oauth/authorize";
        oauthOptions.TokenEndpoint = "https://the.idm.dev/idm/oauth/token";
        oauthOptions.UserInformationEndpoint = "https://the.idm.dev/idm/oauth/userinfo";
        oauthOptions.Scope.Add(pConfiguration["the_scheme:Scope"]);
        oauthOptions.SaveTokens = true;
                        
        //Handle the certificate checks yourself, 
        oauthOptions.BackchannelHttpHandler = new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => {
                if (cert.Thumbprint == Configuration["TrustedCertificateThumbprint"])
                {
                          return true;
                }
                                    
            }
        };
                
    });
    });  
    
    
        
    

    This is similar to other examples you may have already seen, but instead of just returning true, you can add your own checks such as certificate thumbprint or maybe the signing authority.

    If you have control over the ID server you could also get a certificate with a trusted root, from somewhere like letsencrypt