基本身份验证

问题描述:

我想找到我怎么能使用的urllib2在Python中获得问题KEY The JIRA REST API描述URI的可用基本身份验证

感谢sugestions使用基本身份验证,我会试试吧,同时,我只是想用我自己的努力来更新这样的:这是样品Python代码我想:

import urllib2, sys, re, base64 
from urlparse import urlparse 
theurl = 'http://my.rest-server.com:8080/rest/api/latest/AA-120'   # if you want to run this example you'll need to supply a protected page with y 
our username and password 
username = 'username' 
password = 'password'   # a very bad password 

req = urllib2.Request(theurl) 
print req 
try: 
    handle = urllib2.urlopen(req) 
    print handle 
except IOError, e:     # here we are assuming we fail 
    pass 
else:        # If we don't fail then the page isn't protected 
    print "This page isn't protected by authentication." 
    sys.exit(1) 
if not hasattr(e, 'code') or e.code != 401:     # we got an error - but not a 401 error 
    print "This page isn't protected by authentication." 
    print 'But we failed for another reason.' 
    sys.exit(1) 

authline = e.headers.get('www-authenticate', '')    # this gets the www-authenticat line from the headers - which has the authentication 
scheme and realm in it 
if not authline: 
    print 'A 401 error without an authentication response header - very weird.' 
    sys.exit(1) 
authobj = re.compile(r'''(?:\s*www-authenticate\s*:)?\s*(\w*)\s+realm=['"](\w+)['"]''', re.IGNORECASE)   # this regular expression is used to 
extract scheme and realm 
matchobj = authobj.match(authline) 
if not matchobj:          # if the authline isn't matched by the regular expression then something is wrong 
    print 'The authentication line is badly formed.' 
    sys.exit(1) 
scheme = matchobj.group(1) 
print scheme 
realm = matchobj.group(2) 
print realm 
if scheme.lower() != 'basic': 
    print 'This example only works with BASIC authentication.' 
    sys.exit(1) 

base64string = base64.encodestring('%s:%s' % (username, password))[:-1] 
authheader = "Basic %s" % base64string 
req.add_header("Authorization", authheader) 
try: 
    handle = urllib2.urlopen(req) 
except IOError, e:     # here we shouldn't fail if the username/password is right 
    print "It looks like the username or password is wrong." 
    sys.exit(1) 
thepage = handle.read() 
server = urlparse(theurl)[1].lower()   # server names are case insensitive, so we will convert to lower case 
test = server.find(':') 
if test != -1: server = server[:test]   # remove the :port information if present, we're working on the principle that realm names per serve 
r are likely to be unique... 

passdict = {(server, realm) : authheader }  # now if we get another 401 we can test for an entry in passdict before having to ask the user for a 
username/password 

print 'Done successfully - information now stored in passdict.' 
print 'The webpage is stored in thepage.' 

---和我得到的结果是: 此页面不受保护认证。 但我们失败的另一个原因。

而该网页是通过认证

我尝试安装请求保护的,但得到的错误:

sudo easy_install requests 
Searching for requests 
Reading http://pypi.python.org/simple/requests/ 

