我有一台在公司环境中运行 Windows 的工作计算机,它带有一个用于向外连接到互联网的身份验证代理服务器。我不知道它是如何配置的,但许多工具都无法连接,主要是 npm(Atom 编辑器中的包)、NuGet、PowerShellGet 等类型的工具。我甚至不得不配置我的浏览器(Vivaldi)以使用直接连接,因为我无法登录某些网站,即使它在 MS Edge 中可以正常工作。
HTTP 错误通常是(407) Proxy Authentication Required
。
Windows 中的系统范围的代理服务器正在由一些定期执行的脚本进行配置,我对此无能为力。
解决方案(或者说变通方法)是单独配置所有存在连接问题的应用程序以绕过代理(使用直接连接到互联网)。我已经设法为几乎所有需要的东西都做到了这一点,但到目前为止,我还没有在 Powershell Core 上取得成功。
顺便说一句,我不确定代理有什么意义,因为你可以简单地绕过它,它只是让那台计算机上的常规工作变得更加困难,浪费了我的时间和公司的金钱。
到目前为止,我发现了以下情况。
PowerShellGetFind-Module
失败并出现以下错误:
无法解析包源“https://www.powershellgallery.com/api/v2”
一个简单的 Web 请求失败并显示错误“缓存访问被拒绝“:
Invoke-WebRequest https://google.com
但当强制绕过代理时就会成功:
Invoke-WebRequest https://google.com -NoProxy
netsh winhttp show proxy
说“直接访问(无需代理服务器)。“,但以下命令返回实际的代理:
([System.Net.WebRequest]::GetSystemWebproxy()).GetProxy("https://google.com")
此外,以下命令返回false
:
([System.Net.WebRequest]::GetSystemWebproxy()).IsBypassed("https://google.com")
我做了相当广泛的研究,发现可以通过WebRequest
将默认代理设置为空来配置使用直接连接,但这没有帮助:
[System.Net.WebRequest]::DefaultWebProxy = $null
如果有人有其他想法我将不胜感激。
更新
我发现我实际上可以使用我的域帐户在代理服务器上进行身份验证:
Invoke-WebRequest https://google.com -ProxyUseDefaultCredentials -Proxy http://proxy
因此,这将是代理绕过配置的替代方案。我只是不知道如何为 Powershell 发出的所有请求设置凭据。我不明白为什么 Windows 系统代理未配置为使用我的帐户进行身份验证。
我尝试过配置WebRequest::DefaultWebProxy
使用代理服务器并使用我的域帐户凭据对其进行身份验证,但它不起作用:
[System.Net.WebRequest]::DefaultWebProxy
= New-Object System.Net.WebProxy('http://proxy')
[System.Net.WebRequest]::DefaultWebProxy.Credentials
= [System.Net.CredentialCache]::DefaultNetworkCredentials
答案1
最后,经过几个小时的研究和折腾,我终于解决了我的问题,这要归功于此 GitHub 问题评论!
我不知道背景,但看起来 Powershell Core 实际上正在使用System.Net.Http.HttpClient
而不是System.Net.WebRequest
发出网络请求。
当我了解到这一点时,配置起来相当容易HttpClient
的默认代理。
1. 手动配置HttpClient.DefaultProxy
代理绕过
要绕过代理(使用直接连接),请将其设置为null
:
[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy($null)
我已经将它添加到我的Powershell 配置文件并且 Powershell 建立的所有连接开始工作。
配置特定代理服务器
要配置实际的代理服务器,请使用以下命令:
[System.Net.Http.HttpClient]::DefaultProxy = New-Object System.Net.WebProxy('http://proxy', $true)
配置代理身份验证
如果它是身份验证代理,则必须配置用于代理身份验证的凭据。以下命令将使用您当前登录 Windows 的域帐户的凭据:
[System.Net.Http.HttpClient]::DefaultProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
2. 使用环境变量配置默认代理
另一种解决方案是使用环境变量。根据文档,HttpClient
实际上是使用以下变量来初始化默认代理(如果已定义):
HTTP_PROXY
对于 HTTP 请求HTTPS_PROXY
对于 HTTPS 请求ALL_PROXY
适用于 HTTP 和 HTTPSNO_PROXY
可能包含从代理中排除的主机名的逗号分隔列表
用法示例:
ALL_PROXY='http://proxy:1234'
如果您需要传递凭证:
ALL_PROXY='http://username:password@proxy:1234'
该解决方案得到了更广泛的应用程序的支持,因此它是否比以前的解决方案更好或更差取决于您到底想配置什么,仅仅是 Powershell 还是其他应用程序。
答案2
根据 David Ferenczy Rogožan 的出色回答和研究,我能够让它发挥作用,但就我而言,我必须这样做(请注意与上面的细微差别):
[System.Net.HttpWebRequest]::DefaultWebProxy = New-Object System.Net.WebProxy($null)
答案3
至于这个……
it should be possible to configure WebRequest to use the direct connection by setting the default proxy to null
,正如您所发现的,它不在您的公司基础设施中。
您拥有的是一个强制到您的工作站的 GPO,它强制所有互联网出口网络流量通过过滤/代理网关。
有关详细信息,请参阅如何通过组策略强制执行代理设置 - TechNet 文章 - 美国(英语) - TechNet Wiki(microsoft.com)。 https://social.technet.microsoft.com/wiki/contents/articles/5156.how-to-force-proxy-settings-via-group-policy.aspx
您的雇主正在控制和监控所有加入域的系统的所有入口/出口网络流量。
风险管理/安全政策将起主导作用。任何现代过滤网关都有特定的控制措施,您的组织/企业会出于其既定的风险控制原因使用这些措施。
因此,这不是 PowerShell 功能或代码问题;这是网络限制。所以,无法绕过它。无论您使用什么工具。您必须提供身份/凭据才能允许出站。
您可以查看浏览器设置以查看代理线人,或者他们也可能使用 PAC 文件。
请参阅:什么是 PAC 文件?(websense.com)了解详情。 https://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_explained.aspx
您在正常浏览时没有收到此提示的原因是使用了您的凭据/网络令牌。如果您尝试绕过该提示,则根据公司政策,您会收到提示。
试图规避雇主的风险管理/安全政策将会产生 RPE/CLM(简历生成事件/职业限制举措),并且可能采取法律行动,具体取决于您正在做的事情。