首页 > 解决方案 > 通过 ComVisible DLL 访问 SSL 加密的 WebResource 失败

问题描述

我使用 C# 创建了一个使用 WebRequest 访问 WebService 的 DLL。这个 DLL 被声明为 ComVisible,所以我可以在 Delphi 中使用它。如果 WebRequest 未加密,则一切正常。但是当我使用 https 作为协议时,我收到以下错误消息:

底层连接已关闭:发送时发生意外错误。
无法从传输连接读取数据:Eine vorhandene Verbindung wurde vom Remotehost geschlossen。

但是当我从 .NET 应用程序中使用它时,相同的 DLL 可以工作。

我创建了一个最小的示例项目来查看错误是否可重现并且我遇到了同样的问题。

这是带有 webrequest 的代码

[Guid("D0AAE68A-D2C0-4015-8DE6-471879267418"), ClassInterface(ClassInterfaceType.AutoDual), ProgId("WebRequestTest")]
[ComVisible(true)]
public class ComClient
{
    public bool Authenticate(string customer)
    {
        var request = WebRequest.Create(@"https://server.azurewebsites.net/api/authenticate?apikey=xxxx&customer=" + customer);
        request.Method = "GET";
        try
        {
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
                {
                    string responseString = streamReader.ReadToEnd();
                    Trace.WriteLine(responseString);
                    return true;
                }
            }
        }
        catch (Exception exc)
        {
            Trace.WriteLine(exc);
            return false;
        }
    }
}

在delphi中,代码也小而简单

procedure TForm1.btnTestClick(Sender: TObject);
var
  client: TComClient;
begin
  client := TComClient.Create(self);
  if client.Authenticate('xxxxxxxx') then
    Application.MessageBox('Ok', '', MB_OK + MB_ICONINFORMATION)
  else
    Application.MessageBox('Error', '', MB_OK + MB_ICONINFORMATION);

  client.Free;
  client := nil;
end;

为了使用纯 .NET 进行测试,我创建了一个小型单元测试,它可以正常工作。

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        ComClient client = new ComClient();
        bool result = client.Authenticate("xxxxxxxx");
        Assert.IsTrue(result);
    }
}

在我看来,当使用 COM 应用程序中的 .NET 程序集时,.NET 框架没有完全初始化。如前所述,如果我切换到 http 而不是 https,则调用工作正常。

标签: c#delphisslwebrequestcomvisible

解决方案


我通过 Tav 的评论找到了解决方案。虽然 ServicePointManager.SecurityProtocol 包含协议 TLS | TLS11 | .NET 应用程序的 TLS12,只有 SSL3 和 TLS 协议被分配为 COM 应用程序。由于 Azure AppServices 默认配置为最低 TLS 版本为 1.2,因此您必须相应地重新配置 AppService 或在 COM 程序集中显式添加 TLS1.2。

ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

推荐阅读