REST api using token ow gives SSL error

Larry Weisberg October 18, 2020

I am using JiraClient.py

see: 

When I first ran it, after generating a JIRA API Token, it worked fine.  However, now I am getting an error like this:

  • urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='XXXXX.atlassian.net', port=443): Max retries exceeded with url: /rest/api/3/worklog/updated?since=1601801936618 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1076)')))

 

I even tried generating a brand new token, and it doesn't work with that either.

 

Any ideas?

Thanks,

Larry

3 answers

1 accepted

2 votes
Answer accepted
Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 22, 2020

Hi @Larry Weisberg ,

If I understand correctly you are trying to call a Jira Cloud REST API endpoint using jira_client.py and this is now returning an SSL error, while it was working fine before.

If this is correct, can you please check the following:

  1. In the script you have only entered your email address as the username and the API Token associated to it. You left all the other values set to "none"
  2. You are able to call the same endpoint successfully using Curl. If this does not work please add the -D- argument and paste the response in here (replace : <EMAIL-ADDRESS>, <API-TOKEN>, <NAME> and <TIMESTAMP> with the appropriate values):
    curl -u <EMAIL-ADDRESS>:<API-TOKEN> -D- -X GET "http://<NAME>.atlassian.net/rest/api/3/worklog/updated?since=<TIMESTAMP>"

 

Cheers,
Dario

Larry Weisberg October 22, 2020

Thanks @Dario B 

  1. Correct - I just call:
    client = JiraClient("my.email.address@company.com", "TOKEN_XYXYXYXYX")
    If I add verify=False in the call to
    self._session.get(url) ...
    then it works.
  2. If I just do the http portion from Browser:
    https://company.atlassian.net/rest/api/3/worklog/updated?since=1601798047737

    then it works fine; but doing curl:

    curl -u my.email.address@company.com:TOKEN_XYXYXYXYX -D- -X GET "https://company.atlassian.net/rest/api/3/worklog/updated?since=1601798047737"

    fails with:

    curl: (60) SSL certificate problem: self signed certificate in certificate chain
    More details here: https://curl.haxx.se/docs/sslcerts.html

    curl failed to verify the legitimacy of the server and therefore could not
    establish a secure connection to it. To learn more about this situation and
    how to fix it, please visit the web page mentioned above.

    I guess not so surprising that curl behaves same way that Python does; what is most surprising is that when I ran it the first few times, I did not get errors..

Thanks,

Larry

Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 22, 2020

Hi @Larry Weisberg

This is super weird and a bit concerning at the same time, since we don't have any self-signed certificate in the certificate chain for Atlassian Cloud products.

You can double check this by using the SSLShopper Certificate Checker or any other tool to check certificates:

  • SSLShopper:

    Certificate.jpg
  • OpenSSL:
    openssl s_client -showcerts -servername XXXXXX.atlassian.net -connect XXXXX.atlassian.net:443

    CONNECTED(00000003)
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
    verify return:1
    depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
    verify return:1
    depth=0 C = US, ST = California, L = San Francisco, O = "Atlassian Network Services, Inc.", CN = *.atlassian.net
    verify return:1
    ---
    Certificate chain
    0 s:C = US, ST = California, L = San Francisco, O = "Atlassian Network Services, Inc.", CN = *.atlassian.net
    i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
    ...
    ...

 

Now, if this error is only happening from the command line but not from the browser, there are chances your OS is using some old/outdated CA store (maybe an old version of openssl was installed recently).

In order to doble-check this, please do the following:

  • Compare the certificate you get from the browser with the one you get from command line (you can use the openssl command in above example) in order to  make sure that's the same one and exclude there is anything weird going on.
  • Once verified the certificate is correct/the same, you should update the CA store used by your OS (or by python, if it's not the same).

 

For further details, you might want to see below links:

 

Cheers,
Dario

Larry Weisberg October 22, 2020

Thanks @Dario B - that sounds promising... Might not get to it till next week but I'll take a look, (assuming instructions on the links are clear enough :-), or maybe my IT guy can help out).

 

Thanks!
Larry

Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 23, 2020

Hi @Larry Weisberg ,

The links are a bit random since I don't know which Operating System you use and which version of python. If you provide those details I will try to provide a more specific link.

Have a nice weekend!

Dario

Larry Weisberg October 23, 2020

Thanks @Dario B - I am using Python 3.7 on Windows 10.  As far as the certificates:

I had a few minutes today to run the openssl command above and got this:

CONNECTED(00000178)
---
Certificate chain
0 s:C = US, ST = California, L = San Francisco, O = "Atlassian Network Services, Inc.", CN = *.atlassian.net
i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
-----BEGIN CERTIFICATE-----
MII...
...
...==
-----END CERTIFICATE-----
1 s:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
-----BEGIN CERTIFICATE-----
MII...
...
...
Q=
-----END CERTIFICATE-----
---
Server certificate
subject=C = US, ST = California, L = San Francisco, O = "Atlassian Network Services, Inc.", CN = *.atlassian.net

issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3289 bytes and written 761 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

 

.. I got back 2 different certificates.  But it is not clear how to check what the certificate(s) is/are from the browser, so I wasn't able to compare...

Thanks,

Larry

Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 23, 2020

Hi @Larry Weisberg ,

In order to get the certificate from the browser you can click on the padlock icon next to the url in the address bar:

browser-cert.jpg

 

Also, as already outlined, there is no self-signed certificate anywhere and therefore if this was working fine before and it is not working now then either the CA store used by Windows changed, or something is hijacking the connection.

 So, since you are able to reproduce the issue with CURL, can you double check the CA store used and the certificate returned by replacing the -D- switch with -vvv?

Please run the command and paste the output in your reply removing the sensitive content like in below example:

curl -vvv -u XXXXXXXX@atlassian.com:API_TOKEN "https://XXXXXXXX.atlassian.net/rest/api/3/worklog/updated?since=1601798047737"

* Trying 18.xxx.xxx.xxx:443...
* TCP_NODELAY set
* Connected to XXXXXXXX.atlassian.net (18.184.99.128) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs

[REMOVED]

* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Atlassian Network Services, Inc.; CN=*.atlassian.net
* start date: Nov 28 00:00:00 2019 GMT
* expire date: Jan 18 12:00:00 2022 GMT
* subjectAltName: host "XXXXXXXX.atlassian.net" matched cert's "*.atlassian.net"
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
* SSL certificate verify ok.

[REMOVED]

{"values":[],"since":1601798047737,"until":1601798047737..... [REMOVED] ...

 

Lastly, not sure if this helps, I can see that there is a python package named certifi that includes the Mozilla CA bundle. For details see:

 

Have a nice weekend.

Dario

Larry Weisberg October 23, 2020

Thanks - but something fascinating - I just tried to Python script again and it worked!!!  Apparently because this time I "forgot" to get onto the corporate VPN, which I am normally on..

@Dario B - 

  1. does this make sense/explain what my issue?
  2. Would it still be beneficial would for me to re-run the curl/openssl commands twice - once on VPN and once not?

Thanks,

Larry

Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 23, 2020

Hi @Larry Weisberg ,

Yes, that makes sense and I'd say that the mystery is solved (second scenario: 
something is hijacking the connection). :) 

