Skip to content

Migrate to MSAL Java

Santiago Gonzalez edited this page Nov 7, 2019 · 13 revisions

Both Microsoft Authentication Library for Java (MSAL4J) and Azure AD Authentication Library for Java (ADAL4J) are used to authenticate Azure AD entities and request tokens from Azure AD. Up until now, most developers have worked with Azure AD for developers platform (v1.0) to authenticate Azure AD identities (work and school accounts) by requesting tokens using Azure AD Authentication Library (ADAL). Using MSAL:

  • You can authenticate a broader set of Microsoft identities (Azure AD identities and Microsoft accounts, and social and local accounts through Azure AD B2C) as it uses the Microsoft identity platform endpoint,
  • Your users will get the best single-sign-on experience.
  • Your application can enable incremental consent, and supporting conditional access is easier
  • You benefit from the innovation.

MSAL4J is now the recommended auth library to use with the Microsoft identity platform. No new features will be implemented on ADAL4J. All efforts will be towards improving MSAL.

Differences

If you are already familiar with the Azure AD for developers (v1.0) endpoint (and ADAL4J), you might want to read What's different about the Microsoft identity platform (v2.0) endpoint?.

Scopes not resources

ADAL4J acquires tokens for resources, but MSAL4J acquires tokens for scopes. A number of MSAL4J Parameter (UsernamePasswordParameters, ClientCredentialParameters, DeviceCodeFlowParameters, etc) classes require a parameter called scopes(Set<String> scopes). This parameter is a simple list of strings that declare the desired permissions and resources that are requested. Well known scopes are the Microsoft Graph's scopes.

Core classes

  • ADAL4J uses AuthenticationContext as the representation of your connection to the Security Token Service (STS) or authorization server, through an Authority. On the contrary, MSAL4J is designed around client applications. It provides two separate classes: PublicClientApplication and ConfidentialClientApplication

  • Acquiring Tokens:

ADAL4J method MSAL4J method
acquireToken(String resource, ClientCredential credential, AuthenticationCallback callback) acquireToken(ClientCredentialParameters)
acquireToken(String resource, ClientAssertion assertion, AuthenticationCallback callback) acquireToken(ClientCredentialParameters)
acquireToken(String resource, AsymmetricKeyCredential credential, AuthenticationCallback callback) acquireToken(ClientCredentialParameters)
acquireToken(String resource, String clientId, String username, String password, AuthenticationCallback callback) acquireToken(UsernamePasswordParameters)
acquireToken(String resource, String clientId, String username, String password=null, AuthenticationCallback callback) acquireToken(IntegratedWindowsAuthenticationParameters)
acquireToken(String resource, UserAssertion userAssertion, ClientCredential credential, AuthenticationCallback callback) acquireToken(OnBehalfOfParameters)
acquireTokenByAuthorizationCode() acquireToken(AuthorizationCodeParameters)
acquireDeviceCode() and acquireTokenByDeviceCode() acquireToken(DeviceCodeParameters)
acquireTokenByRefreshToken() acquireTokenSilently(SilentParameters)

IAccount not IUser

ADAL4J manipulated users. However, a user is a human or a software agent, but it can possess/own/be responsible for one or more accounts in the Microsoft identity system (several Azure AD accounts, Azure AD B2C, Microsoft personal accounts).

MSAL4J now defines the concept of Account (through the IAccount interface). This breaking change provides the right semantics: the fact that the same user can have several accounts, in different Azure AD directories. Also MSAL4J provides better information in guest scenarios, as home account information is provided.

Cache persistence

ADAL4J did not have support for token cache.

MSAL4J adds a token cache

Common Authority

In v1.0, if you use the https://login.microsoftonline.com/common authority, you will allow users to sign in with any AAD account (for any organization).

If you use the https://login.microsoftonline.com/common authority in v2.0, you will allow users to sign in with any AAD organization or a Microsoft personal account (MSA). In MSAL4J, if you want to restrict login to any AAD account (same behavior as with ADAL4J), you need to use https://login.microsoftonline.com/organizations. For details, see the authority parameter in public client application.

V1.0 and v2.0 tokens

There are two versions of tokens:

v1.0 tokens v2.0 tokens The v1.0 endpoint (used by ADAL) only emits v1.0 tokens.

However, the v2.0 endpoint (used by MSAL) emits the version of the token that the Web API accepts. A property of the application manifest of the Web API enables developers to choose which version of token is accepted. See accessTokenAcceptedVersion in the application manifest reference documentation.

For more information about v1.0 and v2.0 tokens, see Azure Active Directory access tokens

ADAL to MSAL migration

In ADAL4J the refresh tokens were exposed allowing you to develop solutions around the use of these tokens by caching them and using AcquireTokenByRefreshToken(). Some of those solutions were used in scenarios such as:

  • Long running services that do actions including refreshing dashboards on behalf of the users whereas the users are no longer connected.
  • WebFarm scenarios for enabling the client to bring the refresh token to the web service (caching is done client side, encrypted cookie, and not server side)

MSAL4J does not expose refresh tokens for security reasons. Instead, MSAL handles refreshing tokens for you.

Fortunately, MSAL4J has an API that allows you to migrate your previous refresh tokens (acquired with ADAL) 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 into your application.

This code snippet shows some migration code in a confidential client application.

String rt = GetCachedRefreshTokenForSIgnedInUser(); // Get refresh token from where you have them stored
Set<String> scope = Collections.singleton("SCOPE_FOR_REFRESH_TOKEN");

RefreshTokenParameters parameters = RefreshTokenParameters.builder(scopes, rt).build();

PublicClientApplication app = PublicClientApplication.builder(CLIENT_ID) // ClientId for your application
                .authority(AUTHORITY)  //plug in your authority
                .build();

IAuthenticationResult result = app.acquireToken(parameters);

You will see an access token and ID token returned in your IAuthenticationResult while your new refresh token is stored in the cache.

You will also see that the application now contains an IAccount.

Set<IAccount> accounts =  app.getAccounts().join();

When you'd like to use the tokens that are now in the cache, you can call:


SilentParameters parameters = SilentParameters.builder(scope, accounts.iterator().next()).build(); 
IAuthenticationResult result = app.acquireToken(parameters); 

Clone this wiki locally