DEV Community

loading...

A Token Management Implementation for Web API Authentication in Java

unhurried
Software Engineer in the Countryside in Japan Web / AuthN & AuthZ / Spring Framework / Vue.js / Java / JavaScript & TypeScript / Golang
・2 min read

This article studies an implementation of a synchronized process in Java that enables multiple threads to share same timed tokens, assuming access tokens in OAuth2, for Web API authentication.

Specification of Token Management

I assume the following specification for this token management system.

  • Multiple threads call Web APIs with the same token.
  • When a token expires, a thread that detects the expiration first will update the token.
  • During the update process, token retrievals from other threads needs to wait the completion of the update.

An Implementation in Java

The following is an implementation of the token management system described above.

public class TokenManager {

  // Singleton Pattern
  private static TokenManager instance = new TokenManager();
  private TokenManager() {}
  public static TokenManager getInstance() {
    return instance;
  }

  /* Set "volatile" to variables for token and update time so that any
     threads can retrieve the up-to-date state of the variables. */
  // Timed token
  private volatile String token = null;
  // Update time calcurated from TTL of the token
  private volatile long refreshAt = 0L;

  // getToken doesn't need "synchronized" as any threads can retrieve
  //  the up-to-date token with the aid of "volatile" keyword.
  public String getToken() {
    if (System.currentTimeMillis() >= refreshAt) {
      syncUpdateToken();
    }
    return this.token;
  }

  // Make the method "synchronized" so that only one thread can
  // execute it in time.
  private synchronized void syncUpdateToken() {
    // Prevent subsequents threads that call getToken method during
    // the token update from updating the token again.
    if (System.currentTimeMillis() < refreshAt) {
      return;
    }

    // Token Update Process
    // Update "token" before "refreshAt" as "refreshAt" is used
    // first in getToken method to check the token expiration.
    this.token = ...
    this.refreshAt = ...
  }
}
Enter fullscreen mode Exit fullscreen mode

By making instance variables (token and refreshAt) "volatile", getToken method doesn't need "synchronized", which enables parallel execution of token retrievals while the token is valid.

Note that results in subsequent threads invoking updateToken method, thus token expiration check is also needed in updateToken to prevent unnecessary token updates.

Discussion (0)