Acquiring access token using MSAL for JAVA
Tobias Kuess
26
Reputation points
Hello,
we used ADAL 4J for a couple of years now and it worked fine. Now we're migrating to MSAL. Our flow is:
- Acquire Token using Username & Password via PublicClientApplication
- Use the token to get User related information via Graph API and I can't get it to work because it always throws the following error: java.lang.ClassCastException: java.util.Collections$SingletonList (loaded by <bootstrap>) cannot be cast to java.lang.String (loaded by <bootstrap>)
at com.nimbusds.oauth2.sdk.util.URLUtils.serializeParameters(URLUtils.java:105)
at com.microsoft.aad.msal4j.TokenRequestExecutor.createOauthHttpRequest(TokenRequestExecutor.java:57)
at com.microsoft.aad.msal4j.TokenRequestExecutor.executeTokenRequest(TokenRequestExecutor.java:35)
at com.microsoft.aad.msal4j.AbstractClientApplicationBase.acquireTokenCommon(AbstractClientApplicationBase.java:128)
at com.microsoft.aad.msal4j.AcquireTokenByAuthorizationGrantSupplier.execute(AcquireTokenByAuthorizationGrantSupplier.java:63)
at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:69)
at com.microsoft.aad.msal4j.AuthenticationResultSupplier.get(AuthenticationResultSupplier.java:18)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
at java.lang.Thread.run(Thread.java:838)
That happens when IAuthenticationResult.get() is called. This is the code snipped which is used to aquire the token:
private static IAuthenticationResult getAccessTokenFromUserCredentials(String username, String password) throws Exception {
IAuthenticationResult result;
UserNamePasswordParameters parameters = UserNamePasswordParameters.builder(Collections.singleton("User.Read"), username, password.toCharArray()).build();
PublicClientApplication application = PublicClientApplication.builder(clientId).build();
result = application.acquireToken(parameters).get();
if (result == null) {
throw new ServiceUnavailableException("authentication result was null");
}
return result;
}
Is there anything obvious I am missing?
EDIT:
updated code snipped based on github example:
try {
SilentParameters silentParameters =
SilentParameters
.builder(Collections.singleton("User.Read"))
.account(account)
.build();
// Try to acquire token silently. This will fail on the first acquireTokenUsernamePassword() call
// because the token cache does not have any data for the user you are trying to acquire a token for
result = pca.acquireTokenSilently(silentParameters).join();
LOGGER.debug("AzureAPI | AuthenticationService | getAccessTokenFromUserCredentials | acquireTokenSilently call succeeded");
} catch (Exception ex) {
if (ex.getCause() instanceof MsalException) {
System.out.println("==acquireTokenSilently call failed: " + ex.getCause());
UserNamePasswordParameters parameters =
UserNamePasswordParameters
.builder(Collections.singleton("User.Read"), username, password.toCharArray())
.build();
// Try to acquire a token via username/password. If successful, you should see
// the token and account information printed out to console
result = pca.acquireToken(parameters).join();
LOGGER.debug("AzureAPI | AuthenticationService | getAccessTokenFromUserCredentials | username/password flow succeeded");
} else {
// Handle other exceptions accordingly
throw ex;
}
}
return result;
Sign in to answer