简体   繁体   English

通过ComVisible DLL无法访问SSL加密的WebResource

[英]Access to an SSL encrypted WebResource fails via a ComVisible DLL

I used C# to create a DLL that uses a WebRequest to access a WebService. 我使用C#创建了一个使用WebRequest来访问WebService的DLL。 This DLL is declared as ComVisible, so I can use it with Delphi. 该DLL被声明为ComVisible,因此我可以在Delphi中使用它。 If the WebRequest works unencrypted, everything works fine. 如果WebRequest未加密,则一切正常。 But when I use https as protocol, I get the following error message: 但是当我使用https作为协议时,出现以下错误消息:

The underlying connection was closed: An unexpected error occurred on a send. 基础连接已关闭:发送时发生意外错误。
Unable to read data from the transport connection: Eine vorhandene Verbindung wurde vom Remotehost geschlossen. 无法从传输连接中读取数据:Eine vorhandene Verbindung wurde vom Remotehost geschlossen。

But the same DLL works when I use it from a .NET application. 但是,当我从.NET应用程序使用它时,相同的DLL也可以工作。

I created a minimal sample project to see if the error is reproducible and I had the same problem. 我创建了一个最小的示例项目,以查看错误是否可重现并且存在相同的问题。

Here is the code with the webrequest 这是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;
        }
    }
}

In delphi the code is also small and simple 在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;

To test this with pure .NET, I've created a small unit test, which works without error. 为了使用纯.NET进行测试,我创建了一个小型单元测试,该测试可以正确执行。

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

It looks to me like the .NET framework isn't completely initialized when using a .NET assembly from a COM application. 在我看来,当从COM应用程序使用.NET程序集时,.NET框架尚未完全初始化。 As already mentioned, the call works fine if I switch to http instead of https. 如前所述,如果我切换到http而不是https,则通话效果很好。

I found the solution through Tav's comment. 我通过Tav的评论找到了解决方案。 While ServicePointManager.SecurityProtocol contains the protocols TLS | 虽然ServicePointManager.SecurityProtocol包含协议TLS | TLS11 | TLS11 | TLS12 for .NET applications, only the protocols SSL3 and TLS are assigned as COM application. 用于.NET应用程序的TLS12,仅将协议SSL3和TLS分配为COM应用程序。 Since Azure AppServices are configured by default so that the minimum TLS version is 1.2, you must either reconfigure the AppService accordingly or explicitly add TLS1.2 in the COM assembly. 由于默认情况下配置了Azure AppServices,因此最低TLS版本为1.2,因此您必须相应地重新配置AppService或在COM程序集中显式添加TLS1.2。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM