Building the OAuth 2.0 client using Jersey APIs

Let's build a simple OAuth 2.0 client using Jersey APIs to understand the API usage pattern.

The complete source code for this example is available on the Packt website. You can download the example from the Packt website link that we mentioned at the beginning of this book, in the Preface section. In the downloaded source code, take a look at the rest-chapter6-oauth2-webclient project.

To use the Jersey OAuth 2.0 client APIs in your application, you need to add a dependency to the oauth2-client JAR file. If you use Maven, the dependency entry in pom.xml may look as shown in the following lines:

<dependency> 
  <groupId>org.glassfish.jersey.security</groupId> 
  <artifactId>oauth2-client</artifactId> 
  <!-- specify appropriate version(2.26-b09) --> 
<version>${jersey.version}</version> </dependency>
The Jersey framework (version 2.26.x), which is the latest release available at the time of writing this book, does not offer any server APIs for protecting services via the OAuth 2.0 protocol. 

As OAuth 2.0 is not a strictly defined protocol, you may not find a generic client API solution that works with all the implementations of OAuth 2.0 (by different vendors). The org.glassfish.jersey.client.oauth2.OAuth2ClientSupport class is the main starting class for an OAuth 2.0 client. You will use this as the starting class for building the OAuth 2.0 authorization flow. The current release of the OAuth2ClientSupport class (version 2.26.x) provides dedicated methods for building the authorization grant flow for accessing the OAuth 2.0 protected RESTful web APIs from vendors such as Google and Facebook. The following are the steps for building a Jersey client for Google Tasks APIs:

  1. To start with the authorization code grant flow, generate an instance of org.glassfish.jersey.client.oauth2.ClientIdentifier by passing the client ID and client secret obtained from the service provider (authorization server). This is usually obtained while registering the client with the server. This example accesses the Google Tasks API to read the tasks. Remember that the Jersey OAuth 2.0 client supports only the authorization code grant type, and so, this example also uses the same type.
The following link will help you with details for accessing the OAuth 2.0 protected Google APIs:
https://developers.google.com/identity/protocols/OAuth2.

High-level steps for obtaining the client ID and client secret are available at https://support.google.com/cloud/answer/6158849?hl=en.
  1. Once you have the ClientIdentifier instance ready, the next step is to start building the authorization code grant flow for accessing the Google Tasks API by calling the googleFlowBuilder() method. This method has the following signature:
OAuth2ClientSupport::googleFlowBuilder( 
   ClientIdentifier clientIdentifier, String redirectURI, 
  String scope)  
  1. This call returns the org.glassfish.jersey.client.oauth2.OAuth2FlowGoogleBuilder object that can be directly used to generate the authorization code grant flow defined by Google. Here is the quick summary of parameters for the googleFlowBuilder method:
    • clientIdentifier: This is the ClientIdentifier instance created using the client ID and client secret issued by the service provider.
    • redirectURI: This is the URI to which the user (the resource owner) should be redirected to after the user grants access to the consumer application. It will pass null if the application does not support redirection (for example, if it is not a web application).
    • Scope: This is the API to which access is requested (for example, Google Tasks).
  1. To start the authorization flow, get an instance of org.glassfish.jersey.client.oauth2.OAuth2CodeGrantFlow by calling the build() method on OAuth2FlowGoogleBuilder. The OAuth2CodeGrantFlow instance is capable of authorizing the user using the Authorization Code Grant Flow. The following code snippet demonstrates the API usage for generating OAuth2CodeGrantFlow to access the Google Tasks API:
//Other imports are not shown for brevity 
import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport; 
import org.glassfish.jersey.client.oauth2.OAuth2CodeGrantFlow; 
import org.glassfish.jersey.client.oauth2.OAuth2FlowGoogleBuilder; 
import org.glassfish.jersey.client.oauth2.ClientIdentifier; 
import org.glassfish.jersey.client.oauth2.TokenResult; 
 
