My ultimate goal is to have a program automatically download a JSON output from a JIRA bug repository, via the JIRA API. I have experience in python but almost none in RESTful API development. Currently trying to follow directions located here: https://developer.atlassian.com/jiradev/jira-apis/jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-cookie-based-authentication, and I cannot seem to get past Step 1, where at first, it seems simple to do:
We need to get a session cookie from JIRA, so the first thing we need to do is create a new session using the session
resource in the JIRA REST API.
Tip: You can also use the session
resource to get information about the currently authenticated user in the current session (GET), or log the current user out of JIRA (DELETE).
To do this, just POST the desired user credentials (as JSON) to the session resource:
Example resource | http://jira.example.com:8090/jira/rest/auth/1/session |
---|---|
Example credentials | { "username": "myuser", "password": "mypassword" } |
This will create a new session and return the requested session information, which will look similar to the following:
{ "session": { "name":"JSESSIONID", "value":"6E3487971234567896704A9EB4AE501F" }, "loginInfo": { "failedLoginCount":1, "loginCount":2, "lastFailedLoginTime":"2013-11-27T09:43:28.839+0000", "previousLoginTime":"2013-12-04T07:54:59.824+0000" } }
More importantly, you will get the session cookie (in the header of the response) from the server, which you can use in subsequent requests. You can see an example of this below. You'll notice that the cookie name and value are the same as the cookie name and value in the session response above.
Set-Cookie: JSESSIONID=6E3487971234567896704A9EB4AE501F; Path=/; HttpOnly
Since use of 'requests' library is recommended everywhere in help forums I've seen attempting to help people who are new to RESTful development because it's the simplest to use, I attempted to create a new session in my python 2.7 program in the following way, using the above tutorial info, plus info from the 'requests' libary tutorial site, http://docs.python-requests.org/en/master/user/quickstart/#make-a-request :
jirainterface.py:
import requests
loginurl = 'https://jira01.devtools.mycompany.com/rest/auth/1/session'
resp = requests.post(loginurl, data={'username': 'myusername','password': 'mypassword'})
print(resp.status_code, resp.reason)
Error Response:
Traceback (most recent call last):
File "jiraIinterface.py", line 21, in <module>
resp = requests.post(loginurl, data={'username': 'myusername','password': 'mypassword'})
File "C:\Python27\lib\site-packages\requests\api.py", line 110, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 596, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
There is nothing wrong with the loginurl, if I type it in to a browser, I get a response very much like the above sample requested session info.
Any help or insight is appreciated.
The error says that the python client does not trust the SSL certificate of the server. In your browser it works, because usually browsers have a broader list of trusted certificate authorities or your due to a company policy the CA certificate has already been preinstalled on your PC.
What you need to do is export the CA certificate to a pem format (you can do this in the browser - look in Google) and use the "verify" parameter when doing the POST request - see documentation here (section "SSL Cert Verification").
You can also disable certificate verification altogether by passing verify=False to the requests.post method.
I appreciate your response. When using chrome or IE Certificate Export Wizard, the option to export to .pem is not available :-/ I did look around on my computer and found that there are several .pem files like 'cacert.pem' here C:\Python27\Lib\site-packages\certifi. Certifi documentation says python will automatically use this if certify is available which it is. The cacert.pem did not contain any reference to 'jira' however so I'm assuming I will be adding a CA certificate(s) for JIRA here?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I figured it out! There isn't one tutorial on the internet that described exactly how to get from the step of extracting CA certificates for a site from the browser to having a working .pem file ready for verification use for the python program, so I had to follow a few different tutorials. I'll describe this in a subsequent answer.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Cool! I was on the road and could not respond earlier - you are correct, you need to either add the CA certificate to the file where python looks OR package it in a separate file and pass the full path to the verify parameter.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you very much Petar, your answer was EXTREMELY helpful! However, since the creation of the CA certificates to pem format from JIRA isn't trivial, I will give a brief run down of how I did it
1) Follow this tutorial
http://docs.bvstools.com/home/ssl-documentation/exporting-certificate-authorities-cas-from-a-website
or search 'How to Export Certificate Authorities from a Website' and export the CA certificates. Instead of what they suggest in the tutorial, make sure to export to file format "Base-64 encoded X.509 (.CER) "
2) Then follow this tutorial to use these CA certificates to build your .pem file:
https://www.digicert.com/ssl-support/pem-ssl-creation.htm or search "How to create a .pem file for SSL certificate installations with the Server and Intermediate Certificates"
My program now looks something like this, which works:
jirainterface.py:
import requests
loginurl = 'https://jira01.devtools.mycompany.com/rest/auth/1/session'
filepath = 'C:\Path\To\My\JIRA.pem'
loginArgs = {'username': 'myusername','password': 'mypassword'}
resp = requests.post(loginurl, json=loginArgs, verify=filepath)
print(resp.status_code, resp.reason)
>> (200, ‘OK’)
Yeah!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Corinne,
Could you elaborate on the step 2? I am interested in understanding which certificates are concatenated. For instance, once the JIRA certificate is found by inspection in step 1, are there any other certificates that should be concatenated?
I was also using wincertstore package to decode the certificates - it short-circuits the need to export them to .cer then convert to .pem if name is known; which comes from the inspection of the certificate as you suggest it in step 1. This example shows how to print the ASCII texts for the certificates: https://pypi.python.org/pypi/wincertstore
import wincertstore
for storename in ("CA", "ROOT"):
with wincertstore.CertSystemStore(storename) as store:
for cert in store.itercerts(usage=wincertstore.SERVER_AUTH):
if cert.get_name()=="The name of CERT found":
print(cert.get_pem().decode("ascii"))
print(cert.get_name())
print(cert.enhanced_keyusage_names())
Thank you in advance.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.