Skip to main content

Tech Tutorial: OAuth in JIRA

Posted by Simon Cast
May 31, 2013

JIRA logoAs we announced recently, we’ve integrated ProdPad with JIRA. This allows you to push ideas and user stories across to JIRA, creating a link back and forth between the two apps.

In the process of building this, I found the documentation for authentication in JIRA to be… let’s say lacking. It was a process of trial and error (and finally stumbling across this helpful page) that helped me get the OAuth integration for JIRA up and working.

Instead of keeping this to ourselves, I’ve decided to write a little tutorial to help others trying to setup JIRA OAuth. This tutorial applies to both the hosted “OnDemand” version and standalone installations. If you’re looking to build your own JIRA integration, we hope this helps!

Understanding JIRA OAuth

The key to understanding JIRA OAuth setup is that:
a. There is no central repository of consumer applications (unlike say Twitter or Trello), and
b. JIRA uses RSA encryption as part of its OAuth setup.

Before you can do the authentication, you have to set up a consumer app in the JIRA install. Note: each JIRA instance that you are connecting to will need a consumer app to be set up, whether that JIRA instance is hosted or standalone.

JIRA calls the OAuth consumer app “Application Link”, which requires RSA keys for signing the API calls. Before you can authenticate or communicate with a JIRA instance, you need to set up this “Application Link” and the RSA keys to be used for signing.

Set up a Consumer App in JIRA

To set up the consumer app, do the following (Note: You will need to have administrator access to your JIRA account):

1a. Log in to JIRA and, in the Administration list (click on the cog icon in the top right), head to Add-ons. (Figure 1a)

Figure 1a

Figure 1a

1b. Click on Manage add-ons. (Figure 1b)

Figure 1b

Figure 1b

2. Click on Application Links.  (Figure 2)

Figure 2

Figure 2

3. Enter https://app.prodpad.com into the field at the top of the “Configure Applications Link” page, and click Create new link. (Figure 3)

Figure 3

Figure 3

4. In the “Link Applications” modal window, enter the name of your app, ProdPad and select Generic Application from the “Application Type” dropdown. Repeat the name of the app, ProdPad, for the “Service Provider Name”, and enter prodpad for the “Consumer key” and the “Shared secret”. For the “Request Token URL”, “Access token URL” and the “Authorize URL”, enter https://app.prodpad.com. Check the checkbox for “Create incoming link”.

Figure 4

Figure 4

5. Enter Consumer Key (alphanumeric) and a Consumer Name, and paste the RSA public key into the “Public Key” field

Figure 5

Figure 5

6. Click Continue.

You’ve now created an “Application Link” (consumer app) in the JIRA instance with which you can authenticate against.

Code for the Authentication

The next step is to write the code to do the authentication of the user. I’ll show you an outline that is based on using the Zend OAuth classes, but the basic principal should be the same with whatever OAuth library you use.

The first method is to send a call to get the request token which you can then exchange for an access token. Each call using OAuth needs to be signed by the RSA keys and you need to configure the call.


$private_key = new Zend_Crypt_Rsa_Key_Private([your private key]);
$public_key = new Zend_Crypt_Rsa_Key_Public([your public key]);
$config = array(
'callbackUrl' => 'https://api.example.com/oauth',
'requestTokenUrl' => 'http://some.jira.host/plugins/servlet/oauth/request-token',
'authorizeUrl' => 'http://some.jira.host/plugins/servlet/oauth/authorize',
'accessTokenUrl' => 'http://some.jira.host/plugins/servlet/oauth/access-token',
'consumerKey' => [secret key],
'signatureMethod' => 'RSA',
'rsaPrivateKey' => $private_key,
'rsaPublicKey' => $public_key,
);

Getting the config right is important – otherwise you will spend a lot of time banging your head against a brick wall. Let’s go through each setting:

In the case of Zend Oauth classes it needs to convert the strings that are the public & private RSA keys into specific classes in order to be used. This is done in the first two lines of code above.

The config object is then array of information and classes.

The first element, callbackUrl, represents the URL in your system or application that JIRA will send the user back to during the authentication dance.

requestTokenUrl is the URL in the JIRA instance that is called to get the request token. The URL begins with the JIRA instance host in this case represented by http://some.jira.host/. This will be distinct for each JIRA instance. The plugins/servlet/oauth/request-token is common to all JIRA instances.

authorizeUrl is the URL that the user is sent to in order to authorise access to their account in a JIRA instance. Like requestTokenUrl, the URL begins with the host of the JIRA instance and then plugins/servlet/oauth/authorize. The last part is common across all JIRA installs.

accessTokenUrl is the URL that your system will call to convert the request token into an access token once the user has authorised access to their account. Like the requestTokenUrl the URL begins with the host of the JIRA instance and then plugins/servlet/oauth/access-token. This last part is common across all JIRA installs.

consumerKey is the alphanumeric string you entered in the Consumer Key field during the setup of the “Application Link” in JIRA.

signatureMethod, in this case, tells the Zend OAuth class to use RSA signing instead of the Zend OAuth class default.

rsaPrivateKey and rsaPublicKey hold the $private_key and $public_key classes respectively. The Zend OAuth uses these keys to sign the API calls it makes. Note: these keys must match the ones you set up in the “Application Link”

Once you’ve got the config set up, you need to call the method to fetch the request token. In the case of Zend, this is done this way:


