我有一个 Python 脚本,该脚本应该从我们的服务器到互联网访问各种 Web API。问题是,就我所见,Python 在支持 NTLM 身份验证方面支持得相当差。这导致我们的公司代理服务器始终返回 HTTP 代码 407。我最初的想法是使用 IIS 和应用程序请求路由模块设置本地代理服务器,它会在处理 NTLM 身份验证的同时将所有请求转发到我们的公司代理。这种方法的问题在于它似乎没有转发我的 NTLM 凭据,而当前用户正在从该凭据运行 Python 脚本。
这种方法有效吗?如果有效,我该如何实现它?
答案1
答案2
可能有点晚了,但还是想提一下。毫无疑问,在脚本中支持 NTLM 会很棒,但这会增加复杂性,而且回报不大。最好使用 NTLMAps、Cntlm 或 Px。
NTLMAps 和 Cntlm 是作为中间代理执行 NTLM 身份验证的代理。但是,它们都需要用户/密码,因为它们主要针对 Linux 用户。我以前在 Windows 上使用这些工具,但每次更改密码时都必须向它们提供凭据并进行更新,这让我很烦恼。
因此,我撰写了适用于 Windows 的 Px它与上述两个类似,都是 HTTP 代理,但使用 SSPI 来管理与企业代理所需的身份验证。您需要配置的只是代理服务器和端口。
对于开发您自己的应用程序,代码还应该有助于弄清楚如何在 Python 和其他可以访问 SSPI 的语言中执行此操作。但您宁愿隔离 NTLM 混乱,而不是干预它。
答案3
我知道这是一个非常老的问题,但我看到的所有答案都要求您将 NTLM 凭据输入某种 python NTLM 代理处理代码中。根据我的经验,这些代理也容易出现错误。我为 Windows 创建了一个解决方案,它将自动检测公司代理系统配置,并使用当前用户的凭据自动执行 NTLM 身份验证。此解决方案使用 pywin32 和 COM 调用。它并不漂亮,但效果很好,所以我想把它传下去,以防它对其他人有帮助。
在示例中,我展示了如何执行 POST,但从此代码中应该很容易弄清楚其他类型的请求:
import win32com.client
try:
import _winreg as winreg
except:
import winreg
class HTTP:
proxy = ""
isProxy = False
def __init__(self):
self.get_proxy()
def get_proxy(self):
oReg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
oKey = winreg.OpenKey(oReg, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
dwValue = winreg.QueryValueEx(oKey, 'ProxyEnable')
if dwValue[0] == 1:
oKey = winreg.OpenKey(oReg, r'Software\Microsoft\Windows\CurrentVersion\Internet Settings')
dwValue = winreg.QueryValueEx(oKey, 'ProxyServer')[0]
self.isProxy = True
self.proxy = dwValue
def url_post(self, url, formData):
httpCOM = win32com.client.Dispatch('Msxml2.ServerXMLHTTP.6.0')
if self.isProxy:
httpCOM.setProxy(2, self.proxy, '<local>')
httpCOM.setOption(2, 13056)
httpCOM.Open('POST', url, False)
httpCOM.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
httpCOM.setRequestHeader('User-Agent', 'whatever you want')
httpCOM.send(formData)
return httpCOM.responseText
http = HTTP()
print(http.url_post('http://ipecho.net/', 'test=1'))