将 NTLM 身份验证从本地代理服务器转发到企业代理

将 NTLM 身份验证从本地代理服务器转发到企业代理

我有一个 Python 脚本,该脚本应该从我们的服务器到互联网访问各种 Web API。问题是,就我所见,Python 在支持 NTLM 身份验证方面支持得相当差。这导致我们的公司代理服务器始终返回 HTTP 代码 407。我最初的想法是使用 IIS 和应用程序请求路由模块设置本地代理服务器,它会在处理 NTLM 身份验证的同时将所有请求转发到我们的公司代理。这种方法的问题在于它似乎没有转发我的 NTLM 凭据,而当前用户正在从该凭据运行 Python 脚本。

这种方法有效吗?如果有效,我该如何实现它?

答案1

你看过这些了吗?

NTLM 授权代理服务器

Python NTLM

答案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'))

相关内容