I have high volume multi threaded java based application which needs to call REST based endpoints running on Microsoft cloud with Authorization token in the header retrieved using "Azure ADAL AcquireToken". I am using "AzureAD/azure-activedirectory-library-for-java" (Code sample below). Questions I have are -
- Do I need to make a call to retrieve the token using acquireToken method for each and every REST call I am going to make? If yes, then I believe the token I am going to get with latest call may change, then in that case are the requests if I have requests already made with previously retrieved tokens going to fail or Azure ADAL will still going to honor all the previously generated tokens?
- If token retrieved previously are not expected to be honored by Azure ADAL then what options I have to manage single token at a time and then making sure at a time only one token is used by all the requests? Do I need to implement some kind of single threaded cache to retrieve a token, maintain that token until it expires, make a call to get new token if expired and make all my multi threaded requests go through this single threaded cache to get the latest token? Any suggestions on this. If this is the case then its seems like a huge bottleneck in high volume multi threaded multi jvm application as far as scalability goes.
My code below. When I called the acquireToken method from a loop inside the main method, I mostly got 3 different types of token in 10 calls and all 3 different tokens seemed to work, but not sure if that how it should be called in a multi threaded applications.
package com.mycompany.msft.auth;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;
public class ApplicationAuthExample {
private final static String AUTHORIZATION_ENDPOINT = "https://login.microsoftonline.com/";
private final static String ARM_ENDPOINT = "https://myendpoint";
private static String credential = "my credential";
private static String clientId = "my client id";
private static String tenantId = "my tenant id";
private static String url = AUTHORIZATION_ENDPOINT + tenantId ;
AuthenticationContext context = null;
AuthenticationResult result = null;
ExecutorService service = null;
public AuthenticationResult getAuthToken() {
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(url, false, service);
Future<AuthenticationResult> future = null;
ClientCredential cred = new ClientCredential(clientId, credential);
future = context.acquireToken(ARM_ENDPOINT, cred, null);
result = future.get();
} catch (Exception ex) {
System.out.println("Exception occurred:");
ex.printStackTrace();
System.exit(1);
} finally {
service.shutdown();
}
return result;
}
public static void main(String[] args) throws Exception {
ApplicationAuthExample auth = new ApplicationAuthExample();
for (int i =0 ; i< 10 ; i++) {
AuthenticationResult result = auth.getAuthToken();
// use adal to Authenticate
System.out.println (i+ " Authorization" + "Bearer " + result.getAccessToken());
System.out.println (i + " getExpiresOn" + result.getExpiresOn());
//This token comes different in different calls. Which one should I use and which one not.
System.out.println (i+ " getExpiresOn" + result.getRefreshToken());
System.out.println (i+" getExpiresOn" + result.getUserInfo());
}
}
}