Also, it can still make sense to compare the certificates you get when you use curl with and without the VPN, so that you can bring this issue to the attention of your IT department.

Ciao!

Dario

Larry Weisberg October 25, 2020

Thanks so much @Dario B - I'll follow up with my local IT.

Larry Weisberg October 26, 2020

Thanks everyone for their advice.  In the end, I just needed to copy the (Base 64) certificate for our VPN into "...\Python\Python37\Lib\site-packages\certifi\cacert.pem" and the REST API from Python worked like a charm.

Like # people like this
Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
October 27, 2020

Thanks for updating this thread with the final solution @Larry Weisberg ! 

Like Larry Weisberg likes this
1 vote
Nic Brough -Adaptavist-
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
October 18, 2020

The SSL certificate your call is presenting to the server is not valid.  You will need to change to a valid certificate.

Larry Weisberg October 18, 2020

Thanks Nic!

I am using JiraClient from https://gist.github.com/dblanchette/b8ed8cf42431f56024c1c70ed5137e0f and basically my code does this:

    client = JiraClient("larry.weisberg@pragroup.com", "XYXYXYX") # Token value
recent_worklogs = client.retrieve_worklogs_updated_since(datetime.now() - timedelta(days=14))

 

JiraClient constructor does this:

class JiraClient:
def __init__(
self,
username: str = None,
api_token: str = None,
access_token: str = None,
access_token_secret: str = None,
consumer_key: str = None,
key_cert: str = None,
):
self._user_url = os.getenv("JIRA_SERVER", "").rstrip("/")
self._base_url = f"{self._user_url}/rest/api/3"

if username and api_token:
self._session = requests.Session()
self._session.auth = (username, api_token)
return

 

And retrieve worklogs : 

   response = self._session.get(url) 

 

This is where failure occurs, where URL is just a REST api that does work from Browser; Also it used to work from this script.

Basically - where is the ssl Cert created, used in the code?  Why/How would it have changed?

0 votes
Ian Jia Ern Khoo July 13, 2022

@Dario B @Nic Brough -Adaptavist-  Hi Nic and Dario,

I'm having some issues with accessing JIRA Cloud using my python script. I am using the bearer token authentication method. Previously, it also showed a 401 authentication error because of the SSL certification. Was wondering if you could help me with this. Thank you.

 

import jira.client
from jira.client import JIRA
jira_client = JIRA(options={'server':'my-site.com','request':False}, basic_auth=('jira_username', 'bearer_token_here'))
issue = jira_client.issue('XXXX-191')
print(issue.fields.summary)
Dario B
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
July 14, 2022

Hi @Ian Jia Ern Khoo ,

Please notice that adding an unrelated reply a thread from 2 years ago that is marked as resolved (answer accepted) is not the best way to get help.

However, in short:

  1. There's no such thing as bearer token authentication for Jira Cloud REST API. The allowed authentication methods are the ones listed in: https://developer.atlassian.com/cloud/jira/platform/security-overview/
  2. From what I see your script is (indeed) using basic authentication and not bearer token authentication.
  3. In order to use basic authentication you have to provide an Atlassian account email address and API token, as explained in the following page: Basic auth for REST APIs
  4. The code snippet you attached seems to have some generic placeholders data instead of real data and therefore there's not much I can say, other that 'my-site.com' is not a valid Jira Cloud URL and that you should provide email address and api token instead of username and bearer token.
  5. As suggested/mentioned many times in this thread you may want to send the same request with CURL in order to double check whether the issue is with your code or with the data you are providing

 

Finally, if nothing helps, I strongly advise to create a new thread providing more details on what you are doing together with the error message as well as the same request sent using Curl (removing the sensitive data like email address and api token).

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
TAGS
AUG Leaders

Atlassian Community Events