If you want to use the JIRA REST API without storing plain-text passwords in your application, you need to use OAuth. If you want the application to directly talk to JIRA without binding it to a JIRA user account, you need to use 2-legged OAuth. JIRA requires RSA keys for 2-legged OAuth. Zend_OAuth supports RSA-signed requests, but this is somewhat undocumented. Also, the Java OAuth library used by JIRA appears to have a bug that requires the field oauth_token in the Authorization header to be present but blank for 2-legged authentication (if it’s not present, it raises uncaught exceptions…). Lastly, you have to use the exact server name that JIRA thinks it has. Finding out all this took me quite a while, so here is the full code:
require_once 'Zend/Oauth.php'; require_once 'Zend/Oauth/Consumer.php'; require_once 'Zend/Crypt/Rsa/Key/Private.php'; require_once 'Zend/Crypt/Rsa/Key/Public.php';
$jql = 'project = KB'; $max = 50; $server = 'https://www.example.com/jira/'; // this must not be http://localhost:8080. It must match the proxyName, proxyPort and Context configured in ./conf/server.xml in JIRA. Otherwise you get signature_invalid exceptions $query = array('jql' => $jql, 'startAt' => '0', 'maxResults' => $max, 'fields' => 'summary,assignee,duedate,priority')
$privkey = new Zend_Crypt_Rsa_Key_Private('jira.pem'); $pubkey = new Zend_Crypt_Rsa_Key_Public('jira.pub'); $consumer = 'samplescript';
$query['oauth_token'] = ''; // otherwise you get uncaught net.oauth.OAuthProblemException: signature_invalid exceptions $oauth_config = array( 'consumerKey' => $consumer, 'rsaPrivateKey' => $privkey, 'rsaPublicKey' => $pubkey, 'signatureMethod' => 'RSA-SHA1', 'siteUrl' => $server . '/plugins/servlet/oauth', 'requestScheme' => Zend_Oauth::REQUEST_SCHEME_QUERYSTRING, );
$oauth = new Zend_Oauth_Consumer($oauth_config); $oauth->setSignatureMethod('RSA-SHA1'); $oauth->setRsaPrivateKey($privkey); $oauth->setRsaPublicKey($pubkey);
$token = new Zend_Oauth_Token_Access(); // 2-legged authentication doesn't use tokens, but this is the only way to get a HTTP Client that sets the proper Authorization headers $oauth->setToken($token); $client = $token->getHttpClient($oauth_config, $url);
$client->setUri(sprintf('%s/search', $url)); $client->setMethod(Zend_Http_Client::GET); $client->setParameterGet($query); $json = json_decode($client->request()->getBody());
Generating the keys
openssl genrsa -out jira.pem 1024 openssl rsa -in jira.pem -pubout -out jira.pub
Registering them with JIRA
Go to the JIRA Administration, click Plugins, then Application Links.
Click Add Application Link, enter your server URL, enter the name of your application and select Generic Application.
Now configure it: got to Incoming Authentication, set a Consumer Key (I used samplescript above), set a name and paste the contents of jira.pub into the box. Now check
I tried to use your code but i always get 500 error, any idea of this, i installed latest zend framework but still no success under logs i see PHP Fatal error: Class ‘OAuthConsumer’ not found in
Install Zend Framework 1.
Hello, Michael! I can’t find where defined $url in your article.
Pingback: Migrating JIRA to osTicket | Michael Kuron's Blog
JIRA 7.2, and I don’t understand why I don’t see the “Allow 2 legged OAuth option”.
Any ideas as to why?
It’s your Jira server, e.g. https://jira.example.com, http://jira.example.com:8080, https://www.example.com/jira, etc.
I no longer run Jira, and I only used it up to version 6.x. But have a look at the documentation: https://confluence.atlassian.com/adminjiracloud/using-applinks-to-link-to-other-applications-779295829.html — it looks like 2-legged is now on by default, but you can manually enable it in the token properties.