Flurl: Feature Request: Allow ignoring of untrusted certificates....

Created on 21 Aug 2018  路  6Comments  路  Source: tmenier/Flurl

Hi,

I would like to suppress the exception generated by HttpClient for untrusted certificates. See this StackOverflow post.

My use case is when I am using an internal local host that has a self signed certificate. Currently this generates the following exception stack trace:

Flurl.Http.FlurlHttpException
HResult=0x80131500
Message=Call failed. An error occurred while sending the request. GET https://localhost/abpscripts/getscripts
Source=Flurl.Http
StackTrace:
at Flurl.Http.FlurlRequest.d__23.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Flurl.Http.FlurlRequest.d__19.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Flurl.Http.FlurlRequest.d__19.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Flurl.Http.HttpResponseMessageExtensions.d__3.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapExceptionTResult

Inner Exception 1:
HttpRequestException: An error occurred while sending the request.

Inner Exception 2:
WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

Inner Exception 3:
AuthenticationException: The remote certificate is invalid according to the validation procedure.

How can I configure Flurl so that I can successfully call an end point that is protected by an untrusted certificate?

Most helpful comment

I seem to hit all the obscure cases :)

But point taken, it is a rather esoteric thing.

I was just thinking that the developer who's looking to customize the HttpClientHandler that Flurl, by default, generates an HttpClientHandler as the HttpMessageHandler, so yes CreateMessageHandler is the place to look. I was wondering why you pointed someone at CreateMessageHandler since HttpMessageHandler doesn't have any such features. Had to look through the Flurl source to figure it out, but now that I know, I'll never need to figure it out again, and someone who already knew a bit more about HttpMessageHandler/HttpClientHandler probably wouldn't need the extra help in the first place.

@natiki -- This is what I wound up with. Could tweak to make an "insert customizations here" example, if desired.

public class CustomHttpClientFactory : DefaultHttpClientFactory
{
    public override HttpMessageHandler CreateMessageHandler()
    {
        var httpMessageHandler = base.CreateMessageHandler();

        // By default, Flurl creates HttpClientHandlers as message handlers.
        // Confirm this is what it did, and then attach a custom behavior.
        if (httpMessageHandler is HttpClientHandler httpClientHandler)
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
        }
        else
        {
            _logger.Warn("HttpMessageHandler is type {MessageHandlerType}. Cannot set custom certification validation callback.",
                httpMessageHandler.GetType().Name);
        }

        return httpMessageHandler;
    }

}

This issue here on GitHub was what eventually led me to the solution. If it'd be clearer as a Stack Overflow answer then I guess that can be arranged.

All 6 comments

Flurl uses HttpClient under the hood, so the same Stack Overflow answers apply. The "quick and dirty" (and popular) answer should work as-is. Most of the other answers involve a configuring a handler, which you can plug into Flurl with a custom factory that overrides CreateMessageHandler().

I'm going to close this since it was submitted as a feature request. Generally I prefer to have people post programming questions on Stack Overflow, and feel free to post it there if you need a more in-depth answer, but hopefully this info points you in the right direction.

@tmenier, it took me a bit to make this work. I feel like a little addition to the docs might help. Are they also on GitHub? Taking pull requests?

To be honest, I think it's probably a bit too obscure to add to the docs specifically. This list of different scenarios that can be accommodated with HttpClient by configuring the message handler is huge, and a custom factory is always the hook you need to do it in Flurl.

I always appreciate the offers to add things like this to the docs, but lately I've been steering people toward posting a self-answered Stack Overflow question, which is encouraged, will get much better visibility, and is a better fit since it's solving a very specific programming problem.

How about a samples/examples that show things that "are not to make it into the code". @rellis-of-rhindleton If you have some code to share I would appreciate it.

I seem to hit all the obscure cases :)

But point taken, it is a rather esoteric thing.

I was just thinking that the developer who's looking to customize the HttpClientHandler that Flurl, by default, generates an HttpClientHandler as the HttpMessageHandler, so yes CreateMessageHandler is the place to look. I was wondering why you pointed someone at CreateMessageHandler since HttpMessageHandler doesn't have any such features. Had to look through the Flurl source to figure it out, but now that I know, I'll never need to figure it out again, and someone who already knew a bit more about HttpMessageHandler/HttpClientHandler probably wouldn't need the extra help in the first place.

@natiki -- This is what I wound up with. Could tweak to make an "insert customizations here" example, if desired.

public class CustomHttpClientFactory : DefaultHttpClientFactory
{
    public override HttpMessageHandler CreateMessageHandler()
    {
        var httpMessageHandler = base.CreateMessageHandler();

        // By default, Flurl creates HttpClientHandlers as message handlers.
        // Confirm this is what it did, and then attach a custom behavior.
        if (httpMessageHandler is HttpClientHandler httpClientHandler)
        {
            httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
        }
        else
        {
            _logger.Warn("HttpMessageHandler is type {MessageHandlerType}. Cannot set custom certification validation callback.",
                httpMessageHandler.GetType().Name);
        }

        return httpMessageHandler;
    }

}

This issue here on GitHub was what eventually led me to the solution. If it'd be clearer as a Stack Overflow answer then I guess that can be arranged.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

voroninp picture voroninp  路  5Comments

mattkoch614 picture mattkoch614  路  4Comments

nikoudel picture nikoudel  路  6Comments

tomasr78 picture tomasr78  路  7Comments

cremor picture cremor  路  4Comments