“基础连接已关闭: 发送时发生意外错误。”使用 SSL 证书

问题

我有例外

基础连接已关闭: 发送时发生意外错误。

在我的日志,它打破了我们的 OEM 整合与我们的电子邮件营销系统随机时间

我的网站是托管在一个 Windows Server 2008 R2与 Iis7.5.7600。

这个网站有大量的 OEM 组件,和全面的仪表板。除了我们的一个电子邮件营销组件之外,所有其他元素都可以很好地工作,我们正在使用它作为仪表板内的 iframe 解决方案。

它的工作方式是,我发送一个带有所有凭证的 < a href = “ https://Learn.microsoft.com/en-us/dotnet/api/system.net.httpwebrerequest? view = net-6.0”rel = “ nofollow noReferrer”> HttpWebRequest 对象,然后我得到一个 URL,我把它放到一个 iframe 中,它就可以工作了。

但它只能工作一段时间(1-4小时) ,然后从调用

GetResponse () ;

我有例外

基础连接已关闭: 发送时发生意外错误。

即使系统尝试从 HttpWebRequest获取 URL,也会出现同样的异常。

唯一的办法就是:

  • 回收应用程序池
  • 任何东西都可以在 web.config 中编辑。

我已经想尽一切办法了。

我试过了

明确地加上,

  • keep-alive = false

  • keep-alive = true

  • 增加了暂停时间:

    <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />

我已经上传了这个页面到一个非 SSL 的网站,以检查是否 SSL 证书在我们的生产服务器是使连接下降了一些方式。

任何解决问题的方向都是值得赞赏的。

密码


Public Function CreateHttpRequestJson(ByVal url) As String
Try
Dim result As String = String.Empty
Dim httpWebRequest = DirectCast(WebRequest.Create("https://api.xxxxxxxxxxx.com/api/v3/externalsession.json"), HttpWebRequest)
httpWebRequest.ContentType = "text/json"
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/x-www-form-urlencoded"
httpWebRequest.KeepAlive = False
'ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3


'TODO change the integratorID to the serviceproviders account Id, useremail
Using streamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
Dim json As String = New JavaScriptSerializer().Serialize(New With { _
Key .Email = useremail, _
Key .Chrome = "None", _
Key .Url = url, _
Key .IntegratorID = userIntegratorID, _
Key .ClientID = clientIdGlobal _
})


'TODO move it to the web.config, Following API Key is holonis accounts API Key
SetBasicAuthHeader(httpWebRequest, holonisApiKey, "")
streamWriter.Write(json)
streamWriter.Flush()
streamWriter.Close()


Dim httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamReader = New StreamReader(httpResponse.GetResponseStream())
result = streamReader.ReadToEnd()
result = result.Split(New [Char]() {":"})(2)
result = "https:" & result.Substring(0, result.Length - 2)
End Using
End Using
Me.midFrame.Attributes("src") = result
Catch ex As Exception
objLog.WriteLog("Error:" & ex.Message)
If (ex.Message.ToString().Contains("Invalid Email")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Email Taken")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Access Level")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Unsafe Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Empty Person Name")) Then
'TODO Show message on UI
End If
End Try
End Function
  



Public Sub SetBasicAuthHeader(ByVal request As WebRequest, ByVal userName As [String], ByVal userPassword As [String])
Dim authInfo As String = Convert.ToString(userName) & ":" & Convert.ToString(userPassword)
authInfo = Convert.ToBase64String(Encoding.[Default].GetBytes(authInfo))
request.Headers("Authorization") = "Basic " & authInfo
End Sub
393744 次浏览

在我的情况下,我连接到的网站已经升级到 TLS 1.2。结果我不得不安装。我的网络服务器上的 net 4.5.2,以支持它。

下面的代码解决了这个问题

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3

对我来说是12:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

这些天来,我一直面临着同样的问题,集成也只是“以前工作过”。

完全是因为沮丧,我才这么做的

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

这为我解决了这个问题. . 尽管严格的集成只使用 SSLv3。

自从 Fiddler 报告说有一个“空的 TLS 谈判密码”或类似的东西后,我开始意识到有些东西是不对的。

希望能成功!

我发现这是一个信号,表明您部署代码的服务器有一个旧的。NET 框架安装,不支持 TLS 1.1或 TLS 1.2。解决步骤:

  1. 在生产服务器上安装最新的.NET运行时间(IIS 和 SQL)
  2. 在开发计算机上安装最新的.NET开发包
  3. 将 VisualStudio 项目中的“目标框架”设置更改为最新的.NET 框架。

您可以从这个 URL: http://getdotnet.azurewebsites.net/target-dotnet-platforms.html获得最新的.NET 开发人员包和运行时

如果你被困在。Net 4.0和目标站点正在使用 TLS 1.2,您需要改用以下代码行。 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

来源: TLS 1.2和.NET 支持: 如何避免连接错误

使用 HTTP 调试代理可能导致这种情况,例如 Fiddler。

我从一个本地文件(对 Apple.com 的身份验证)加载了一个 PFX 证书,但它失败了,因为 Fiddler 无法传递这个证书。

尝试禁用 Fiddler 来检查,如果这是解决方案,那么您可能需要在您的计算机上安装证书,或者以某种方式让 Fiddler 可以使用它。

下面的代码解决了我的问题:

request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

转到 web.config/App.config 来验证您使用的是哪个.net 运行时

  <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>

