Tech Tutorial: OAuth in JIRA

May 31, 2013

ProdPad Labs

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.

Simon Cast is a product expert and Co-founder of ProdPad - building great product management software, and of Mind the Product, a global community of product managers. He has 14 years experience in building products, ranging from satellite control software to online social capital tools, and also spent time in the Australian Army. In 2010, he co-founded ProductCamp London with Janna, and he now organizes ProductTank events and the Mind the Product Conference.

25
Leave a Comment

avatar
14 Comment threads
11 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
16 Comment authors
anelli bulgari Bzero CopiaSam LiSimon CastYoussefSimon Recent comment authors
Kourosh
Guest
Kourosh

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
Guest
Alexander

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
Guest
sonia

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
Guest
sana

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

Martin
Guest
Martin

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
Guest
Anil

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
Guest
marc

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

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

Leo Nunes
Guest

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
Guest
Nikita

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
Guest
Martijn

Thanks. Very helpful

vivek
Guest

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

Simon
Guest
Simon

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
Guest
Youssef

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

Sam Li
Guest

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

trackback

anelli bulgari Bzero Copia

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