-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Using the latest System.Net.Http 4.1.1 as per #17770 (comment), results in an exception when starting a web app that's .NET 4.6.1:
Inheritance security rules violated by type: 'System.Net.Http.WebRequestHandler'. Derived types must either match the security accessibility of the base type or be less accessible.
I've emailed a repro to @davidsh
Execution plan & status
[UPDATED by karelz]
High-level plan:
A. Revert HttpClientHandler implementation in net46 build of CoreFX back to using original .NET Framework HTTP stack instead of WinHTTP (WinHttpHandler) based stack.
B. Revise implementation of the 8 new APIs on HttpClientHandler we introduced in 4.1.0.0 OOB package so that it works accordingly for the net46 build.
Execution plan:
-
Validate feasibility of [A]
- a. Port HttpClientHandler from NetFX (remove WinHttpHandler build dependency for net46 build).
- b. Add APTCA (on assembly only, no security attributes should be necessary for types or methods - same as in Desktop source code).
- Run the SecAnnotate tool to verify the claim above - Result: Passed
- c. Manually test the 2 scenarios (simplified and @onovotny’s) - Result: Verified
-
Validate feasibility of [B]
- a. Investigate the 2 remaining APIs (DefaultProxyCredentials, MaxConnectionsPerServer) which we do not know if we can implement. - Result: They are in the bucket 4.a below.
-
Full testing of [A] implementation (cost: 1d)
- a. Make changes in master
- b. Test all ~7 end-to-end scenarios reported by community (ask for help from community, provide steps to consume master packages on myget)
- Self hosting ASP.NET Core from Windows Service - validated by @annemartijn0 (here)
- Azure Storage API - validated by @karelkrivanek (here)
- Raven.Database package + usage of new HttpClientHandler - validated by @jahmai (here)
- Direct dependency on System.Net.Http - validated by @pollax (here)
- 4.6 console app depending on System.Net.Http - validated by @MikeGoldsmith (here)
- 4.6 Azure webjob (console app) with ServiceBus - validated by @chadwackerman (here)
- 4.6 Azure Batch app - validated by @chadwackerman (here)
- Not-yet-described scenario by @dluxfordhpf
-
Full implementation and testing of [B]
- a. Decide on design of 4 APIs (CheckCertificateRevocationList, SslProtocols, DefaultProxyCredentials, MaxConnectionsPerServer) which we can’t implement “correctly” - we have 3 choices - either throw PlatformNotSupportedException, or do nothing, or set the properties domain-wide instead of per-HttpClient-instance
- i. Implement the decision (cost: 2d)
- ii. List all libraries on NuGet (e.g. WCF?) which use the APIs we will be technically breaking, contact them
- 4 NuGet libraries potentially affected - owners contacted - see details and tracking progress
- b. Implement 5 APIs which we know how to implement (cost: 3d)
- c. Final testing on master branch package - covered by [3.b]
- a. Decide on design of 4 APIs (CheckCertificateRevocationList, SslProtocols, DefaultProxyCredentials, MaxConnectionsPerServer) which we can’t implement “correctly” - we have 3 choices - either throw PlatformNotSupportedException, or do nothing, or set the properties domain-wide instead of per-HttpClient-instance
-
Ship final packages
- a. Port changes into release/1.1.0 branch
- b. Produce new package - 4.3.1
- c. Test most of ~7 end-to-end scenarios reported by community (ask for help from community, provide steps to consume 4.3.1 stable package from myget feed - see here)
- Self hosting ASP.NET Core from Windows Service - @annemartijn0
- Azure Storage API - @karelkrivanek
- Raven.Database package + usage of new HttpClientHandler - @jahmai
- Direct dependency on System.Net.Http - @pollax (here)
- 4.6 console app depending on System.Net.Http - @MikeGoldsmith
- 4.6 Azure webjob (console app) with ServiceBus
- 4.6 Azure Batch app
- Not-yet-described scenario by @dluxfordhpf
- KeyVault - @Vhab (here)
- SignalR - @tofutim (here)
- OwlMQ - @JoeGordonMVP (here)
- d. Publish package on nuget.org - https://www.nuget.org/packages/System.Net.Http/4.3.1
Impact of the change - Breaking changes
Here's list of technical breaking changes caused by the proposed solution. It includes workarounds for each.
Note that these new behaviors are specific when running on net46 / Desktop. When you run on .NET Core, the behavior is intact.
HttpClientHandler.CheckCertificateRevocationList(introduced in System.Net.Http 4.1)- New behavior: Throws
PlatformNotSupportedException - Workaround: Use
ServicePointManager.CheckCertificateRevocationListinstead (impacts the whole AppDomain, not just singleHttpClientHandleras it did in System.Net.Http 4.1-4.3)
- New behavior: Throws
HttpClientHandler.SslProtocols(introduced in System.Net.Http 4.1)- New behavior: Throws
PlatformNotSupportedException - Workaround: Use
ServicePointManager.SecurityProtocolinstead (impacts the whole AppDomain, not just singleHttpClientHandleras it did in System.Net.Http 4.1-4.3)
- New behavior: Throws
HttpClientHandler.ServerCertificateCustomValidationCallback(introduced in System.Net.Http 4.1)- New behavior: Works fine, except that the first parameter of type
HttpRequestMessageis alwaysnull - Workaround: Use
ServicePointManager.ServerCertificateValidationCallback
- New behavior: Works fine, except that the first parameter of type
- HTTP/2.0 support (introduced in System.Net.Http 4.1)
- New behavior: System.Net.Http (for net46 = Desktop) no longer supports HTTP/2.0 protocol on Windows 10.
- Workaround: Target System.Net.Http.WinHttpHandler NuGet package instead.
- Details:
- HTTP/2.0 support is part of the new CoreFx HTTP stack which on Windows is based on WinHTTP. The original HTTP stack in .NET Framework 4.6 did not support HTTP/2.0 protocol. If HTTP/2.0 protocol is needed, there is a separate NuGet package, System.Net.Http.WinHttpHandler which provides a new HttpClient handler. This handler is similar in features to
HttpClientHandler(the normal default handler for HttpClient) but will support HTTP/2.0 protocol. When using HttpClient on .NET Core runtime, the WinHttpHandler is actually built-in to HttpClientHandler. But on .NET Framework, you need to explicitly use WinHttpHandler. - Regardless of whether you are running using .NET Framework runtime (with WinHttpHandler) or .NET Core runtime using HttpClientHandler (or WinHttpHandler), there are additional requirements in order to get HTTP/2.0 protocol working on Windows:
- The client must be running on Windows 10 Anniversary Build (build 14393 or later).
- The
HttpRequestMessage.Versionmust be explicitly set to 2.0 (the default is normally 1.1). Sample code:
- HTTP/2.0 support is part of the new CoreFx HTTP stack which on Windows is based on WinHTTP. The original HTTP stack in .NET Framework 4.6 did not support HTTP/2.0 protocol. If HTTP/2.0 protocol is needed, there is a separate NuGet package, System.Net.Http.WinHttpHandler which provides a new HttpClient handler. This handler is similar in features to
var handler = new WinHttpHandler();
var client = new HttpClient(handler);
var request = new HttpRequestMessage(HttpMethod.Get, "http://www.example.com");
request.Version = new Version(2, 0);
HttpResponseMessage response = await client.SendAsync(request);