$consumer = new Zend_Oauth_Consumer($config);
try {
$token = $consumer->getRequestToken();
} catch (Zend_Oauth_Exception $e) {
//some exception handling
}
//store the token for the next step (DB, SESSION etc)
$_SESSION['REQUEST_TOKEN'] = serialize($token);
$consumer->redirect();

In this snippet of code, the Zend OAuth class calls the requestTokenUrl and returns a token that is then used in the next step of the OAuth process. You’ll need to persist the $token in some manner, whether in the database, the session, or a cache. I suggest database as the JIRA token has a long life.

Once you’ve persisted the $token, you now need to redirect the user to the authorizeUrl so they can grant access to their account. This is done by the method $consumer->redirect(); at the bottom of the snippet.

Assuming the user grants your app access to their account, they are then redirected back to your app to the URL specified in callbackUrl. This end point should be the one that then does the next step of the OAuth dance: exchanging the request token for the access token.

Again, you’ll need to configure the Zend OAuth class using exactly the same method above. Once you’ve setup the config array you can then use the Zend OAuth class to exchange the request token you got in the first step with the access token that will then allow you to make API calls to the user’s account in the JIRA instance.


$config array(//as per above);
$consumer = new Zend_Oauth_Consumer($config);
try {
$token = $consumer->getAccessToken($_GET,unserialize($_SESSION['REQUEST_TOKEN']);
} catch(Zend_Oauth_Exception $e) {
//exception handling
}
$_SESSION['ACCESS_TOKEN'] = serialize($token);

In the above code, we are using the getAccessToken method of the Zend OAuth class to exchange the request token we got previously for the access token we need to access the API. Note that the method requires you to pass in the GET parameters as well as the unserialized request token.

What variable that contains the GET variable will depend on what MVC framework you are using (if any).

You will now have an access token that is persisted. This access token can then be used to access the user’s account on the JIRA instance. For further reading, check out using the Zend OAuth to make authenticated calls to APIs.

Hopefully this has saved you some time! If you can see anything I’ve missed or have any suggestions to improve on it, please leave a comment below.

Sign up to our monthly newsletter, The Outcome.

You’ll get all our exclusive tips, tricks and handy resources sent straight to your inbox.

How we use your information

guest
25 Comments
Inline Feedbacks
View all comments
Kourosh
Kourosh
September 20, 2013 3:21 pm

Hi,

I have been trying to make something like what you did for Jira using asp.net but I have not succeeded. How do I make Oauth work using dotnet? any idea? thanks

Alexander
Alexander
October 24, 2013 2:52 pm

Thanks for the useful tutorial! It helps me understand some corner cases of JIRA+OAuth workflows, although my dev language in Java.

One question is still being open though. What happens when the access token expires?
I guess in this case a user should follow the same initial path: requestToken -> authorize -> exchangeRequestForAccessToken. Will JIRA display “Authorize this app” screen again? Or it will silently redirect him to my callback page (as he has already granted access earlier)?
How can I check if the access token has expired? (any REST API for that)

Thanks in advance,
Alexander

sonia
sonia
May 13, 2015 7:59 am
Reply to  Alexander

Even I want to know What happens when OAuth access token expires? Is Jira rest api support refresh token to regenerate the token programatically?

sana
sana
December 3, 2013 7:04 pm

I want to know if jira rest based api has etag(or similar) support? Does it return 304 response for any response ?

Martin
Martin
May 15, 2014 2:11 pm

Hi Simon,

I thank you for creating this tutorial, I jus have a doubt in creating application link, How do you get the rsa public key ? and how to create one ?

Anil
Anil
July 30, 2015 5:23 pm

Thank you for such a nice tutorial, This helped me a lot to setup my application. But every thing was fine when I run from my local machine but when I moved to live server not giving any response from JIRA. Please help me is there any extra things I need to do for live server?

marc
marc
September 3, 2015 5:09 pm

Do you know how to crack jira agile? is been hard to crack, not a lot of information on internet. I guess you know how.
Thanks

Janna Bastow
Admin
September 4, 2015 10:57 am
Reply to  marc

Hi Marc, I’m not quite sure what you mean by cracking Jira Agile. Please elaborate!

Leo Nunes
November 16, 2015 12:44 pm

Hi Simon, I need to make one .NET application that authenticate user in JIRA and after this step is successfully, I need to redirect user to JIRA Dashboard. I need to do this because my application needs to make some check with other applications. I have been implemented JIRA Basic authentication, but, when I try to redirect, is like the session is losted. Do you know something about this?

Nikita
Nikita
February 18, 2016 5:31 am

Hey Simon,
Can you please help me how to do the same oauth settings, but in java?
I’m stuck and cant find anything relevant on the internet.

Martijn
Martijn
March 16, 2016 3:06 pm

Thanks. Very helpful

vivek
May 10, 2016 10:04 am

is there any way to automate App Link generation, using plugin something.

Simon
Simon
November 22, 2016 4:24 pm

I’m not sure if it’s our particular setup in Jira and/or my permissions set, but the Appication Links settings wasn’t under the Add-ons tab, but the Applications tab (which doesn’t appear in your screenshots). Might be worth checking and updating. Otherwise – great article, thanks!

Youssef
Youssef
January 1, 2017 11:02 am

Is there any way to get the user name/email from the access token (or the request token and verifier)?

Sam Li
March 13, 2017 1:47 am

Thank you very much. Your words saved me a lot of time.

trackback
December 2, 2017 3:17 am

anelli bulgari Bzero Copia

Just learning……….thanks so much, love it.