Reading https://github.com/kennethreitz/requests 
Reading http://python-requests.org 
Best match: requests 0.9.1 
Downloading http://pypi.python.org/packages/source/r/requests/requests-0.9.1.tar.gz#md5=8ed4667edb5d57945b74a9137adbb8bd 
Processing requests-0.9.1.tar.gz 
Running requests-0.9.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-lTQu8K/requests-0.9.1/egg-dist-tmp-M2yQCt 
Traceback (most recent call last): 
    File "/usr/bin/easy_install", line 7, in ? 
    sys.exit(
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1712, in main 
    with_ei_usage(lambda: 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1700, in with_ei_usage 
    return f() 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 1716, in <lambda> 
    distclass=DistributionWithoutHelpCommands, **kw 
    File "/usr/lib64/python2.4/distutils/core.py", line 149, in setup 
    dist.run_commands() 
    File "/usr/lib64/python2.4/distutils/dist.py", line 946, in run_commands 
    self.run_command(cmd) 
    File "/usr/lib64/python2.4/distutils/dist.py", line 966, in run_command 
    cmd_obj.run() 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 211, in run 
    self.easy_install(spec, not self.no_deps) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 446, in easy_install 
    return self.install_item(spec, dist.location, tmpdir, deps) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 476, in install_item 
    dists = self.install_eggs(spec, download, tmpdir) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 655, in install_eggs 
    return self.build_and_install(setup_script, setup_base) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 930, in build_and_install 
    self.run_setup(setup_script, setup_base, args) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/command/easy_install.py", line 919, in run_setup 
    run_setup(setup_script, args) 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 61, in run_setup 
    DirectorySandbox(setup_dir).run(
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 105, in run 
    return func() 
    File "/usr/lib/python2.4/site-packages/setuptools-0.6c12dev_r88846-py2.4.egg/setuptools/sandbox.py", line 64, in <lambda> 
    {'__file__':setup_script, '__name__':'__main__'} 
    File "setup.py", line 6, in ? 
    File "/tmp/easy_install-lTQu8K/requests-0.9.1/requests/__init__.py", line 26 
    from . import utils 
     ^
SyntaxError: invalid syntax 
+0

专门为吉拉我会建议看蟒蛇JIRA API封装包PyPI上:https://pypi.python.org/pypi/jira – ThorSummoner 2016-01-06 23:37:22

有趣的是,我昨天为此工作了JIRA Python CLI。我采用了使用REST API来获取身份验证cookie和定制开罐器的方法。下面的示例显示了如何使用开启器将数据发布到页面以添加组件,但是您可以用针对其他REST调用的正确URL的呼叫替换该 。

""" 
Demonstration of using Python for a RESTful call to JIRA 

Matt Doar 
CustomWare 
""" 

import urllib 
import urllib2 
import cookielib 

jira_serverurl = "http://jira.example.com:8080" 
creds = { "username" : "admin", "password" : "admin" } 
authurl = jira_serverurl + "/rest/auth/latest/session" 

# Get the authentication cookie using the REST API 
cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
req = urllib2.Request(authurl) 
req.add_data('{ "username" : "admin", "password" : "admin" }') 
req.add_header("Content-type", "application/json") 
req.add_header("Accept", "application/json") 
fp = opener.open(req) 
fp.close() 

add_component_url = jira_serverurl + "/secure/project/AddComponent.jspa?pid=10020&name=ABC4" 
print "Using %s" % (add_component_url) 

# Have to add data to make urllib2 send a POST 
values = {} 
data = urllib.urlencode(values) 

# Have to tell JIRA to not use a form token 
headers = {'X-Atlassian-Token': 'no-check'} 

request = urllib2.Request(add_component_url, data, headers=headers) 
fp = opener.open(request) 

print fp.read() 
+0

天哪,我不喜欢这个编辑器的代码宏。给我标记! – mdoar 2012-01-11 17:25:02

+0

嗨马特, 尝试“CNTRL + K”,选择代码部分 – kamal 2012-01-12 17:37:10

+0

马特, 我无法理解pid值和名称部分,在 dd_component_url = jira_serverurl +“/secure/project/AddComponent.jspa?pid= 10020&name = ABC4“ – kamal 2012-01-13 03:13:44

我建议你使用非常优异requests库,它提供了一个很好的抽象,使考虑的urllib2有点更容易使用。

随着requests你可以简单地做:

r = requests.get('https://api.github.com', auth=('user', 'pass')) 

它支持所有的使REST所需的请求方法调用以及(POST,PUT,DELETE,等...)。

你可以找到更多在这里:

http://pypi.python.org/pypi/requests


如果你绝对MUST使用普通的旧的urllib2,这里是它如何工作的一个示例:

import urllib2 

theurl = 'http://www.someserver.com/toplevelurl/somepage.htm' 
username = 'johnny' 
password = 'XXXXXX' 

passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 
passman.add_password(None, theurl, username, password) 
# because we have put None at the start it will always 
# use this username/password combination for urls 
# for which `theurl` is a super-url 

authhandler = urllib2.HTTPBasicAuthHandler(passman) 

opener = urllib2.build_opener(authhandler) 

urllib2.install_opener(opener) 
# All calls to urllib2.urlopen will now use our handler 
# Make sure not to include the protocol in with the URL, or 
# HTTPPasswordMgrWithDefaultRealm will be very confused. 
# You must (of course) use it when fetching the page though. 

pagehandle = urllib2.urlopen(theurl) 
# authentication is now handled automatically for us 

更多可以在这里找到:http://www.voidspace.org.uk/python/articles/authentication.shtml

+0

没有直接回答这个问题,但我正要建议检查出'请求'以及。 @kamal即使你不使用'requests',你也应该检查模块。 – istruble 2012-01-10 22:21:20

+0

Thanks @istruble – kamal 2012-01-10 23:17:45

我在访问Jira REST时遇到了同样的问题。 这里是我工作:

class JiraOpenerWrapper(object): 
    # Class to wrap urllib2 OpenerDirector to add authenication headers. 
    # this is needed fro Jira - see comment below. 
    def __init__(self, opener, user, password): 
    self.opener = opener 
    self.user = user 
    self.password = password 

    def open(self, url, data, timeout): 
    if isinstance(url, str): 
     # if given a url - create a request and add 
     req = urllib2.Request(url, data, { 
         "Authorization": 
         "Basic " + base64.b64encode(
          self.user + ":" + self.password) 
        }) 
    else: 
     req = url 
    return self.opener.open(req, data, timeout) 

    def __getattr__(self, attr): 
    if attr == "open": 
     return self.open 
    return getattr(self.opener, attr) 


def RegisterPasswords(user, password): 
    password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() 
    password_manager.add_password(
    None, 'https://rt.mycorp.site/', user, password) 
    password_manager.add_password(
    None, 'https://jira.mycorp.site/', user, password) 
    auth_handler = urllib2.HTTPBasicAuthHandler(password_manager) 
    opener = urllib2.build_opener(auth_handler) 
    # Jira has a strage behviour - it does not return the proper error 
    # when sending a request without an Authentication header. 
    # This causes Python's urllib2 not to retry with the pass word. 
    # For Jira we would need to add the headers all the time 
    jira_opener = JiraOpenerWrapper(opener, user, password) 
    urllib2.install_opener(jira_opener) 


def GameJira(): 
    url = "https://jira.mycorp.site/rest/api/2/issue/PRJ-123" 

    data = urllib2.urlopen(url, None).read() 
    print "Jira:\n", data 
+0

在这里的所有解决方案中,这是唯一一个为JIRA 6.2工作的人(尽管我没有尝试请求库)。 – Jamie 2014-07-04 14:14:08

我使用requests module有更好的成功。

import requests 

jira_session = requests.session() 

try: 
    jira_session.post('https://server', auth=(user, password), verify=False) 
except: 
    print('Unable to connect or authenticate with JIRA server.') 

url = 'https://server/rest/api/2/search?jql=project="ABCXYZ"&maxResults=100' 
results = jira_session.get(url) 
project_data = results.json()