也请参阅以下要点:https ://gist.github.com/dnozay/194d816aa6517dc67ca1
401 - retry
当您需要访问需要认证的页面时,Jenkins不会返回HTTP错误代码。相反,它返回403 - forbidden
。在维基,https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients,它表明使用命令行工具wget
,你需要使用wget--auth-no-challenge
它是行为正是因为。
假设您定义了:
jenkins_url = "https://jenkins.example.com"
username = "johndoe@example.com"
api_token = "my-api-token"
您可以将a子类化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
这个答案有一个很好的例子:。当您找到url时,403forbidden
将发送Authorization
标头,而不是重试。
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