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

sel*_*lf. 7 windows proxy

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

这种方法会奏效吗?如果是这样,我该如何实施?

小智 11

可能有点晚了,但还是想提一下。毫无疑问,在您的脚本中支持 NTLM 会很棒,但这会增加复杂性,而不会带来大的回报。最好使用 NTLMAps、Cntlm 或 Px。

NTLMps 和 Cntlm 是作为中间代理执行 NTLM 身份验证的代理。但是,它们都需要用户/通行证,因为它们主要针对 Linux 用户。我以前在 Windows 上使用过这些工具,但对必须向它们提供凭据并在每次更改密码时更新的相同要求感到恼火。

因此,我为 Windows编写了Px,它是一个类似于上述两个的 HTTP 代理,但使用 SSPI 来管理所需的公司代理身份验证。您需要配置的只是代理服务器和端口。

为了开发您自己的应用程序,代码还应该有助于弄清楚如何在 Python 以及可能可以访问 SSPI 的其他语言中执行此操作。但是您宁愿隔离 NTLM 混乱而不是干预它。

  • 被低估的帖子。 (2认同)

she*_*ter 5

我知道这是一个非常古老的问题,但我看到的所有答案都要求您将 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'))
Run Code Online (Sandbox Code Playgroud)