Windows Server2019下IIS部署ASP.NET Core无法通过企业代理访问问题求助
问题现象
环境为Windows Server 2019(版本1809)+ IIS 10.0,部署多套ASP.NET Core应用,当前网络已配置企业代理,但应用始终无法穿透代理访问外网,抛出两类System.Net.Http.HttpRequestException异常:
- 连接超时异常:
System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. - 连接被拒异常(访问部分站点时触发):
System.Net.Http.HttpRequestException: No connection could be made because the target machine actively refused it.
已完成排查项
- 服务器本地直接使用IE、Chrome浏览器访问目标外网链接,可正常加载
- 另一台配置相同IIS规则、相同应用代码、相同代理参数的同环境服务器,应用可正常访问外网
- 已尝试传统IIS进程代理配置方案,未生效
- 对照测试:同服务器部署ASP.NET Framework版本Web应用,未配置代理时同样无法访问外网,在站点目录或Microsoft.NET目录下的web.config中添加代理配置后即可正常访问;但ASP.NET Core应用的代理问题始终无法通过该方式解决
- 两类应用使用的测试代码完全一致,代码如下:
public async Task<IActionResult> Index() { using (var client = new HttpClient()) { try { var message = await client.GetStringAsync("http://webcode.me"); ViewBag.Message = message; } catch (Exception ex) { ViewBag.Message = ex.ToString(); } } return View(); }
问题根因
ASP.NET Core和ASP.NET Framework的代理读取逻辑完全不同:
- ASP.NET Framework会自动读取web.config中
<system.net><defaultProxy>节点的代理配置,同时会加载运行上下文对应用户的IE代理设置,因此在web.config加完配置就能生效。 - ASP.NET Core托管在IIS时,由w3wp进程拉起独立的dotnet子进程运行应用,默认不会读取传统web.config里的system.net节点配置,也不会继承当前登录管理员的用户代理配置;且IIS应用池默认使用ApplicationPoolIdentity虚拟账号运行,该账号上下文下没有加载配置好的企业代理规则,因此应用发起请求时会尝试直连外网,触发超时、连接被拒错误。
- 本地浏览器访问正常,是因为浏览器读取的是当前登录管理员账号下的代理配置,和IIS运行应用的账号上下文不是同一个环境。另一台同配置服务器可正常运行,通常是因为该服务器已经配置过系统级代理环境变量,或应用池使用了带代理配置的自定义服务账号。
修复方案
按优先级从高到低选择即可,不需要修改原有业务代码:
方案1:配置系统级代理环境变量(推荐,一劳永逸)
适合服务器上所有ASP.NET Core/Java/Node.js等非Framework类应用都需要走代理的场景:
- 打开服务器系统属性-高级-环境变量,在系统变量区域新增3个变量:
- 变量名
HTTP_PROXY,变量值为企业代理地址,格式为http://代理IP:端口;如果代理需要身份认证,格式为http://用户名:密码@代理IP:端口 - 变量名
HTTPS_PROXY,变量值和HTTP_PROXY保持一致即可 - (可选)变量名
NO_PROXY,变量值为不需要走代理的内网地址、域名,多个值用英文逗号分隔,例如localhost,127.0.0.1,*.内部域名.com,10.0.0.0/8
- 变量名
- 打开命令提示符执行
iisreset重启IIS,配置即可全局生效。
方案2:单应用配置代理环境变量
适合仅个别ASP.NET Core应用需要走代理的场景:
- 找到目标站点根目录下的
web.config文件,定位到<aspNetCore>配置节点 - 在节点内新增
<environmentVariables>子节点,配置代理参数,示例如下:
<aspNetCore processPath="dotnet" arguments=".\你的应用入口dll名.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"> <environmentVariables> <environmentVariable name="HTTP_PROXY" value="http://代理IP:端口" /> <environmentVariable name="HTTPS_PROXY" value="http://代理IP:端口" /> <environmentVariable name="NO_PROXY" value="localhost,127.0.0.1" /> </environmentVariables> </aspNetCore>
- 保存文件后回收对应应用池,配置即可生效,不会影响服务器上其他站点。
方案3:代码层面指定代理(仅用于临时测试,不推荐生产用)
如果临时测试不想改服务器配置,可以在初始化HttpClient时手动指定代理,示例代码:
var proxyConfig = new WebProxy { Address = new Uri("http://代理IP:端口"), BypassProxyOnLocal = true, // 代理不需要认证的话,注释下面这行 Credentials = new NetworkCredential("代理账号", "代理密码") }; var httpHandler = new HttpClientHandler { UseProxy = true, Proxy = proxyConfig }; using var client = new HttpClient(httpHandler);
注意:生产环境不要每次请求都新建HttpClient实例,建议使用IHttpClientFactory做实例复用,避免出现端口耗尽问题。
内容的提问来源于stack exchange,提问作者Iver Cold
相关产品推荐
相关产品推荐

