繁体   English   中英

C# VSTO 插件 - Excel 终止 HTTPS 连接

[英]C# VSTO Add-In - Excel Terminates HTTPS connection

在 C# 中创建了一个 Excel 插件。 加载项只是从指定的 URL 下载数据并填写工作表。 当从 HTTP 或 HTTPS 连接下载数据时,一切正常。 但是,当我尝试从不受信任的 HTTPS 服务器下载数据时,抛出异常并且没有任何反应。 我试图调试代码并且有以下异常。

    private void BtnCreateDataSource_Click(object sender, EventArgs e)
{
    ServicePointManager.ServerCertificateValidationCallback += (messageSender, cert, chain, sslPolicyErrors) => true;

string data_str = @"{
    ""grant_type"": ""password"",
    ""username"": ""xxx"",
    ""password"": ""xxx"",
    ""scope"": ""openid https://xxxx""
}";
    var data = Encoding.ASCII.GetBytes(data_str);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://xxx/oidc/grantToken");
    //HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.google.com");

    request.Method = "POST";
    request.ContentType = "application/json";
    request.ContentLength = data.Length;
    StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);

    using (var stream = request.GetRequestStream())
    {
        stream.Write(data, 0, data.Length);
    }

    var response = (HttpWebResponse)request.GetResponse();

    var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

    MessageBox.Show(responseString);
}

例外:

    ************** Exception Text **************
System.Net.WebException: Nadřízené připojení bylo uzavřeno: Došlo k neočekávané chybě při odeslání. ---> System.IO.IOException: Ověření se nezdařilo, protože vzdálená strana zavřela datový proud přenosu.
   v System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   v System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   v System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   v System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest, Boolean renegotiation)
   v System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   v System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   v System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   v System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   v System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
   v System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   v System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
   v System.Net.ConnectStream.WriteHeaders(Boolean async)
   --- Konec trasování zásobníku pro vnitřní výjimku ---
   v System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
   v System.Net.HttpWebRequest.GetRequestStream()
   v uuTS.FormCreateDataSource.BtnCreateDataSource_Click(Object sender, EventArgs e) v C:\Dropbox\projekty\uuTS\uuTS\FormCreateDataSource.cs:řádek 202
   v System.Windows.Forms.Control.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnClick(EventArgs e)
   v System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   v System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   v System.Windows.Forms.Control.WndProc(Message& m)
   v System.Windows.Forms.ButtonBase.WndProc(Message& m)
   v System.Windows.Forms.Button.WndProc(Message& m)
   v System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

它在线崩溃: StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);

可能 Excel 在识别到连接不受信任(证书颁发机构不受信任)时终止连接。 我该如何克服这个问题? 我不想安装分配给该不受信任的 HTTPS 服务器的证书。 我也尝试过使用 HttpClient 的方法。 这没用。 当我使用“https://www.google.com”而不是我不受信任的 HTTPS 服务器时,它会通过线路并打开连接。

使用 HttpClient 的方法:

    public bool LoadToken()
{
string data_str = @"{
    ""grant_type"": ""password"",
    ""username"": """ + this.Login + @""",
    ""password"": """ + this.Password + @""",
    ""scope"": ""openid " + this.ApiUrl + @"""
}";
    ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

    var handler = new HttpClientHandler();
    handler.ClientCertificateOptions = ClientCertificateOption.Manual;
    handler.ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => { return true; };

    using (HttpClient client = new HttpClient(handler))
    {
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
        

        {
            client.BaseAddress = new Uri(this.OidcUrl);
            HttpResponseMessage response = client.PostAsync(this.OidcUrl, new StringContent(data_str, Encoding.UTF8, "application/json")).Result;

            if (response.IsSuccessStatusCode)
            {
                // Parse the response body.
                string responseStr = response.Content.ReadAsStringAsync().Result;
                this.Token = JsonConvert.DeserializeObject<TokenJson>(responseStr);
                this.TokenValidUntil = DateTime.Now.AddSeconds(this.Token.expires_in - 30);
                return true;
            }
            else
            {
                Log.Error("Error " + ((int)response.StatusCode).ToString() + " (" + response.ReasonPhrase + ")");
                return false;
            }

        }
    }
}

尝试改用以下代码:

ServicePointManager.ServerCertificateValidationCallback = new        
RemoteCertificateValidationCallback
(
   delegate { return true; }
);

暂无
暂无

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

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