Changing security protocol per request (HttpClient)

17,919

Solution 1

You don't need to set it.

You can use:

using System.Net;
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;

Additional Notes:

  • Needed for .Net 4.5 because Tls12 is not a default protocol.
  • Need to write the above code only once within the application. (For example within Global.asax > Application_Start within Web application or equivalent in Winforms application)
  • For .Net 4.6 and above, Tls12 is a default protocol so it is not needed

Solution 2

There seems to be no way to do this. The SecurityProtocol property is only being used inside the internal TlsStream class in one place:

enter image description here

TlsStream seems to back all the internal TLS connections such as HTTP, FTP and SMTP.

I had hoped that ServicePoint allows you to configure this. For many settings ServicePointManager only provides the default. That hope was unfounded.

So this is quite strong evidence that this is not possible. It's no proof, though.

What should you do? I'd switch out the HTTP client library for the odd server you are talking to. HTTP is not a particularly complicated protocol. I'm sure there's some other implementation available.

Alternatively, use a proxy that terminates the HTTPS connection on your own server. .NET then only deals with HTTP.

Share:
17,919

Related videos on Youtube

Porschiey
Author by

Porschiey

I'm a senior engineering manager leading a dev team at Xbox. Eat, Sleep, Dev.

Updated on June 06, 2022

Comments

  • Porschiey
    Porschiey almost 2 years

    I've got a Web API that must communicate with a few different services. Currently, I have the Web API set to use the following security protocol:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    When the API calls out to another service via HttpClient (say like Twitter), it will use that protocol. At the same time however, another request may come in to access something from the cloud, which for whatever reason, currently requires TLS (not TLS 1.2). The request to the cloud, before firing out, sets the security protocol again:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

    The problem I'm running into is when two separate and unique requests come in, one for Twitter and one for the cloud, the security protocol could switch over to the "wrong one" before it's sent out, causing the request to fail.

    Is there a way to set the security protocol on the HttpClient per request so that I'm not swapping around a setting in some singleton somewhere?

    • Porschiey
      Porschiey almost 9 years
      For anyone coming across this and still stuck, I decided to use AppDomain to isolate the requests to the odd server, enabling the security protocol switch per request. superstarcoders.com/blogs/posts/…
    • Daniel Williams
      Daniel Williams almost 6 years
      Porschiey, your example does not show this using HttpClient, which is not a simple class. Can you give a concrete example using HttpClient, please?
  • Porschiey
    Porschiey over 9 years
    thanks for looking into this. Unfortunately the odd server connection (the cloud) is baked into the SDK, and I don't even have access to the methodology used, let alone know if its HttpClient It'd take a lot of work to re-work all of my other connections to use a different client - and I prefer to use HttpClient... That said, I appreciate this answer, it's very helpful! :)
  • yvoloshin
    yvoloshin over 4 years
    I'm not sure its true that specifying Tls12 is not needed for .Net 4.6 and above. I'm using .Net 4.8, where I'm sending an async request to an API that requires Tls12. If I don't set ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12, the request fails with "Could not create SSL/TLS secure channel". With setting Tls12, it works with no problems.