final String CLIENT_ID =  "xxxxx"; 
final String CLIENT_SECRET = "xxxxxx"; 
//Protected ApI that needs to be accessed by client app 
String SCOPE = "https://www.googleapis.com/auth/tasks.readonly"; 
 
//On successful authorization user  
//is redirected to this URI 
String redirectURI =   
    "http://localhost:8080/hrapp/api/oauth2/authorize"; 
 
ClientIdentifier clientIdentifier = new  
    ClientIdentifier(CLIENT_ID, CLIENT_SECRET); 
final OAuth2CodeGrantFlow oauth2CodeGrantflow =  
    OAuth2ClientSupport.googleFlowBuilder( 
        clientIdentifier,  redirectURI, SCOPE)  
           .prompt(OAuth2FlowGoogleBuilder.Prompt.CONSENT) 
           .build(); 
  1. The OAuth2CodeGrantFlow instance is ready for use by now. Let's start the authorization process. The OAuth2CodeGrantFlow object defines the OAuth 2.0 authorization code grant flow for the client. You can start the flow by calling the start() method:
//Get the authorization URI 
String authorizationUri = oauth2CodeGrantflow.start(); 

This call triggers the authorization process and returns an authorization URI on which the user should give consent to our application to access the resources. The client application should redirect the user to the authorization URI. The resource owner should authorize the client application on the authorization URI to proceed further. On successful authorization, the authorization server automatically redirects the user back to the redirect URI specified while building OAuth2CodeGrantFlow. The authorization server also provides the code and state as a request query parameter for the redirect URI. The client application needs to extract the code and state parameters from the request to use them with the access token request. The state parameter is used for preventing cross-site request forgery. It is added to the redirect URI in the start method; the same parameter should be returned from the authorization response as a protection against CSRF attacks.

  1. To finish the authorization process, call OAuth2CodeGrantFlow::finish(String code, String state) by supplying the code and state returned by the authorization server on authorization. The method will internally request the access token from the authorization server and return the result as a TokenResult object. The TokenResult object contains the result of the authorization flow, including the access token.
  2. Later, you can call OAuth2CodeGrantFlow::getAuthorizedClient() to get the JAX-RS client, which is configured to perform authorized requests to the service provider. The returned JAX-RS client has all the necessary information about the consumer credentials and access token that were received during the authorization process. You can directly use this client to access the protected resources. The following code snippet illustrates the usage of client APIs, as explained in steps 5-6:
//Step 5: code and state are returned by authorization server 
TokenResult tokenResult = oauth2CodeGrantflow.finish(code, state); 
//Step 6: Get the authorized client  
Client client = oauth2CodeGrantflow.getAuthorizedClient(); 
String GOOGLE_TAKS_URI =  
    "https://www.googleapis.com/tasks/v1/users/@me/lists"; 
//Prepare client to call Google Tasks API 
WebTarget service = client.target(GOOGLE_TAKS_URI); 
//Get the response object and work on it 
Response response =  service.request().get(); 
if(response.getStatus() == 200){ 
//Code for processing response such as building  
//Java model etc goes here 
   String output = response.getEntity(String.class); 
} 

With this, we have finished the discussion on OAuth. In the next section, you will learn how to control access to RESTful resources via security APIs.

Building OAuth 2.0 compliant services
If you feel that the support for OAuth in the current Jersey release is not enough to meet your use cases, you can look into other OAuth implementations available in Java. Apache Oltu is one such popular OAuth protocol implementation available today. You can learn more about Apache Oltu at https://oltu.apache.org.

Note that the Jersey framework (version 2.26.x), which is the latest release available at the time of writing this book, does not offer any server API for protecting your RESTful web services via OAuth 2.0. However, with Oltu, you can easily create OAuth 2.0-compliant server endpoints. More details can be found at https://cwiki.apache.org/confluence/display/OLTU/OAuth+2.0+Authorization+Server.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.8.8