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

FYI: if you use Console Runner and start to get exceptions for accessing https recently #1659

Closed
xied75 opened this issue Mar 7, 2018 · 11 comments

Comments

@xied75
Copy link

xied75 commented Mar 7, 2018

Dear all,

Just encountered this, I used to have some tests accessing https fine (two months ago), now it will throw:

---- System.Net.WebException : The request was aborted: Could not create SSL/TLS secure channel.

(In my case the target host is GitHub.com,
https://developer.github.com/changes/2018-02-01-weak-crypto-removal-notice/)

After some googling, I found this to be the most easy solution without touching my code:
https://stackoverflow.com/questions/44751179/tls-1-2-not-negotiated-in-net-4-7-without-explicit-servicepointmanager-security

Lots other people suggest you to modify your code to specify TLSv1.2, but I prefer the solution for running the Console Runner by adding this to the runner config file:

<runtime>
   <AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> 
</runtime>

p.s. Anyone can suggest how to do similar things for VS runner?

@bradwilson
Copy link
Member

In general, I'm usually reluctant to make changes like this (which conditionally change the behavior of the runner), for two reasons: (a) the change is truly conditional, based on whether the framework understands that switch or not; and (b) changing the default behavior of the framework makes it impossible to know whether your code runs correctly against the unmodified framework.

I'd be much more likely to support the idea of just compiling the console runner against several versions of the desktop CLR, and letting people choose at test run time which one they would want.

@bradwilson
Copy link
Member

Subsumed by #1709.

@olsh
Copy link

olsh commented Jul 24, 2018

The TLS issue still exists when dotnet test command is used.
Even if I specify the target framework to net471.

@bradwilson
Copy link
Member

Using dotnet test always runs the .NET 4.5.2 version of the console runner. The only available workaround today is to call xunit.console.exe of your preferred framework, rather than using dotnet test.

@thomazmoura
Copy link

Using dotnet test always runs the .NET 4.5.2 version of the console runner. The only available workaround today is to call xunit.console.exe of your preferred framework, rather than using dotnet test.

@bradwilson Does that mean that even today you can't actually use xunit to run integration tests that access TLS 1.2 resources when running the tests from Visual Studio and dotnet test?

I've been trying to make this work on Visual Studio for a while now, but unfortunately Visual Studio seems to always target 4.5.2 while running xunit tests. The same tests work fine if run with MS Test (switching the Fact to TestMethod and adding the TestClass annotations). I'm using the xunit.runner.visualstudio nuget package, by the way.

Is there no way to force Visual Studio to use a > 4.6 version of the runner or something like?

@bradwilson
Copy link
Member

@bradwilson Does that mean that even today you can't actually use xunit to run integration tests that access TLS 1.2 resources when running the tests from Visual Studio and dotnet test?

For .NET Framework tests, that's still true, yes.

This is something that should get fixed with v3 given the new design (your tests become an executable program rather than a DLL).

@ohadschn
Copy link

ohadschn commented Jun 1, 2020

I'm seeing this too when using the Visual Studio test explorer. It looks like the VS test explorer uses the same logic as dotnet test, namely executes the .NET 4.5.2 runner (I'm actually seeing 4.5.1 in AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName).

If anyone's interested how come this is the behavior even though you have a later framework installed, there is a .NET backwards compatibility mechanism (System.AppContext). Here is the exact culprit: https://referencesource.microsoft.com/#System/sys/AppContextDefaultValues.Defaults.cs,28

For more information: https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

@alexsaare
Copy link

I get the same behaviour with the Visual Studio 2019 test runner. I have a set of integration tests that target multiple frameworks.

I don't mind setting the Security Protocol directly in the test for frameworks older than 4.6 using pre-processor directives as below

#if (NET452)
            // explicitly support TLS 1.2
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
#endif

Setting this for all versions of the .NET Framework allows the test to pass but it isn't a great solution as it's not really testing what the it was designed to test.

A better workaround I found is to use the ReSharper test runner. It works as expected and all tests run correctly for me. Unfortunately, not all my collaborators have ReSharper!

@ohadschn
Copy link

@alexsaare that won't work, NET452 is a compile-time constant, and the xunit runner is chosen at runtime. I suggest this piece of code instead:

if (ServicePointManager.SecurityProtocol != SecurityProtocolType.SystemDefault)
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
}

@alexsaare
Copy link

alexsaare commented Jun 10, 2020

Thanks for your feedback @ohadschn

The enum SecurityProtocolType.SystemDefault does not exist prior to framework 4.7.1 which is one reason why I only want to set it (or not) at compile time.

I expect you already know that Microsoft's recommended solution for 4.5.2 and earlier is simply to upgrade but I'm not in control of my clients. Their workaround involves updating registry keys which really isn't something I want to have to manage either on dev PCs or on the build severs for the sake of integration tests. I'm therefore happy to set this explicitly in code but only for the framework versions that need it - I.E. it shouldn't need setting at all for 4.6+.

Our project is a multi-targeted library (netstandard2.0; netstandard1.6; net45) and as such the test are also multi-targeted to match the potential frameworks which could consume the library (netcoreapp2.0; netcoreapp2.1; netcoreapp2.2; netcoreapp3.0; netcoreapp3.1; netcoreapp1.0; netcoreapp1.1; net452; net46; net472; net48;).

Again, the solution above works exactly the way we need it to when using the ReSharper test runner. The Visual Studio 2019 runner however fails for compilations that target the "old" .NET frameworks - netcore are all fine.

I'm guessing but it may ber that the Visual Studio 2019 test runner either shares an AppDomain for .NET framework versions or, as you indicated above, the tests are executed using the wrong framework version. - ** see edit update below **

You can view the library here if you're interested.

Cheers

**** edit ****

I just tested this and you're right, I output 'AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName' and it is always '.NETFramework,Version=v4.5.1' for "old" .NET framework versions no matter what the compilation target of the dll produced.

When run in ReSharper, the value of 'AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName' is the correct framework for the target compilation.

@ohadschn
Copy link

@alexsaare whatever the reason, VS test explorer indeed executes the 4.5.1 version of the xunit console runner.

If you can't rely on SecurityProtocolType.SystemDefault, I suggest you test AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName instead.

A simple EndsWith check will probably be enough, but if you want to parse it robustly you can take the framework code: https://referencesource.microsoft.com/#System/parent/parent/parent/InternalApis/Clr/inc/AppContextDefaultValues.cs,2a50c664fa895e7b

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

No branches or pull requests

6 participants