https 请求仅在 .net Web 应用程序中失败
Posted
技术标签:
【中文标题】https 请求仅在 .net Web 应用程序中失败【英文标题】:https request fails only in .net web app 【发布时间】:2018-08-04 19:07:03 【问题描述】:我正在尝试修补一个 .net Web 应用程序,该应用程序经过多年的工作后开始无法获得 UPS 运输报价,这极大地影响了 Web 业务。经过反复试验,我发现以下代码在控制台应用程序中运行良好:
static string FindUPSPlease()
string post_data = "<xml data string>";
string uri = "https://onlinetools.ups.com/ups.app/xml/Rate";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
byte[] postBytes = Encoding.ASCII.GetBytes(post_data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// get response and send to console
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
Console.WriteLine(response.StatusCode);
return "done";
这在 Visual Studio 中运行得很好,并且从 UPS 得到了一个很好的小响应,即 XML 格式当然是错误的。
但是,如果我将此函数粘贴到 Web 应用程序中而不更改单个字符,则会在 request.GetRequestStream()
上引发异常:
身份验证失败,因为远程方已关闭传输流。
我在应用程序的几个不同位置进行了尝试,结果相同。
Web 应用程序环境的哪些方面会影响请求?
【问题讨论】:
这有点猜测,但既然你说它在 VS 中有效,但在 web 中无效,这可能是 CORS (developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 问题。较新的浏览器内置了保护措施,以阻止网站不恰当地访问来自其他域的 API 响应。如果您使用的是 Chrome 或 Firefox,您可以获得一个 No-CORS 插件,看看它是否有效? 它在 VS 控制台应用程序中有效,但在运行 Web 应用程序时不能在 VS 中。 (顺便说一句,它在网络上也不起作用)。 我刚刚发现这篇文章解决了几乎相同的问题,除了它涉及 Web 服务请求。但是,我无法评论那里的评论是否解决了问题。是 TLS 问题吗? ***.com/questions/48329844/… 【参考方案1】:原来是 TLS 问题。我猜控制台应用程序默认使用比 Web 应用程序更高的协议,尽管没有指定。因此,您所要做的就是在发出请求之前添加以下代码行:
using System.Net;
...
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
这就是全部,尽管我花了很多钱才到达那里。
以下是 UPS 对此问题的回应:
自 2018 年 1 月 18 日起,UPS 将仅接受 TLS 1.1 和 TLS 1.2 安全协议... 100% 来自使用生产 URL(onlinetools.ups.com/tool 名称)的客户在 TLS 1.0 上的请求将被拒绝。
无论如何,希望这对某人有所帮助。
吉姆
【讨论】:
非常感谢,我花了 2 个小时在 Powershell 上寻找相同问题的解决方案。你拯救了我的一天!【参考方案2】:您可以尝试将凭据设置为您的请求对象,如下所示。
request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
【讨论】:
不幸的是,尝试这样做并没有改变结果。【参考方案3】:尝试设置默认凭据或检查是否设置了任何代理服务器并将其传递,如下例所示。
以WebClient为例。
我在设置默认凭据时遇到问题,因为在服务器上启用了代理。所以我通过代理 URL 和端口以及可以访问它的凭据。
using (System.Net.WebClient web = new System.Net.WebClient())
//IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy;
//defaultWebProxy.Credentials = CredentialCache.DefaultCredentials;
//web.Proxy = defaultWebProxy;
var proxyURI = new Uri(string.Format("0:1", proxyURL, proxyPort));
//Set credentials
System.Net.ICredentials credentials = new System.Net.NetworkCredential(proxyUserId, proxyPassword);
//Set proxy
web.Proxy = new System.Net.WebProxy(proxyURI, true, null, credentials);
web.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var result = web.UploadString(URL, "");
return result;
【讨论】:
我正在使用 Comcast,并且在我的任何设置中都没有有效的代理。这将是需要代理 URL 的唯一问题,对吗? 是的,但请检查您的应用托管服务器是否启用了任何代理。这可以从 Internet Explorer 工具选项中的 LAN 设置中检查。以上是关于https 请求仅在 .net Web 应用程序中失败的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET WebService 仅在使用 Http Get 但 web.config 设置正确时错误地返回 XML 而不是 JSON
仅在特定条件下被 CORS 策略阻止的 Angular 请求
仅在 HTTPS 中执行 ajax POST 请求时,Laravel 403 错误(生产)
仅在 IIS 部署后的 Asp.net Web api 异常:名为“HelpPage_Default”的路由已在路由集合中