python-使用urllib2从基本身份验证受保护的Jenkins服务器中获取URL
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python-使用urllib2从基本身份验证受保护的Jenkins服务器中获取URL,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4526字,纯文字阅读大概需要7分钟。
内容图文
我正在尝试从Jekins服务器获取URL.直到最近,我仍然能够使用该页面上描述的模式(HOWTO Fetch Internet Resources Using urllib2)创建一个密码管理器,该密码管理器使用用户名&正确地响应了BasicAuth挑战.密码.在jenkins团队changed their security model之前,一切都很好,并且该代码不再起作用.
# DOES NOT WORK!
import urllib2
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
top_level_url = "http://localhost:8080"
password_mgr.add_password(None, top_level_url, 'sal', 'foobar')
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
opener = urllib2.build_opener(handler)
a_url = 'http://localhost:8080/job/foo/4/api/python'
print opener.open(a_url).read()
堆栈跟踪:
Traceback (most recent call last):
File "/home/sal/workspace/jenkinsapi/src/examples/password.py", line 11, in <module>
print opener.open(a_url).read()
File "/usr/lib/python2.7/urllib2.py", line 410, in open
response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 523, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 448, in error
return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 531, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden
[Finished in 0.0s with exit code 1]
问题似乎是Jenkins返回的不是预期的401代码,而是urllib2解释为对话结束的403.它从不实际发送密码.在github上浏览一番之后,发现了另一个可以正常工作的开发人员解决方案…
# WORKS... SORTA
def auth_headers(username, password):
return 'Basic ' + base64.encodestring('%s:%s' % (username, password))[:-1]
auth = auth_headers('sal', 'foobar')
top_level_url = "http://localhost:8080"
a_url = 'http://localhost:8080/job/foo/4/api/python'
req = urllib2.Request(a_url)
req.add_header('Authorization', auth)
print urllib2.urlopen(req).read()
但是,这似乎并不令人满意.不必费心检查域名是否与用户名和密码有关……它只是发送我的登录详细信息!
有人可以建议一种使原始脚本正常工作的方法吗?我想以一种可以登录Jenkins的方式使用urllib2密码管理器.
解决方法:
也请参阅此要点:https://gist.github.com/dnozay/194d816aa6517dc67ca1
Jenkins不返回401-当您需要访问需要身份验证的页面时,请重试HTTP错误代码.而是返回403-禁止.在Wiki https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients中,它显示了使用命令行工具wget时需要使用wget –auth-no-challenge,这正是由于这种行为.
收到403时,尝试使用基本身份验证-禁止:
假设您定义了:
jenkins_url = "https://jenkins.example.com"
username = "johndoe@example.com"
api_token = "my-api-token"
您可以将urllib2.HTTPBasicAuthHandler子类化以处理403 HTTP响应.
import urllib2
class HTTPBasic403AuthHandler(urllib2.HTTPBasicAuthHandler):
# retry with basic auth when facing a 403 forbidden
def http_error_403(self, req, fp, code, msg, headers):
host = req.get_host()
realm = None
return self.retry_http_basic_auth(host, req, realm)
然后是使用该处理程序的问题,例如您可以安装它,使其适用于所有urllib2.urlopen调用:
def install_auth_opener():
'''install the authentication handler.
This handles non-standard behavior where the server responds with
403 forbidden, instead of 401 retry. Which means it does not give you the
chance to provide your credentials.'''
auth_handler = HTTPBasic403AuthHandler()
auth_handler.add_password(
realm=None,
uri=jenkins_url,
user=username,
passwd=api_token)
opener = urllib2.build_opener(auth_handler)
# install it for all urllib2.urlopen calls
urllib2.install_opener(opener)
这是一个简单的测试,看它是否还可以.
if __name__ == "__main__":
# test
install_auth_opener()
page = "%s/me/api/python" % jenkins_url
try:
result = urllib2.urlopen(page)
assert result.code == 200
print "ok"
except urllib2.HTTPError, err:
assert err.code != 401, 'BAD CREDENTIALS!'
raise err
使用抢占式身份验证.
这个答案有一个很好的例子:https://stackoverflow.com/a/8513913/1733117.
当URL匹配时,您将发送Authorization标头,而不是在被禁止使用403时重试.
class PreemptiveBasicAuthHandler(urllib2.HTTPBasicAuthHandler):
'''Preemptive basic auth.
Instead of waiting for a 403 to then retry with the credentials,
send the credentials if the url is handled by the password manager.
Note: please use realm=None when calling add_password.'''
def http_request(self, req):
url = req.get_full_url()
realm = None
# this is very similar to the code from retry_http_basic_auth()
# but returns a request object.
user, pw = self.passwd.find_user_password(realm, url)
if pw:
raw = "%s:%s" % (user, pw)
auth = 'Basic %s' % base64.b64encode(raw).strip()
req.add_unredirected_header(self.auth_header, auth)
return req
https_request = http_request
内容总结
以上是互联网集市为您收集整理的python-使用urllib2从基本身份验证受保护的Jenkins服务器中获取URL全部内容,希望文章能够帮你解决python-使用urllib2从基本身份验证受保护的Jenkins服务器中获取URL所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。