Currently the behavior of the property ServerCertificateCustomValidationCallback of the class HttpClientHandler is not obvious and lacks proper documentation.
This is a request to document the behavior of the property.
I would expect the documentation to go into details on:
Also I would like to request similar documentation for the WebRequestHandler.ServerCertificateValidationCallback property.
WebRequestHandler is not a class available in .NET Core. It is only available in .NET Framework.
In general, the behavior is this:
.NET Framework.
ServicePointManager.ServerCertificateValidationCallback will be used for HttpWebRequest always.
HttpClientHandler.ServerCertificateCustomValidationCallback will be used if non-null, Otherwise, ServicePointManager.ServerCertificateValidationCallback will be used.
WebRequestHandler.ServerCertificateValidationCallback will be used if non-null, Otherwise, ServicePointManager.ServerCertificateValidationCallback will be used.
.NET Core
ServicePointManager.ServerCertificateValidationCallback is not implemented and isn't used.
HttpClientHandler.ServerCertificateCustomValidationCallback will be used if non-null. Otherwise, there is no callback.
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator is a simple static delegate that always returns true. It is intended to be as follows:
c#
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
Looking at the code and this dotnet/runtime#21672 leads me to believe that DangerousAcceptAnyServerCertificateValidator is a special value that would essentially be the only possible value (other than the null value) for ServerCertificateCustomValidationCallback in the future for non-Windows OS. As far as I understand the code and based on some tests on OSX, it looks like for any value other than DangerousAcceptAnyServerCertificateValidator, it would fail on non-Windows operating systems that use the OS networking stack or use the latest OpenSSL.
Is that the case?
CC @stephentoub
DangerousAcceptAnyServerCertificateValidator is a special value that would essentially be the only possible value (other than the null value) for ServerCertificateCustomValidationCallback in the future for non-Windows OS
No. That's currently the case on Unixes using a non-OpenSSL-based libcurl. But it works fine with any delegate on Linux with libcurl built against OpenSSL. And it works fine on macOS and Linux with the new ManagedHandler implementation, which doesn't depend on libcurl.
Is the managed handler used when the network stack does not support the custom validation?
Are you asking for this information to be added to ServerCertificateCustomValidationCallback's API reference? In that case, I think this issue should be moved to dotnet/docs, since that's where the documentation is maintained.
Is the managed handler used when the network stack does not support the custom validation?
Not currently. One of the missing features in ManagedHandler right now is support for various auth protocols (e.g. Negotiate), and we don't know at the time of making the request whether we're going to get back a request for one of those. And once we have such features implemented, hopefully we'd just make ManagedHandler the default anyway. In theory we could special case things like "if you're on a platform where ServerCertificateCustomValidationCallback would fail and if you're making a request to an https URL, then fallback to ManagedHandler, since it wouldn't succeed anyway". That's an interesting idea to pursue if we don't get far enough with ManagedHandler in 2.1 to just make it the default. cc: @geoffkizer
Is there some way to force the managed handler to be used?
I think you should make the whole thing more transparent and expose the individual handlers as API so the developer can make the trade-off. I would expect in some cases it would be required to use the OS stack (e.g. FIPS) while in others it might be ok to use the managed one.
Is there some way to force the managed handler to be used?
Right now it's enabled by setting an environment variable or a TLS slot.
I think you should make the whole thing more transparent
It's still in development and hasn't shipped.
In terms of documentation updates, please take a look at docs.microsoft.com and feel free to submit a PR and/or click the "Edit" link on the documentation topic you want changed.
Most helpful comment
WebRequestHandler is not a class available in .NET Core. It is only available in .NET Framework.
In general, the behavior is this:
.NET Framework.
ServicePointManager.ServerCertificateValidationCallback will be used for HttpWebRequest always.
HttpClientHandler.ServerCertificateCustomValidationCallback will be used if non-null, Otherwise, ServicePointManager.ServerCertificateValidationCallback will be used.
WebRequestHandler.ServerCertificateValidationCallback will be used if non-null, Otherwise, ServicePointManager.ServerCertificateValidationCallback will be used.
.NET Core
ServicePointManager.ServerCertificateValidationCallback is not implemented and isn't used.
HttpClientHandler.ServerCertificateCustomValidationCallback will be used if non-null. Otherwise, there is no callback.
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator is a simple static delegate that always returns true. It is intended to be as follows:
c# var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;