如何解决由于HTTP 302,无法使用Python检索NTLM认证的网页
|| 谁能帮我下面提供的python代码?我已对其进行了一些稍微的修改,以供自己使用。我试图从运行NTLM身份验证的Windows服务器访问网页。起初,我的问题是保持持久连接,这样我就不会出现http 401错误。现在,我已经克服了这一点,但是发生的是我收到了HTTP 302重定向错误以及在响应的set-cookie中发送回的cookie。因此,我添加了一个cookie处理程序,但是没有做任何事情。另外,从服务器返回的“位置”字段包含我最初提交的原始URL。我不明白这一点。为什么从服务器发送回进行重定向的位置字段具有与我提交的完全相同的URL?import urllib2
import httplib,socket
import cookielib
import ntlm
from ntlm import ntlm
class AbstractNtlmAuthHandler:
httplib.HTTPConnection.debuglevel = 1
url1 = \"\"
def __init__(self,password_mgr=None):
if password_mgr is None:
password_mgr = HTTPPasswordMgr()
self.passwd = password_mgr
self.add_password = self.passwd.add_password
def http_error_authentication_required(self,auth_header_field,req,fp,headers):
auth_header_value = headers.get(auth_header_field,None)
if auth_header_field:
if \'ntlm\' in auth_header_value.lower():
if auth_header_value is not None and \'ntlm\' in auth_header_value.lower():
fp.close()
return self.retry_using_http_NTLM_auth(req,None,headers)
def retry_using_http_NTLM_auth(self,realm,headers):
print req.get_full_url()
print \"\\n\\n\"
#user,pw = self.passwd.find_user_password(realm,req.get_full_url())
user,url1)
if pw is not None:
# ntlm secures a socket,so we must use the same socket for the complete handshake
headers = dict(req.headers)
headers.update(req.unredirected_hdrs)
auth = \'NTLM %s\' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user)
if req.headers.get(self.auth_header,None) == auth:
return None
headers[self.auth_header] = auth
host = req.get_host()
if not host:
raise URLError(\'no host given\')
h = None
if req.get_full_url().startswith(\'https://\'):
h = httplib.HTTPSConnection(host) # will parse host:port
else:
h = httplib.HTTPConnection(host) # will parse host:port
# we must keep the connection because NTLM authenticates the connection,not single requests
headers[\"Connection\"] = \"Keep-Alive\"
headers = dict((name.title(),val) for name,val in headers.items())
h.request(req.get_method(),req.get_selector(),req.data,headers)
r = h.getresponse()
r.begin()
r._safe_read(int(r.getheader(\'content-length\')))
if r.getheader(\'set-cookie\'):
# this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out)
headers[\'Cookie\'] = r.getheader(\'set-cookie\')
r.fp = None # remove the reference to the socket,so that it can not be closed by the response object (we want to keep the socket open)
auth_header_value = r.getheader(auth_header_field,None)
(ServerChallenge,NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE (auth_header_value[5:])
user_parts = user.split(\'\\\\\',1)
DomainName = user_parts[0].upper()
UserName = user_parts[1]
auth = \'NTLM %s\' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge,UserName,DomainName,pw,NegotiateFlags)
headers[self.auth_header] = auth
headers[\"Connection\"] = \"Close\"
headers = dict((name.title(),val in headers.items())
try:
h.request(req.get_method(),headers)
# none of the configured handlers are triggered,for example redirect-responses are not handled!
return h.getresponse()
except socket.error,err:
raise URLError(err)
else:
return None
class HTTPNtlmAuthHandler(AbstractNtlmAuthHandler,urllib2.BaseHandler):
auth_header = \'Authorization\'
def http_error_401(self,code,msg,headers):
return self.http_error_authentication_required(\'www-authenticate\',headers)
class ProxyNtlmAuthHandler(AbstractNtlmAuthHandler,urllib2.BaseHandler):
auth_header = \'Proxy-authorization\'
def http_error_407(self,headers):
return self.http_error_authentication_required(\'proxy-authenticate\',headers)
if __name__ == \"__main__\":
url = \'HTTP WEB ADDRESS HERE\'
url1 = url
user = \'USERNAME\'
password = \'PASSWORD\'
user_agent = \'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)\'
data = \"\"
headers = { \'User-Agent\' : user_agent }
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,user,password)
cookie_jar = cookielib.CookieJar()
cookie_handler = urllib2.HTTPCookieProcessor(cookie_jar)
redirect = urllib2.HTTPRedirectHandler()
auth_basic = urllib2.HTTPBasicAuthHandler(passman)
auth_digest = urllib2.HTTPDigestAuthHandler(passman)
auth_NTLM = HTTPNtlmAuthHandler(passman)
opener = urllib2.build_opener(cookie_handler,auth_NTLM,auth_basic,auth_digest,redirect)
urllib2.install_opener(opener)
req = urllib2.Request(url,data,headers)
response = urllib2.urlopen(req)
解决方法
从服务器获得响应后,请检查其是否为302状态。如果状态为302,请获取cookie并使用cookie信息进行另一个请求
if(response.code==302):
header={\'Cookie\':response.headers[\'Set-Cookie\']}
req=urllib2.Request(thesameurl,None,header)
response=urllib2.urlopen(req)
response.read()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。