How to authenticate to Jira REST API

saranya22 June 6, 2018

I am using Jenkinsfile to update the Build result to one of the field using Curl command. 
Am using HTTP Basic auth. But, I need another method to authenticate to Jira Rest API other than Basic as it is very easy to Decode using base64.
Suggest me a method to authenticate to Jira server using curl command?

The curl command that I use is 

 sh """curl  --noproxy '*' -D- -H "Authorization: Basic YWRtaW46YWRtaW4=" -X PUT --data '{"fields":{"customfield_10314":{"value":"Development Completed"}}}' -H "Content-Type: application/json" https://localhost:8081/jira/rest/api/2/issue/${issue}"""

2 answers

1 accepted

16 votes
Answer accepted
Andy Heinzer
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
April 5, 2019

Hi everyone,

Having reviewed this question, it appears that the question asked and the answer given don't exactly match up here. Saranya is asking about how to use a different authentication method other than Basic with curl. Moses' reply does provide ways to use OAuth to authenticate via REST, but this method does not utilize curl (and I can't find a way to use curl with OAuth).  As a result, I think that some people searching google that come across this issue find the answer confusing or misleading for their own use cases.

I wanted to add a more comprehensive and clarifying answer here, sorry if it's long-winded:

There are different methods for authenticating to the REST API in regards to Jira, but each platform has some slightly different authentication methods available to them and as such have different use cases. Platforms here refers to the difference between Server and Atlassian Cloud products. There are different kinds of tokens to refer to below.

 

For Jira Server

Jira Server does not have the same kind of API tokens that can be created for Atlassian Cloud products. There are tokens that can be created, but these are OAuth tokens. The use of OAuth tokens requires that you utilize a programming library in a language such as Java, perl, python, nodejs, etc in order to make these calls. If you're using OAuth, you can't use curl.  Examples of these libraries in different languages and source code can be found in https://bitbucket.org/atlassianlabs/atlassian-oauth-examples/src/master/
But if you're using curl, and you're using Jira Server, you can still utilize basic auth or cookie based auth for making REST calls.

Jira Server Developer blog's page on Security Overview https://developer.atlassian.com/server/jira/platform/security-overview/ explains the different authentication and authorization you can use with Jira Server.  From that page:

OAuth

OAuth uses request tokens generated from Jira to authenticate users. We recommend using OAuth when you integrate with Jira. It takes more effort to implement, but it is more flexible and secure compared to the other two authentication methods.

See OAuth, to learn how to implement a client that uses OAuth.

Basic authentication

Basic authentication uses a predefined set of user credentials to authenticate. We recommend that you don’t use basic authentication, except for tools like personal scripts or bots. It may be easier to implement, but it is much less secure.

See Basic authentication, to work through an example of calling Jira with basic authentication.

Cookie-based authentication

Jira uses cookie-based authentication in the browser. You can rely on this to call the REST API from the browser (for example, via JavaScript). However, we recommend you use OAuth or Basic authentication in most cases.

See Cookie-based authentication, to learn how to call Jira using cookies.

Security for apps

Jira Server apps run alongside the product code, so you don’t need to call the REST API. Instead, you call the Java API directly. However, there are additional steps to follow to make your app secure, such as using form token handling.

Form token handling

Form token handling is an additional authentication mechanism for apps that lets Jira validate the origin and intent of requests. This is used to provide another level of security against cross-site request forgery (XSRF).

See Form token handling, to work through how to implement form token handling in Jira.

 

 

For Jira Cloud,

It is possible you can create your own API token at https://id.atlassian.com These are only for Atlassian Cloud sites. These are not OAuth tokens. More details on the creation are in https://confluence.atlassian.com/cloud/api-tokens-938839638.html These tokens as part of Basic auth as described in https://developer.atlassian.com/server/jira/platform/basic-authentication

If you're using basic auth in Jira Cloud, then using a utility like curl can work here with an API token.

However if you're wanting to using OAuth (not the API token created from https://id.atlassian.com), you won't be able to use curl to authenticate. It's a detail that lots of users miss and I fear Atlassian has not sufficient documented just yet. In order to do the handshakes required for OAuth use, your REST calls are expected to utilize a programming library that Atlassian has provided. As such, curl can't parse what this library is doing. This handshake can be in any of various languages such as java, python, perl, ruby, nodejs, etc. You can find the source of this library and examples on how to use it in https://bitbucket.org/atlassianlabs/atlassian-oauth-examples/src/master/

 

Other ways to make REST calls in Jira Cloud
https://developer.atlassian.com/cloud/jira/platform/security-for-other-integrations/

I hope this helps to clarify some common misconceptions about the different methods of authenticating in REST for Jira Cloud and Jira Server.

Cheers,

Andy

Kin August 10, 2020

Must be noted, it appears that you cannot create an authentication token from a "Confluence Cloud connect app" to authenticate with Jira Cloud when making Jira rest API calls.
Some say that the workaround is to implement a connect app on the Jira Cloud also, but how to do the exchange etc is not documented. I assume that is one way to get a clientId and sharedSecret from Jira Cloud to use in Confluence Cloud to get the accestoken?
Or do we still have to wait for AC-2001 ?

The most confusing part in the documentation is the thin line between a "connect app" and "non connect app" which also determines if oauth 3LO or 2LO is supported and wether a JWT is currently limited to one cloud product within the Atlassian cloud ecosystem. Hence "OR" in documentation.

Although it can be accomplished by using the userid + apitoken approach, the only downside to this is that the apitoken can only be generated by the user manually.

Ofcourse there's the approach of creating two separate connect apps for Confluence Cloud and Jira Cloud, the last that only serves a oauthClientId and sharedSecret to use on the Concfluence side.

geoffrey r_ August 11, 2020

This solution needs to be revised since Basic Auth and Cookie-based Auth has been depreciated and removed from the API.

Like Rabbit Stoddard likes this
Isaac_nl October 13, 2020

They have not been removed and I doubt they will be removed soon. The OAuth (1.0) method is terrible and at least an API token method should be added before removing BasicAuth and/or Cookie based authentication.

4 votes
Moses Thomas
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
June 6, 2018

@saranya22I propose the

OAuth is an authentication protocol that allows a user (resource owner) to grant a third-party application (consumer/client) access to their information on another site (resource). JIRA uses 3-legged OAuth (3LO), which means that the user is involved in the authentication process by authorizing access to  your Jira data.

1. You need to configure application links (in coming) , that is third party application with your jira instance, see good article https://www.prodpad.com/blog/tech-tutorial-oauth-in-jira/ on how to configure application link for third party.

Also see how to generate public and private key,

https://confluence.atlassian.com/jirakb/how-to-generate-public-key-to-application-link-3rd-party-applications-913214098.html

 

2. You will need to generate Access token, (doing the OAuth dance) I suggest you use Python code to generate it , easier. https://bitbucket.org/atlassian_tutorial/atlassian-oauth-examples/src/3f0d22c5b1d8749fae6f05aa3556ca8ac3724b5a/python/?at=default

 

Once you are able to generate this access token if you succeed it will display a link to ( log in as this user Admin for example which you want to use to access Jira data,(tickets in Jira for example) then approve access to Jira using this user.

 3. Then you can use this user in you external application(code to access Jira, by adding private key parameter in python code for instance that accesses Jira data in  your Jira instance)

Best.

Don Dewar December 21, 2018

The method in the example requires a PEM key to the server. If I got a permanent access token from Jira how can that be used? I basically want to do what rest-oauth-client-1.0.one-jar.jar does but using python

Moses Thomas
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 31, 2018

@Don DewarSee point 2 & 3 you have your answer there.

Don Dewar December 31, 2018

Thanks. I finally did figure that out but now get this traceback.

./app2.py
Traceback (most recent call last):
  File "./app2.py", line 11, in <module>
    r = s.get("https://********/jira/rest/api/2/issue/*****-4313")
  File "/Library/Python/2.7/site-packages/requests/sessions.py", line 521, in get
    return self.request('GET', url, **kwargs)
  File "/Library/Python/2.7/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Python/2.7/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Python/2.7/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/Library/Python/2.7/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/Library/Python/2.7/site-packages/urllib3/connectionpool.py", line 346, in _make_request
    self._validate_conn(conn)
  File "/Library/Python/2.7/site-packages/urllib3/connectionpool.py", line 850, in _validate_conn
    conn.connect()
  File "/Library/Python/2.7/site-packages/urllib3/connection.py", line 337, in connect
    cert = self.sock.getpeercert()
  File "/Library/Python/2.7/site-packages/urllib3/contrib/pyopenssl.py", line 348, in getpeercert
    'subjectAltName': get_subj_alt_name(x509)
  File "/Library/Python/2.7/site-packages/urllib3/contrib/pyopenssl.py", line 222, in get_subj_alt_name
    for name in ext.get_values_for_type(x509.DNSName)
  File "/Library/Python/2.7/site-packages/urllib3/contrib/pyopenssl.py", line 175, in _dnsname_to_stdlib
    name = idna_encode(name)
  File "/Library/Python/2.7/site-packages/urllib3/contrib/pyopenssl.py", line 173, in idna_encode
    return idna.encode(name)
  File "/Library/Python/2.7/site-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/Library/Python/2.7/site-packages/idna/core.py", line 265, in alabel
    raise IDNAError('The label {0} is not a valid A-label'.format(label))
idna.core.IDNAError: The label Bundle_***** is not a valid A-label

which appears to be a correct error given the IDNA name has an underscore in it. (note company specific names are obscured in the traceback with asterisks). I haven't been able to find a work around for this, but that is a python community issue rather than Jira.

Moses Thomas
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
December 31, 2018

@Don DewarI suspect that some  library is missing for  me it worked for me using  the code  which  i have provided  in the  link  above.  I suggest  you  install pycharm  and then run your code  with   pycharm  will  show you message on  what  is missing.  Then  once you  have run  the code  go  to  >settings  > project interpreter and then  click (+ )  button to  add missing  packages.

But  make  sure you  are doing the right thing,  following  the documentation  .

Co-op 3 (Alesia Lozito) February 6, 2020

[We're new here, so please forgive any newb errors, like posting too late or in the wrong location. Advice on this is very welcome ... ]

 

OAuth 2.0 (3LO) issues:

We are building an internal message system to display some company wide data, including the status of Jira Issues for each of our teams. We're writing this in VueJS. The data is obtained (successfully) from the Jira API, and passed to a Google Chart. Up to this point, we've been satisfied using Basic Authentication to get things up and running, but are now trying to implement OAuth 2.0. It's proving difficult. There are very few examples here and other places online, and those we've seen don't include much detail as yet.

In particular during our OAuth2.0 (3LO) authorization we are able to retrieve an authentication code successfully in step 1 as outlined in the documentation. This code is then parsed from the URL into the second 'exchange' to receive a token as outlined in step 2 in the same documentation.

Documentation: https://developer.atlassian.com/cloud/jira/platform/oauth-2-authorization-code-grants-3lo-for-apps/

However, when trying to retrieve the token the response errors out with a 401 and is:


{"error":"access_denied","error_description":"Unauthorized"}

 

Multiple attempts have been made to check for syntax errors  - however the authorization and syntax we use is identical to that found in the Jira API documentation (as far as we can tell).

We are at a loss as to what could be causing this. Our code is posted below - with the user data omitted. (We're convinced it was accurate as well before deletion). Hopefully explanation and code provide enough information for some others to provide help and/or hints that we and others might be able to use.

(If you've read this far, thanks so much for your interest and patience!)

 

Paul and Dave

 

Relevant Code:


// This code works fine.
oAuthTwoAttempt: function () {
var redirectURL = `https://auth.atlassian.com/authorize?audience=api.atlassian.com&client_id=xxxx&scope=read%3Ajira-work&redirect_uri=http%3A%2F%2Flocalhost%3A3000&state=5555&response_type=code&prompt=consent`
this.redirectedRecently = true;
window.location.href = redirectURL;
},

// Extracting the code from the URL
getParameterByName: function(name, url) {
if (!url) url = window.location.search;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
},

// This function causes the 401 error response. The server will respond successfully - just with an error.
oAuthExchange: function () {
var authCode = this.getParameterByName("code", window.location.search);
console.log("Auth Code: " + authCode);
var headers = {
"Content-Type" : "application/json"
};
var jiraData = //'{"grant_type": "authorization_code","client_id": "xxxx","client_secret": "xxxx","code": "' + authCode + '","redirect_uri": "http%3A%2F%2Flocalhost%3A3000"}'
{
"grant_type": "authorization_code",
"client_id": "xxxx",
"client_secret": "xxxx",
"code": authCode,
"redirect_uri": "http%3A%2F%2Flocalhost%3A3000"
}
console.log(jiraData);
fetch(
'https://auth.atlassian.com/oauth/token',
{
method: "POST",
headers: headers,
data: jiraData
})
.then(response => {
return response.json();
})
.then(jsonData => {
});
}

Co-op 3 (Alesia Lozito) February 7, 2020

This appears to not have been viewed, so I reposted it here: https://community.atlassian.com/t5/Jira-discussions/OAuth-2-0-a-challenge/m-p/1295627#M10459 Thanks!

Suggest an answer

Log in or Sign up to answer