OAuth 2.0 client in 5 minutes

Getting OAuth 2.0 access token in your Java application

This example shows how to receive an access token from Facebook. It should work similarly with other OAuth 2.0 compatible implementations. See OAuth Wiki for the list of current OAuth 2.0 server implementations.

You can also run a sample client app available at: Client Tutorial or go through the following steps:

Add Oltu client to your classpath:

add Maven dependency:

<dependency>
    <groupId>org.apache.oltu.oauth2</groupId>
    <artifactId>org.apache.oltu.oauth2.client</artifactId>
    <version>1.0</version>
</dependency>

Build OAuth End User Authorization Request

Create the End User Authorization Request by providing end-user authorization URI at the Authorization Server (e.g. Facebook), your application's client id and a redirect URI, in order to receive the authorization code.

         OAuthClientRequest request = OAuthClientRequest
            .authorizationProvider(OAuthProviderType.FACEBOOK)
            .setClientId("your-facebook-application-client-id")
            .setRedirectURI("http://www.example.com/redirect")
            .buildQueryMessage();

If the token Provider is not in the OAuthProviderType Enum you can manually set the correct endpoints. The Enum is merely a convenience to easily set the OAuth endpoints. The Code example below show how you can manually set the authorization endpoint.

         OAuthClientRequest request = OAuthClientRequest
            .authorizationLocation("https://graph.facebook.com/oauth/authorize")
            .setClientId("your-facebook-application-client-id")
            .setRedirectURI("http://www.example.com/redirect")
            .buildQueryMessage();

The above code will produce an OAuth request where all the parameters are encoded in the URL query. You can obtain the generated URL by calling this method:

         request.getLocationUri();

For example, in a Java Servlet, you would execute the following code:

protected void doGet(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
throws ServletException, IOException {


   OAuthClientRequest request;

   // ... omitted code ...

   servletResponse.sendRedirect(request.getLocationUri());

}

The user is redirected to Facebook (the authorization page, to be exact), which asks the user which permission they would like to grant to your application. The user simply needs to click Allow.

Get Authorization Code from redirect URI

After the user grants permission for your client application, then Facebook redirects the user to: http://www.example.com/redirect (recall step Step 2), with request parameter similar to: code=2.89e3QEvryHUOHPe9YMqpeA__.3600.1285585200-1556050396|5CUsytnAALwWALAUUM8KHlJVNpQ

OAuthAuthzResponse oar = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
String code = oar.getCode();

Exchange OAuth code for an access token

OAuthClientRequest request = OAuthClientRequest
                .tokenProvider(OAuthProviderType.FACEBOOK)
                .setGrantType(GrantType.AUTHORIZATION_CODE)
                .setClientId("your-facebook-application-client-id")
                .setClientSecret("your-facebook-application-client-secret")
                .setRedirectURI("http://www.example.com/redirect")
                .setCode(code)
                .buildQueryMessage();

            //create OAuth client that uses custom http client under the hood
            OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

            //Facebook is not fully compatible with OAuth 2.0 draft 10, access token response is
            //application/x-www-form-urlencoded, not json encoded so we use dedicated response class for that
            //Custom response classes are an easy way to deal with oauth providers that introduce modifications to
            //OAuth 2.0 specification
            GitHubTokenResponse oAuthResponse = oAuthClient.accessToken(request, GitHubTokenResponse.class);

            String accessToken = oAuthResponse.getAccessToken();
            String expiresIn = oAuthResponse.getExpiresIn();

If the token Provider is not in the OAuthProviderType Enum you can manually set the correct endpoints. The Enum is merely a convenience to easily set the OAuth endpoints. The Code example below show how you can manually set the token endpoint.

OAuthClientRequest request = OAuthClientRequest
                .tokenLocation("https://graph.facebook.com/oauth/access_token")
                .setGrantType(GrantType.AUTHORIZATION_CODE)
                .setClientId("your-facebook-application-client-id")
                .setClientSecret("your-facebook-application-client-secret")
                .setRedirectURI("http://www.example.com/redirect")
                .setCode(code)
                .buildQueryMessage();
...

 

Now you can store the accessToken and an optional refreshToken and retrieve user data.

Below is an example to get a Facebook profile with the retrieved accessToken.

OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest("https://graph.facebook.com/me")
         .setAccessToken(accessToken).buildQueryMessage();

OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
 

Below is an example to post a picture to Facebook with the retrieved accessToken.

OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest("https://graph.facebook.com/{album-id}/photos")
         .setAccessToken(accessToken)
         .buildQueryMessage();

bearerClientRequest.setHeader(OAuth.HeaderType.CONTENT_TYPE, "multipart/form-data");
bearerClientRequest.setBody(photo);

OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.POST, OAuthResourceResponse.class);

For the fully working code see OAuth 2.0 client demo included in the package!

Enjoy!

Additional features

Provide custom response readers

Oltu is extensible and you can provide your own custom response classes that can handle responses from providers that introduce modifications to the core OAuth 2.0 specification. For example, you providers can read access tokens from
application/x-www-form-urlencoded instead of json encoded body.

Just create your own class that extends:

org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse

and pass it as one of the

oAuthClient.accessToken();

parameters.

Use your own HTTP client

OAuthClient can use different java http clients with customized configurations like timeouts, connection pools, etc. in order communicate with authorization servers and receive access tokens.
Oltu provides an exemplar implementation of the URLConnection client and Apache's HttpClient 4.

You can easily write your own HTTP client by extending:

org.apache.oltu.oauth2.client.HttpClient
  • No labels

4 Comments

  1. In the "Exchange OAuth code for an access token" caption we have:

    OAuthClientRequest request = OAuthClientRequest
    .tokenLocation("https://graph.facebook.com/oauth/access_token")
    .setGrantType(GrantType.AUTHORIZATION_CODE)
    .setClientId("your-facebook-application-client-id")
    .setClientSecret("your-facebook-application-client-secret")
    .setRedirectURI("http://www.example.com/redirect")
    .setCode(code)
    .buildBodyMessage();

    But is not working after implementing if you don't use .buildQueryMessage();.

    Let me know if I'm not right! (smile)

    Enjoy.

    1. I have updated the page with your finding. Also changed the maven artifacts location (smile)

  2. In the AuthZ request
    .authorizationLocation("https://graph.facebook.com/oauth/authorize")
    can be replaced with
    .authorizationProvider(OAuthProviderType.FACEBOOK)

    In the access token request
    .tokenLocation("https://graph.facebook.com/oauth/access_token")
    can be replaced with
    .tokenProvider(OAuthProviderType.FACEBOOK)

    I guess the OAuthProviderType enum was added later.