How to using JWT based Authentication with RingCentral APIs in a Spring Boot App
Tags: ringcentral, java, springboot, security
Published: 2022-06-22 22:33:55

Modern Java enterprise applications such as Spring Boot Java apps connect with multiple services (1st party, 2nd party, and 3rd party) all the time to deliver value to the enterprise users. 

One of the key concerns of an enterprise developer/architect is ensuring the integrity and security of the application and users, especially when they are using 3rd party services via REST APIs & SDKs. 

In this article, we will understand how to connect to RingCentral's open platform and authenticate against the same in a simple SpringBoot application using OAuth 2.0 Client Authentication with JWT Grant Type.

## OAuth 2.0 JWT Grant Type Overview

**Authentication with JWT**

[JWT](https://datatracker.ietf.org/doc/html/rfc7519) stands for JSON Web Token, which is essentially a JSON format that looks like an encoded string and carries secure information. This makes it ideal for performing authentication of users/developers that have signed up to use 3rd party APIs. Therefore, it becomes vital to secure JWT's in a safe place.

JWT Credentials do not expire by default (however you can set them to time out if needed), they are immutable but can be revoked by the owner and are generally bound to the environment/application for which they're created.

**Authorization with OAuth 2.0**

JWT is often combined with OAuth 2.0, which is a popular protocol over HTTPS to authorize APIs, applications and users with access tokens rather than credentials. 

It is import realize that the JWTs are not used directly to call the API. Instead, a JWT is used in the process of obtaining an access token which is itself then used to call the API. This is why securing JWT token string in a safe place is of vital importance.

For purpose of understanding these concepts,  I've created a sample SpringBoot application that you can clone from [GitHub](https://github.com/suyashjoshi/ringcentral-springboot). It incorporates the JWT Auth 2.0 flow using RingCentral's Java SDK. Follow the instructions in the project's README to install the pre-requisites and run the project.

**When should I use a JWT for authentication?**

Using a JSON Web Token for app authentication is ideal in the following circumstances:

- Backend Logic: There is no user interface through which to facilitate the OAuth auth token flow. 

- No Expiration of Tokens: You need a way for users to grant access to their accounts using a credential that doesn't expire.

- No Refreshing of Tokens: You need a way to access an account that doesn't rely on token refreshing.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdrlcwbj1nbq7driwj52.png)

**How does JWT work with OAuth 2.0 in SpringBoot App connected to RingCentral Platform?**

1. The developer generates a JWT (JSON Web Token) from RingCentral. You can refer to [this guide](https://developers.ringcentral.com/guide/authentication/jwt/create-jwt) for step-by-step instructions.

2. The developer provides the JWT Credential programmatically by calling the RingCentral platform - Auth API. Once successfully authenticated and authorized, the API responds with an "Access Token".

3. The application then presents the "Access Token" to access resource server APIs, in this case, call various RingCentral Platform APIs for which the application has been granted permissions.

The API calls for performing OAuth via RingCentral platform services can be easily done by using RingCentral's Java SDK that can be downloaded from [maven central](https://search.maven.org/artifact/com.ringcentral/ringcentral).

The sample [Spring Boot App](https://github.com/suyashjoshi/ringcentral-springboot) is kept simple so we can focus on two key classes - `AuthClient.java` and `RingCentralController.java` to see how the OAuth Flow with JWT works.

**AuthClient.java**

```
@Component
public class AuthClient {

  // Credentials should be privately secured separately, in this demo app they are in 'application.properties' file
  private static String RINGCENTRAL_CLIENT_ID;
  private static String RINGCENTRAL_CLIENT_SECRET;
  private static String RINGCENTRAL_JWT;

  // Using RingCentra Sandbox URL, replace with the Production URL for Production Credentials
  private static String RINGCENTRAL_SERVER_URL = "https://platform.devtest.ringcentral.com";

  @Value("${rc.clientid}")
  private void setClientID(String id) {
    RINGCENTRAL_CLIENT_ID = id;
  }
  @Value("${rc.clientsecret}")
  private void setClientSecret(String secret) {
    RINGCENTRAL_CLIENT_SECRET = secret;
  }
  @Value("${rc.jwt}")
  private void setJWT(String jwt) {
    RINGCENTRAL_JWT = jwt;
  }

  public void AuthClient() {
    this.setClientID(RINGCENTRAL_CLIENT_ID);
    this.setClientSecret(RINGCENTRAL_CLIENT_SECRET);
    this.setJWT(RINGCENTRAL_JWT);
  }

  // Connect with RingCentral Platform and return the RestClient object
  public static RestClient authenticate() throws IOException, RestException {
    RestClient rc = new RestClient(RINGCENTRAL_CLIENT_ID, RINGCENTRAL_CLIENT_SECRET, RINGCENTRAL_SERVER_URL);
    rc.authorize(RINGCENTRAL_JWT);
    return rc;
  }
}
```


**RingCentralController.java**

After having setup up Authentication and Authorization, we call the RingCentral Platform API to read the Account Status of the logged-in user.

```
@Controller
public class RingCentralController {
  
  @RequestMapping("/account")
  @ResponseBody
  public String getRCAccountInfo() {
    try {
      RestClient rc = AuthClient.authenticate();
      GetAccountInfoResponse result = rc.restapi().account().get();
      return result.status;
    } 
    catch (IOException | RestException e) {
      e.printStackTrace();
      return("Error Occured!");
    }
  }
}
```

Compile and Run the app **./mvnw spring-boot:run** and then open your web browser to **localhost:8080/account** to see the API result 'Confirmed' demonstrating a successful API Call. 

Hope this helped you understand how JWT & OAuth goes hand in hand in a Spring Boot, especially with the help of RingCentral Java SDK which makes it easy to perform authentication, authorization, and calling various platform APIs. 

If you have any questions, please feel free to comment, tweet, or open GitHub issues.