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
4 Comments
Francisco Ferri
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!
Enjoy.
Stein Welberg
I have updated the page with your finding. Also changed the maven artifacts location
Jasha Joachimsthal
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.
Stein Welberg
Done!