OAuth 2.0 protected resource request

Once the client has obtained the required token accessing the protected resource or web API is simply a matter of including the token in the HTTP request.

The most common (and simple) access token type is bearer. Make sure the token is kept secure at all times, since, at its type implies, whoever has it will have access (until the token expires or is revoked).

Bearer access tokens are typically included in the Authorization header like this:

Authorization: Bearer [token-value]

For example:

GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer xyz......

Example request

Setting the authorisation header is a straightforward, and should be possible with any HTTP client / library.

With cURL

curl -H "Authorization: Bearer $ACCESS_TOKEN" URI

With java.net.URL

import java.net.*;
import com.nimbusds.oauth2.sdk.token.*;

// The obtained access token
AccessToken accessToken = ...

// The protected resource / web API
URL resourceURL = new URL("http://example.com/resource/1");

// Open the connection and include the token
URLConnection conn = resourceURL.openConnection();
conn.setRequestProperty("Authorization", accessToken.toAuthorizationHeader());

// Continue...

With JAX-RS Jersey client

import javax.ws.rs.client.*;
import com.nimbusds.oauth2.sdk.token.*;

// The obtained access token
AccessToken accessToken = ...

Invocation.Builder invocationBuilder = targetResource.request(...);
invocationBuilder.header("Authorization", accessToken.toAuthorizationHeader());

With Apache HttpClient

See this post on StackOverflow.

Dealing with errors

Errors will be inevitable :)

If you get a 4xx HTTP status code check the WWW-Authenticate header whether request failed due to an invalid or expired access token.

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
                  error="invalid_token",
                  error_description="The access token expired"

The bearer spec defines the following error codes:

  • invalid_request The request was badly constructed.

  • invalid_token The provided access token is invalid or has expired. Request a new access token from the authorisation server and try again.

  • insufficient_scope The provided access token is valid, but its scope is not sufficient to perform the request. You're either trying to do too much with the token, or may need to request a new one with the needed scope.

  • no error code No access token was provided with the request.

The Nimbus OAuth 2.0 SDK provides you with a handy class to parse bearer token errors:

import com.nimbusds.oauth2.sdk.token.*;

// Get the WWW-Authenticate header.
wwwAuthHeader = ...

// Parse it
BearerTokenError error = BearerTokenError.parse(wwwAuthHeader);

// Check the error code
if (error.equals(BearerTokenError.MISSING_TOKEN)) {
    // Handle missing token...
} else if (error.equals(BearerTokenError.INVALID_REQUEST)) {
    // Malformed request...
} else if (error.equals(BearerTokenError.INVALID_TOKEN)) {
    // Refresh / obtain new token...
} else if (error.equals(BearerTokenError.INSUFFICIENT_SCOPE)) {
    // Overstepped authorisation / obtain new token with required scope
}

References