提问人:PaulH 提问时间:11/6/2023 最后编辑:PaulH 更新时间:11/7/2023 访问量:29
使用 TLS1.2 连接到 MS Graph - 服务器重新启动时,SecurityProtocol 从 TLS1.2 重置
Connecting to MS Graph using TLS1.2 - SecurityProtocol resets from TLS1.2 when server is rebooted
问:
我有一个安装在 Windows Server 2016 上的 C# 程序,并通过 MS Graph 连接到 Exchange Online。但是,每当服务器重新启动时,程序都会停止工作几个小时。设置了一个 Powershell 脚本来调查问题(并执行与 C# 程序相同的操作),该错误似乎是由服务器重新启动时安全协议重置引起的 - 在正常情况下,它默认为 TLS1.2,但在重新启动后它默认为“Ssl3,Tls”。
MS Graph 目前需要使用 TLS 1.2(Microsoft Graph 服务:停用 TLS 1.0 和 1.1,并在 US Gov Cloud 中准备 TLS 1.2)。
Microsoft 最佳做法建议 .NET 应用程序不应对任何特定版本的 TLS 进行硬编码。相反,.NET 应用程序应使用客户端操作系统支持的任何 TLS 版本,这意味着应用程序将在 TLS 的较新版本可用时自动利用它们(.NET Framework 的传输层安全性 (TLS) 最佳做法)。
那么,如何让服务器操作系统在服务器重新启动后继续默认为 TLS1.2?(如果我不应该将其硬编码到 C# 程序中)。 ...
C# 程序在服务器重新启动后运行时出现以下错误:
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.
以下是 Powershell 脚本的相关部分,该脚本执行与 C# 程序相同的操作。
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
通常,Powershell 脚本会生成以下输出:
Tls12
Get-AccessToken
在服务器重新启动后的几个小时内,Powershell 脚本将生成以下输出:
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
根据 Microsoft 最佳做法(如上所述),C# 程序和 Powershell 脚本不指定 TLS 的版本。它们在 Windows Server 2016(支持 TLS1.2)上运行,并安装了 .NET Framework 版本 4.8(默认使用 TLS1.2)。
那么,如何让服务器操作系统在服务器重新启动后继续默认为 TLS1.2,就像它通常所做的那样?
答: 暂无答案
评论