-
Notifications
You must be signed in to change notification settings - Fork 111
API Wiki
AuthenticationContext is a point of entry Class in the ADAL library. It handles all the initialization, token access,
token refresh and caching logic. Authentication Context can be initialized like below
mAuthContext = new AuthenticationContext(getApplicationContext(), AUTHORITY_URL,
false);Explanation of the parameters
-
context: Application Context of the host app -
authority: A URL indicating a directory that AADL can use to obtain tokens. In Azure AD it is of the form https://<[instance]/[tenant], where [instance] is the directory host (e.g. https://login.microsoftonline.com) [tenant] is an identifier within the directory itself (e.g. a domain associated to the tenant, such as contoso.onmicrosoft.com, or the GUID representing the TenantID property of the directory). -
validateAuthority: Validates authority before sending the request if set to true. -
tokenCacheStore: Optional parameter for the app to pass in its ownITokenCacheStoreto store tokens.
acquireToken - This method can be called using the AuthenticationContext instance to acquire tokens interactively. It
starts an interactive flow with the user if a valid/unexpired token is not present in the cache. acquireToken can be
invoked like below:
mAuthContext.acquireToken(MainActivity.this, RESOURCE_ID, CLIENT_ID, REDIRECT_URI, PromptBehavior.Auto, getAuthInteractiveCallback());Explanation of the parameters
-
activity: The activity instance which is calling method. It is required to launch authentication activity -
resource: Theresourcefor which you want an access token. You should pass the Resource URI of the Web API you're trying to access. -
clientId: It is the application id of your public client application in the AzureAD Portal -
redirectUri: Optional parameter. If not defined on your application, you can set it up as your packagename. -
loginHint: Optional parameter ifvalidateAuthorityis false. This parameter will be used to pre-populate the username field in the authentication form. -
extraQueryParameters: Optional parameter. This will be appended as a query string in the HTTP authentication request to the authority. -
prompt: Optional parameter added as a query parameter to authorization url. Default value isPromptBehavior.Auto.The following table summarizes the usage of the acceptedpromptvalues.Prompt behavior Description Auto ADAL will prompt the user for credentials only when necessary. Always The user will be prompted for credentials even if it is available in the cache or in the form of refresh token. REFRESH_SESSION Re-authorizes (through displaying webview) the resource usage, making sure that the resulting access token contains the updated claims. FORCE_PROMPT If Azure Authenticator or Company Portal is installed, this flag will have the broker app force the prompt behavior, otherwise it will be same as Always. -
callback: Application needs to implement theAuthenticationCallback<AuthenticationResult>to use the result in it's context.AuthenticationCallbackcan be defined like below.
private AuthenticationCallback<AuthenticationResult> getAuthInteractiveCallback() {
return new AuthenticationCallback<AuthenticationResult>() {
@Override
public void onSuccess(AuthenticationResult authenticationResult) {
if(authenticationResult==null || TextUtils.isEmpty(authenticationResult.getAccessToken())
|| authenticationResult.getStatus()!= AuthenticationResult.AuthenticationStatus.Succeeded){
Log.e(TAG, "Authentication Result is invalid");
return;
}
/* Successfully got a token, call graph now */
Log.d(TAG, "Successfully authenticated");
Log.d(TAG, "ID Token: " + authenticationResult.getIdToken());
/* Store the auth result */
mAuthResult = authenticationResult;
/* Store User id to SharedPreferences to use it to acquire token silently later */
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
preferences.edit().putString(USER_ID, authenticationResult.getUserInfo().getUserId()).apply();
}
@Override
public void onError(Exception exception) {
/* Failed to acquireToken */
Log.e(TAG, "Authentication failed: " + exception.toString());
if (exception instanceof AuthenticationException) {
ADALError error = ((AuthenticationException)exception).getCode();
if(error==ADALError.AUTH_FAILED_CANCELLED){
Log.e(TAG, "The user cancelled the authorization request");
}
}
}
};
}-
fragment: If the authentication logic is implemented in a Fragment, it needs to be wrapped inIWindowComponentand should be passed in as a parameter using a utility method like below
private IWindowComponent wrapFragment(final Fragment fragment){
return new IWindowComponent() {
Fragment refFragment = fragment;
@Override
public void startActivityForResult(Intent intent, int requestCode) {
refFragment.startActivityForResult(intent, requestCode);
}
};
}NOTE: In releases 1.13.2, 1.13.3, and 1.14.0 the onError(Exception) and onSuccess(AuthenticationResult) callbacks may not be invoked on the UI thread. This issue is tracked here.
To acquire tokens from the cache you can use either of following methods below
-
acquireTokenSilentSync- Acquires token from the cache synchronously.mAuthContext.acquireTokenSilentSync(RESOURCE_ID, CLIENT_ID, userId);
-
acquireTokenSilentASync- Acquires token from the cache asynchronously.mAuthContext.acquireTokenSilentAsync(RESOURCE_ID, CLIENT_ID, userId, getAuthSilentCallback());
Explanation of the parameters
-
resource: Theresourcefor which you want an access token. You should pass the Resource URI of the Web API you're trying to access. -
clientId: It is the application id of your public client application in the AzureAD Portal -
userId:UserIdobtained fromUserInfoinside theAuthenticationResultreturned fromacquireTokencall. -
callback: Application needs to implement theAuthenticationCallback<AuthenticationResult>to use the result in it's context.AuthenticationCallbackcan be defined like below.private AuthenticationCallback<AuthenticationResult> getAuthSilentCallback() { return new AuthenticationCallback<AuthenticationResult>() { @Override public void onSuccess(AuthenticationResult authenticationResult) { if(authenticationResult==null || TextUtils.isEmpty(authenticationResult.getAccessToken()) || authenticationResult.getStatus()!= AuthenticationResult.AuthenticationStatus.Succeeded){ Log.d(TAG, "Silent acquire token Authentication Result is invalid, retrying with interactive"); /* retry with interactive */ mAcquireTokenHandler.sendEmptyMessage(MSG_INTERACTIVE_SIGN_IN); return; } /* Successfully got a token, call graph now */ Log.d(TAG, "Successfully authenticated"); /* Store the mAuthResult */ mAuthResult = authenticationResult; } @Override public void onError(Exception exception) { /* Failed to acquireToken */ Log.e(TAG, "Authentication failed: " + exception.toString()); if (exception instanceof AuthenticationException) { AuthenticationException authException = ((AuthenticationException) exception); ADALError error = authException.getCode(); logHttpErrors(authException); /* Tokens expired or no session, retry with interactive */ if (error == ADALError.ERROR_SILENT_REQUEST || error == ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED || error == ADALError.INVALID_TOKEN_CACHE_ITEM) { mAcquireTokenHandler.sendEmptyMessage(MSG_INTERACTIVE_SIGN_IN); } return; } /* Attempt an interactive on any other exception */ mAcquireTokenHandler.sendEmptyMessage(MSG_INTERACTIVE_SIGN_IN); } }; }
Both the acquireToken and acquireTokenSilent(...) calls pass back an AuthenticationResult which the following information wrapped in it.
-
AccessToken: Token to access the WEB API. This is a string, usually a base64 encoded JWT but the client should never look inside the access token. -
RefreshToken: A token to get newAccessTokenon expiry. -
ExpiresOn: date/time when the token expires -
TenantId: Contains the tenant in which the user was found -
AccessTokenType: Access token type , usually "Bearer" for Azure AD tokens. -
ExtendedLifeTimeToken: boolean indicating if the token is valid in terms of extended lifetime. -
Authority: TheAuthoritywhich has delivered the token. -
ErrorCode,ErrorLogInfo,ErrorDescription: Error information in case of an error -
IdToken: Information about theUser -
UserInfo:The information about the user is exposed through the UserInfo class which has the following information- A
unique Idfor the user in the identity provider. - A
displayable Idfor the user - The user's
family name - The user's
given name - The
identity providerholding the user identify. - The
password expirationdate for the user. This can be null. -
password change URI. This can be null
- A
ADAL provides Default cache in SharedPreferences with some simple cache query functions. You can get the current cache from AuthenticationContext like below
ITokenCacheStore cache = mContext.getCache();
# You can also provide your cache implementation, if you want to customize it.
mContext = new AuthenticationContext(MainActivity.this, authority, true, yourCache);ADAL by default sets a requestCorrelationId for every request to identify the request for Telemetry and Logging purposes. This is generated using java UUID.randomUUID method. Application developer can set their own requestCorrelationId like below
mAuthContext.setRequestCorrelationId(new UUID(data))- Error Handling
- Auth Telemetry
- Logging
- Doze and App Standby
- ProGuard
- Session Cookies in WebView
- Resource Overrides