Python和urllib2的Windows身份验证

13 投票
2 回答
23744 浏览
提问于 2025-04-15 11:49

我想从一个网页上获取一些数据,但这个网页需要我输入Windows的用户名和密码。

到目前为止,我已经得到了:

opener = build_opener()
try:
    page = opener.open("http://somepagewhichneedsmywindowsusernameandpassword/")
    print page
except URLError:
    print "Oh noes."

请问urllib2支持这个吗?我找到了一些关于Python NTLM的资料,但那需要我输入用户名和密码。有没有办法直接获取认证信息呢?比如像IE或Firefox那样,如果我更改了network.automatic-ntlm-auth.trusted-uris的设置。

在msander的回答后编辑

现在我得到了这个:

# Send a simple "message" over a socket - send the number of bytes first,
# then the string.  Ditto for receive.
def _send_msg(s, m):
    s.send(struct.pack("i", len(m)))
    s.send(m)

def _get_msg(s):
    size_data = s.recv(struct.calcsize("i"))
    if not size_data:
        return None
    cb = struct.unpack("i", size_data)[0]
    return s.recv(cb)

def sspi_client():
    c = httplib.HTTPConnection("myserver")
    c.connect()
    # Do the auth dance.
    ca = sspi.ClientAuth("NTLM", win32api.GetUserName())
    data = None
    while 1:
        err, out_buf = ca.authorize(data) # error 400 triggered by this line
        _send_msg(c.sock, out_buf[0].Buffer)

        if err==0:
            break

        data = _get_msg(c.sock)

    print "Auth dance complete - sending a few encryted messages"
    # Assume out data is sensitive - encrypt the message.
    for data in "Hello from the client".split():
        blob, key = ca.encrypt(data)
        _send_msg(c.sock, blob)
        _send_msg(c.sock, key)
    c.sock.close()
    print "Client completed."

这个代码基本上是从socket_server.py中复制过来的(可以在这里查看)。但是我遇到了400错误 - 请求错误。有没有人有其他的想法?

谢谢,

Dom

2 个回答

-2

网站可以使用几种不同的身份验证方式。

  1. HTTP身份验证。这种方式是浏览器会弹出一个窗口,让你输入用户名和密码。主要有两种机制:基本认证和摘要认证。每次请求页面时,都会有一个“授权”头部信息,告诉浏览器(或者使用urllib2的程序)该怎么做。

    在这种情况下,你需要配置你的urlopener,提供授权头部所需的信息。你需要构建一个 HTTPBasicAuthHandler 或者 HTTPDigestAuthHandler

    这些AuthHandlers需要一个 密码管理器。这个密码管理器可以是硬编码的用户名和密码(这种情况很常见),也可以通过某些Windows API聪明地获取你的Windows密码。

  2. 应用程序身份验证。这种方式是网页应用会引导你到一个页面,那里有一个表单,你需要填写用户名和密码。在这种情况下,你的Python程序必须使用urllib2进行POST请求(也就是 带数据的请求),数据就是你填写好的表单。通常,POST请求的回复会包含一个cookie,这个cookie让你可以继续访问。你不需要太担心这个cookie,urllib2会自动处理。

你怎么知道你用的是哪种方式呢?你可以查看响应的头部信息。通过urllib2.openurl得到的响应中包含所有的头部信息(在 page.info() 中)以及页面内容。

可以阅读 Python中的HTTP身份验证

如何通过Python脚本使用urllib、urllib2和ClientCookie登录phpBB3论坛?

如何从非网页的Python客户端访问经过身份验证的Google App Engine服务?

16

假设你是在Windows上写客户端代码,并且需要无缝的NTLM认证,那么你应该看看Mark Hammond在python-win32邮件列表上发的关于NTLM的文章,这篇文章基本上回答了同样的问题。文中提到的sspi示例代码是Python Win32扩展中包含的(这些扩展和ActivePython一起提供,或者你也可以在这里下载)。

撰写回答