Python和urllib2的Windows身份验证
我想从一个网页上获取一些数据,但这个网页需要我输入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 个回答
网站可以使用几种不同的身份验证方式。
HTTP身份验证。这种方式是浏览器会弹出一个窗口,让你输入用户名和密码。主要有两种机制:基本认证和摘要认证。每次请求页面时,都会有一个“授权”头部信息,告诉浏览器(或者使用urllib2的程序)该怎么做。
在这种情况下,你需要配置你的urlopener,提供授权头部所需的信息。你需要构建一个 HTTPBasicAuthHandler 或者 HTTPDigestAuthHandler。
这些AuthHandlers需要一个 密码管理器。这个密码管理器可以是硬编码的用户名和密码(这种情况很常见),也可以通过某些Windows API聪明地获取你的Windows密码。
应用程序身份验证。这种方式是网页应用会引导你到一个页面,那里有一个表单,你需要填写用户名和密码。在这种情况下,你的Python程序必须使用urllib2进行POST请求(也就是 带数据的请求),数据就是你填写好的表单。通常,POST请求的回复会包含一个cookie,这个cookie让你可以继续访问。你不需要太担心这个cookie,urllib2会自动处理。
你怎么知道你用的是哪种方式呢?你可以查看响应的头部信息。通过urllib2.openurl得到的响应中包含所有的头部信息(在 page.info()
中)以及页面内容。
可以阅读 Python中的HTTP身份验证
假设你是在Windows上写客户端代码,并且需要无缝的NTLM认证,那么你应该看看Mark Hammond在python-win32邮件列表上发的关于NTLM的文章,这篇文章基本上回答了同样的问题。文中提到的sspi示例代码是Python Win32扩展中包含的(这些扩展和ActivePython一起提供,或者你也可以在这里下载)。