OAuth2 Authorization for IRIDA

This document describes how a client application can communicate with the IRIDA REST API using OAuth2 Authorization.

In order for a user to access a resource on the REST API, they must first obtain an OAuth2 token from that API. This token allows a given client and user access to a given resource on the API. The token is stored by both the client and API. When the client makes a request to the API they pass along their token which is compared to a list of active issued tokens, then the client is given or denied access based on the validity of that token.

Terms

Authorization Code Grant Type

Introduction

A client must provide the correct credentials to obtain a token from the API. If your client is connecting to the REST API via a web service, you will use the “authorization_code” grant type. This will enable the OAuth2 web authorization flow.

For the user, this will happen in 4 steps:

  1. User requests a page requiring an OAuth2 connection to IRIDA.
  2. User is presented with a login page for the IRIDA REST API.
  3. User is asked to verify access to their protected resources.
  4. User is redirected back to your web service and displayed the requested resources.

On the server things are a little more complicated:

  1. Your web service requests a resource from IRIDA REST API and receives HTTP 401 (Unauthorized). This begins the OAuth2 authorization_code flow.
  2. Your web server redirects the user to /oauth/authorization with parameters to redirect back to your web service once authorization is complete. This will present the user with a login page from the IRIDA API.
  3. Once the user completes the login and authorizes your client, they are redirected back to your web service. This redirect will contain a ?code=XXXX parameter which is the authorization_code.
  4. Your service sends the authorization code to /oauth/token. The API will send a response containing an OAuth2 token.
  5. Your service may then request resources from the API using the token.

While this description sounds fairly complicated, whatever web framework you’re using will likely provide an OAuth2 package or library for handling OAuth2 client authorizations. An incomplete list can be found at http://oauth.net/2/ (look under “Client Libraries”), but you can find more on your web framework’s website.

Obtaining a Token

Whatever OAuth2 client library you’re using should provide some method to request an OAuth2 token from a server. The implementation may differ slightly but it should provide a way to set some common client details arguments. You can generally use the following values:

Often these libraries will obtain tokens in 2 steps. The first step will direct the user’s browser to /oauth/authorize on the IRIDA API to obtain an authorization code. The second will exchange the authorization code for a OAuth2 token. This token can then be used to request protected resources from the REST API.

After this authorization occurs, the user will not have to re-authorize your service for as long as the token is valid (12 hours by default). This will require your web service to have some method of storing OAuth2 tokens for a user, otherwise a new token will have to be obtained for each request.

Password Grant Type

Introduction

Similar to the authorization_code grant type, the password grant allows an application to retrieve an OAuth2 token from the REST API, then use it to request resources. The password grant type differs in that it can be easily used from a desktop application as it doesn’t require the user to log in via a web browser. The user will provide their IRIDA username and password directly to the application where it will be used to request an OAuth2 token. Although the password grant type is less complicated for the user and developer, the authorization_code grant is preferred because it doesn’t require the user to pass their username and password directly to the client application.

In the client application:

  1. The client application sends the username, password, client id, and client secret to /oauth/token. The API will send a response containing an OAuth2 token.
  2. Your service may then request resources from the API using the token.

Obtaining a Token

Whatever OAuth2 client library you’re using should provide some method to request an OAuth2 token from a server. The implementation may differ slightly but it should provide a way to set some common client details arguments. You can generally use the following values:

These libraries should obtain a token in one request to the server. It will send all of the client details in an HTTP request to the token endpoint, and the server should respond with an OAuth2 token. This token can then be used to request protected resources from the REST API.

Using a Token to Access Protected Resources

When an OAuth2 token has been obtained it can be used to access protected resource on the IRIDA API. The token is sent to the REST API using an HTTP header. Again most OAuth2 libraries will have a method to request resources using this token, but if not they can be easily used with most HTTP request libraries.

A Bearer Authorization header must be added to the HTTP request using the obtained token. If the token string is “12345”, this header will be of the form:

Authorization: Bearer 12345

If the token is valid, you will receive your requested resources. If not you should receive a HTTP 403 error.

Examples

Perl

my $client = OAuth::Lite2::Client::UsernameAndPassword->new(
        id               => $client_id,
        secret           => $client_secret,
        access_token_uri => $base_url."/oauth/token");

my $token = $client->get_access_token(username=>$username,password=>$password);
my $tokenstr = $token->access_token;

my $head = new HTTP::Headers;
$head->authorization("Bearer $tokenstr");
my $request = HTTP::Request->new("GET",$url,$headers);
...

Python

oauth_serv = OAuth2Service(
    client_id=clientId,
    client_secret=clientSecret,
    name="irida",
    access_token_url = baseURL + "oauth/token",
    base_url=baseURL)

params = {'data' : {'grant_type' : 'password',
        'client_id' : clientId,
        'client_secret' : clientSecret,
        'username' : username,
        'password' : password}}

access_token = oauth_service.get_access_token(decoder=decoder,**params)
session = oauth_service.get_session(access_token)
response = session.get(url)
...