Cleito IWAAC is not made only for browsers. Any HTTP client that can handle Kerberos authentication is actually able to access to web applications protected by IWAAC without entering a username and password. This is especially useful for scripts and programs that request the RESTful web APIs of modern applications such as Jira, Confluence, Bamboo, Bitbucket Server, Fisheye and Crucible.
The Atlassian REST APIs actually support Cookie-based authentication. The JSESSIONID cookie - along with the crowd.token_key and atlassian.xsrf.token cookies - obtained by logging in with a username and password can thus be used in any HTTP request to the Atlassian REST APIs. Thanks to IWAAC, that cookie can also be obtained upon successful Kerberos authentication, hence avoiding the need to hard-code a username and password in scripts and programs that request the REST APIs.
This page gives some examples of PowerShell, Python and Groovy scripts to get a JIRA issue via a simple REST request.
Windows NT
/login.jsp
The UseDefaultCredentials option of Invoke-WebRequest makes it super easy to authenticate with Kerberos from a Windows machine in the AD domain. Thus, a PowerShell REST client will be as simple as the following code:
# URL of Jira's login page $jiraLoginUrl = "http://jira.cleito.com:8080/login.jsp" # URL of the Jira issue to retrieve $jiraIssueUrl = "http://jira.cleito.com:8080/rest/api/2/issue/IWAAC-1" # User-Agent of this script $useragent = "Windows NT" # Get a valid JSESSIONID cookie Invoke-WebRequest -UseDefaultCredentials -Uri $jiraLoginUrl -UserAgent $useragent -SessionVariable websession # REST request Invoke-RestMethod -Method GET -Uri $jiraIssueUrl -UserAgent $useragent -WebSession $websession
The PycURL package allows developers to implement Kerberos authentication with very few lines of code. Please follow these instructions to install PycURL in your environment.
import pycurl import cStringIO # URL of Jira's login page # The URL MUST be of the form: http://FQDN:port/login.jsp # where FQDN is the A record of the server in Active Directory DNS jiraLoginUrl = "http://jira.cleito.com:8080/login.jsp" # URL of the Jira issue to retrieve # The URL MUST be of the form: http://FQDN:port/<uri> # where FQDN is the A record of the server in Active Directory DNS jiraIssueUrl = "http://jira.cleito.com:8080/rest/api/2/issue/IWAAC-1" # User-Agent of this script useragent = "Windows NT" # Instantiate http client curl = pycurl.Curl() curl.setopt(pycurl.COOKIEFILE, "") curl.setopt(pycurl.USERAGENT, useragent) curl.setopt(pycurl.HTTPAUTH, pycurl.HTTPAUTH_NEGOTIATE) curl.setopt(pycurl.USERPWD, ':') # Get a valid JSESSIONID cookie curl.setopt(pycurl.URL, jiraLoginUrl) curl.setopt(pycurl.WRITEFUNCTION, lambda x: None) curl.perform() # REST request response = cStringIO.StringIO() curl.setopt(pycurl.URL, jiraIssueUrl) curl.setopt(curl.WRITEFUNCTION, response.write) curl.perform() curl.close() print response.getvalue()
Thanks to Apache HttpComponents, Groovy makes Kerberos authentication very easy as well. Thus, a Groovy REST client will be as simple as the following code. Please note that this will only work on Windows machines in the AD domain as Apache HttpComponents relies on Windows system libraries for Kerberos authentication.
@Grab('org.apache.httpcomponents:httpclient-win:4.5.2') import org.apache.http.client.methods.CloseableHttpResponse import org.apache.http.client.methods.HttpGet import org.apache.http.client.protocol.HttpClientContext import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.WinHttpClients import org.apache.http.util.EntityUtils // URL of Jira's login page // The URL MUST be of the form: http://FQDN:port/login.jsp // where FQDN is the A record of the server in Active Directory DNS def jiraLoginUrl = "http://jira.cleito.com:8080/login.jsp" // URL of the Jira issue to retrieve // The URL MUST be of the form: http://FQDN:port/login.jsp // where FQDN is the A record of the server in Active Directory DNS def jiraIssueUrl = "http://jira.cleito.com:8080/rest/api/2/issue/IWAAC-1" // User-Agent of this script def useragent = "Windows NT" // Check whether required Windows libraries are available assert WinHttpClients.isWinAuthAvailable() //Instantiate http client def httpclient = WinHttpClients.createDefault() def context = HttpClientContext.create() // Get a valid JSESSIONID cookie def loginRequest = new HttpGet(jiraLoginUrl) loginRequest.setHeader("User-Agent", useragent) httpclient.execute(loginRequest, context) // REST request def restRequest = new HttpGet(jiraIssueUrl) def response = httpclient.execute(restRequest, context) println EntityUtils.toString(response.getEntity())
You might also want to run your Python or Groovy scripts from non-domain machines (e.g. Linux servers that do not belong to your Active Directory domain). To do so, you will need to generate a keytab file for the user running your scripts. A keytab file is a piece of cryptographic information that will enable your scripts to get the required Kerberos tickets to access to your back-end application.
<YOURDOMAIN.COM>
<YOURDOMAIN.COM>
= {<ad_domain_controller_fqdn>
:88.<yourdomain.com>
= <YOURDOMAIN.COM>
<yourdomain.com>
= <YOURDOMAIN.COM>
<your_AD_username>
-k 1 -e rc4-hmac OR aes128-cts-hmac-sha1-96 OR aes256-cts-hmac-sha1-96
<your_AD_username>@<YOURDOMAIN.COM>
: <your_AD_user_password>
<keytab_file_name>
<keytab_file_name>
<your_AD_username>
before running your Python script (you can run any PycURL-based script).<keytab_file_name>
"<your_AD_username>
@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7.1') @GrabResolver(name='net.sourceforge.spnego', root='http://repository.jspresso.org/maven2/') @Grab('net.sourceforge.spnego:spnego:7.0') import java.net.URL import net.sourceforge.spnego.SpnegoHttpURLConnection import groovyx.net.http.RESTClient // URL of Jira's login page // The URL MUST be of the form: http://FQDN:port/login.jsp // where FQDN is the A record of the server in Active Directory DNS def jiraLoginUrl = "http://jira.cleito.com:8080/login.jsp" // URL of the Jira issue to retrieve // The URL MUST be of the form: http://FQDN:port/<uri> // where FQDN is the A record of the server in Active Directory DNS def jiraIssueUrl = "http://jira.cleito.com:8080/rest/api/2/issue/IWAAC-1" // User-Agent of this script def useragent = "Windows NT" // Instantiate http client System.setProperty("java.security.krb5.conf", "/etc/krb5.conf") System.setProperty("java.security.auth.login.config", "login.conf") def httpClient = new SpnegoHttpURLConnection("rest-client") httpClient.setRequestProperty('User-Agent', useragent) // Get a valid JSESSIONID cookie httpClient.connect(new URL(jiraLoginUrl)) def header def cookieList = [] for (int i=1; (header = httpClient.getHeaderFieldKey(i))!=null; i++) { if (header.equals('Set-Cookie')) { cookieList.add(httpClient.getHeaderField(i).tokenize(';')[0]) } } // REST request def request = new URL(jiraIssueUrl).openConnection() as HttpURLConnection request.setRequestProperty('Cookie', cookieList.join('; ')) println request.inputStream.text