解决办法如下:

  1. NET 4.6及以上版本。您不需要做任何额外的工作来支持 TLS 1.2,它是默认支持的。

  2. .NET 4.5.支持 TLS 1.2,但它不是默认协议。你需要选择使用它。下面的代码将使 TLS 1.2成为默认值,请确保在连接到安全资源之前执行它:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

  1. .NET 4.0.不支持 TLS 1.2,但如果支持。NET 4.5(或更高版本)安装在系统上,然后你仍然可以选择 TLS 1.2,即使你的应用程序框架不支持它。中的 SecurityProtocolType。NET 4.0没有 TLS1.2的条目,所以我们必须使用枚举值的数字表示:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

  1. .NET 3.5或以下。不支持 TLS 1.2(*) ,也没有变通方法。将应用程序升级到框架的最新版本。

我们遇到了这样的问题,一个正在访问我们的 API 的网站得到了“底层连接关闭: 发送时发生了一个意外的错误。”信息。

他们的代码混合了。NET 3.x 和2.2,据我所知,这意味着他们正在使用 TLS 1.0。

下面的答案可以通过启用 TLS 1.0、 SSL 2和 SSL3来帮助您诊断问题,但是需要说明的是,你不想长期这样做,因为所有这三个协议都被认为是不安全的,不应该再使用:

为了让我们的 IIS 响应他们的 API 调用,我们必须在 IIS 的服务器上添加注册表设置来显式启用 TLS 的版本-注意: 在做出这些更改之后,你必须重新启动 Windows 服务器(不仅仅是 IIS 服务) :

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

如果这样还不行,您还可以尝试为 SSL 2.0添加条目:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

明确地说,这不是个好办法和正确的解决方案是让调用者使用 TLS 1.2,但是上面的内容可以帮助诊断这是一个问题。

您可以使用这个 Powershell 脚本加快添加这些 reg 条目的速度:

$ProtocolList       = @("SSL 2.0","SSL 3.0","TLS 1.0", "TLS 1.1", "TLS 1.2")
$ProtocolSubKeyList = @("Client", "Server")
$DisabledByDefault = "DisabledByDefault"
$Enabled = "Enabled"
$registryPath = "HKLM:\\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"


foreach($Protocol in $ProtocolList)
{
Write-Host " In 1st For loop"
foreach($key in $ProtocolSubKeyList)
{
$currentRegPath = $registryPath + $Protocol + "\" + $key
Write-Host " Current Registry Path $currentRegPath"
if(!(Test-Path $currentRegPath))
{
Write-Host "creating the registry"
New-Item -Path $currentRegPath -Force | out-Null
}
Write-Host "Adding protocol"
New-ItemProperty -Path $currentRegPath -Name $DisabledByDefault -Value "0" -PropertyType DWORD -Force | Out-Null
New-ItemProperty -Path $currentRegPath -Name $Enabled -Value "1" -PropertyType DWORD -Force | Out-Null
}
}
 
Exit 0

这是 为 VMM 设置 TLS的 Microsoft 帮助页面中脚本的修改版本。这个 Basics.net 文章是最初给我的想法,看看这些设置页面。

如果有帮助的话,我们的是一个丢失证书的问题。环境是 Windows Server 2016标准与.Net 4.6。

有一个自托管的 WCF 服务 https URI。Open ()将在没有错误的情况下执行。另一个线程将继续访问 https://OurIp:443/OurService?wsdl以确保服务可用。访问用于失败的 WSDL:

基础连接已关闭: 发送时发生意外错误。

使用带有适用设置的 ServicePointManager 安全协议不起作用。玩弄服务器角色和特性也于事无补。然后进入 杰斯・乔治,SE,在几分钟内解决了这个问题。杰斯在 IIS 中安装了一个自签名证书,解决了这个问题。以下是他为解决这一问题所做的努力:

(1)打开 IIS 管理器(inetmgr) (2)点击左面板中的服务器节点,然后双击“服务器证书”。 (3)点击右侧面板上的“创建自签名证书”,然后为友好名称键入任何你想要的内容。 (4)在左面板按「预设网站」、在右面板按「绑定」、按「加入」、选择「 https 」、选择刚创建的证书,然后按「确定」 (5)使用 https 网址,应该是可以访问的。

只要加上:

SecurityProtocol = SecurityProtocolType. Tls12;

您只需将应用程序版本(如4.0)更改为4.6并发布这些代码。

还要添加以下代码行:

httpRequest.ProtocolVersion = HttpVersion.Version10;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

我通过使用下面的代码更新 web.config 找到了解决方案。

我的。Net Framework 设置为4.0,在组织级 TLS 协议更新后,我突然开始面临这个问题。所以我参考了上面的“郭晃”的回答,并更新了目标框架,它工作了。

<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2"  maxRequestLength="102400" executionTimeout="3600"/>
</system.web>

在应用程序域(客户端)和站点(服务器)之间不存在共享 TLS 设置 &/或者不存在共享密码。每个应用程序域(例如 powershell、 cmd、你的应用程序等)都会获取主机的默认客户端设置(或者覆盖它们) ,所以你可以让 cmd shell 工作,但 powershell 失败等等。

您可以使用例如 https://www.ssllabs.com/ssltest/analyze.html?d=api.nuget.org来检查目标 URL

你可以使用例如。

[Net.ServicePointManager]::SecurityProtocol
and
Get-TlsCipherSuite | Format-Table Name

削弱您的 TLS 设置,例如,允许 ssl3,可能会短期工作,但似乎是一个坏主意给我。