0
votes

I am trying to migrate my existing acquire token implementation from ADAL to MSAL. I am able to get the access token and the grant_type=auth_code flow is working fine.

But the issue comes when I am trying to implement the grant_type=refresh_token with scope as offline_access, even though I am able see the refresh_token while debugging the code but since MSAL does not expose refresh_token to the client I do not get that as part of my response.

As per MSAL documentation it says that we should use acquireTokenSilently to get the token once it is expired.

In this link ADAL to MSAL Migration it says that

MSAL for Java has an API that allows you to migrate refresh tokens you acquired with ADAL4j into the ClientApplication: acquireToken(RefreshTokenParameters). With this method, you can provide the previously used refresh token along with any scopes (resources) you desire. The refresh token will be exchanged for a new one and cached for use by your application.

So I am confused with the above line since MSAL will not expose refresh_token how can we create RefreshTokenParameter.

Also I have a use case where I do need to send the refresh_token back to the client.

Can anyone help me by providing further guidance on this.

2

2 Answers

1
votes

The RefreshTokenParameter is created from the refresh token which is received from ADAL, not MSAL, the doc is clear.

MSAL for Java has an API that allows you to migrate refresh tokens you acquired with ADAL4j into the ClientApplication: acquireToken(RefreshTokenParameters).

Then after using the migration code here, you will get the new access token and ID token, and the new refresh token will be stored in the cache which is not exposed. So in your case, if you want to get the refresh token directly, you still need to use ADAL.

Not sure why you need this, because the effect of refresh token is to get the new access token/ID token, to achieve this, you can leverage the acquireTokenSilently in MSAL easily.

1
votes

In the package MSAL, it provides the feature token cache. It caches a token after it's been acquired. Then we can try to refresh the token silently from the cache with the method acquireTokenSilently.

For example

PublicClientApplication pca = PublicClientApplication.builder(CLIENT_ID)
                .authority(AUTHORITY)
                .build();
        Consumer<DeviceCode> deviceCodeConsumer = (DeviceCode deviceCode) ->
                System.out.println(deviceCode.message());
        // get token for graph
        DeviceCodeFlowParameters parameters =
                DeviceCodeFlowParameters
                        .builder(Collections.singleton("User.Read"), deviceCodeConsumer) 
                        .build();
        IAuthenticationResult result = pca.acquireToken(parameters).join();


        DecodedJWT jwt = JWT.decode(result.accessToken());
        System.out.println(jwt.getAudience().get(0));

        // refresh token
        Set<IAccount> accountsInCache = pca.getAccounts().join();

        IAccount account = accountsInCache.iterator().next();
        // get token for my own api
        SilentParameters silentParameters =
                SilentParameters
                        .builder(Collections.singleton("api://872ebcec-c24a-4399-835a-201cdaf7d68b/access_as_user"), account)
                        .build();
        result = pca.acquireTokenSilently(silentParameters).join();
        jwt = JWT.decode(result.accessToken());
        System.out.println(jwt.getAudience().get(0));

enter image description here

For more details, please refer to

https://docs.microsoft.com/en-us/azure/active-directory/develop/migrate-adal-msal-java#core-classes

https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#acquiring-tokens-silently-from-the-cache

https://github.com/Azure-Samples/ms-identity-java-devicecodeflow