Connecting to MS Graph using TLS1.2 - SecurityProtocol resets from TLS1.2 when server is rebooted

65 Views Asked by At

I have a C# program which is installed on Windows Server 2016, and connects to Exchange Online via MS Graph. However, the program stops working for several hours whenever the server is rebooted. Having set up a Powershell script to investigate the problem (and do the same thing as the C# program), it seems that the error is caused by the Security Protocol resetting when the server is rebooted - under normal circumstances it defaults to TLS1.2, but following a reboot it defaults to "Ssl3, Tls".

MS Graph currently requires the use of TLS 1.2 (Microsoft Graph Service: Retiring TLS 1.0 and 1.1 and preparing for TLS 1.2 in US Gov Cloud).

Microsoft best practices recommend that .NET applications should NOT hard code any particular version of TLS. Instead, .NET applications should use whichever TLS version the client operating system supports – this means that the application will automatically take advantage of newer versions of TLS as they become available (Transport Layer Security (TLS) best practices with the .NET Framework).

So how do I get the server operating system to continue to default to TLS1.2 following server reboots? (If I'm not supposed to hard-code it into the C# program). ...

The C# program gives the following error when it is run after the server is rebooted:

  System.Net.HttpRequestException: An error occurred while sending the request. --> 
  System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. -->
  System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

The following is the relevant section of the Powershell script that does the same thing as the C# program.

function Get-AccessToken
{
    param(
        [string] $AppId,
        [string] $TenantName,
        [string] $AppSecret)

    $Scope = "https://graph.microsoft.com/.default"
    $Url = "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token"

    # Add System.Web for urlencode
    Add-Type -AssemblyName System.Web

    # Create body
    $Body = @{
        client_id = $AppId
        client_secret = $AppSecret
        scope = $Scope
        grant_type = 'client_credentials'
    }

    # Splat the parameters for Invoke-Restmethod for cleaner code
    $PostSplat = @{
        ContentType = 'application/x-www-form-urlencoded'
        Method = 'POST'
        Body = $Body
        Uri = $Url
    }

    # Request the token!
    $Request = Invoke-RestMethod @PostSplat
    return $Request
}

#ClientID = "..<redacted>.."
#DirectoryID = "..<redacted>.."
#ClientSecret = "..<redacted>.."
#MailboxName = "..<redacted>.."
#MailboxFolderName = "Inbox"

[Net.ServicePointManager]::SecurityProtocol

Write-Output "Get-AccessToken"
$Credential = Get-AccessToken -AppId $ClientID - TenantName $DirectoryID -AppSecret $ClientSecret 

Normally, the Powershell script produces the following output:

  Tls12
  Get-AccessToken

For several hours following a server reboot, the Powershell script produces the following output:

  Ssl3, Tls
  Get-AccessToken
  Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
  At C:\Path\TestMSGraphGetEmails.ps1:37 char:16
  +     $Request = Invoke-RestMethod @PostSplat
  +                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
      + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

As per Microsoft best practices (described above), the C# program and the Powershell script do not specify a version of TLS. They're running on Windows Server 2016 (which supports TLS1.2), with version 4.8 of the .NET framework installed (which uses TLS1.2 by default).

So how do I get the server operating system to continue to default to TLS1.2 following server reboots, like it normally does?

0

There are 0 best solutions below