### Example Reply/Redirect URI with Signature Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/sso Provides a concrete example of a reply/redirect URI for an Android application, demonstrating the inclusion of the package name and a Base64 URL encoded certificate fingerprint. ```text msauth://com.example.userapp/IcB5PxIyvbLkbFVtBI%2FitkW%2Fejk%3D ``` -------------------------------- ### Clone and Install ADAL Android Library Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Maven Clone the ADAL Android library repository and install it using Maven. This step assumes the Maven Android environment has been previously set up. ```shell git clone https://github.com/AzureAD/azure-activedirectory-library-for-android cd azure-activedirectory-library-for-android mvn clean install ``` -------------------------------- ### Clone and Install Android Maven SDK Deployer Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Maven Clone the Android Maven SDK Deployer repository and install specific platform and compatibility libraries. This makes Android SDK components available in your local Maven repository. ```shell git clone https://github.com/mosabua/maven-android-sdk-deployer.git cd maven-android-sdk-deployer/platforms/android-19 mvn clean install ``` ```shell cd ../../extras/compatibility-v4 mvn clean install -Dextras.compatibility.v4.groupid=com.android.support \ -Dextras.compatibility.v4.artifactid=support-v4 ``` -------------------------------- ### Acquire Token with Callback Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Request an access token using the acquireToken method, providing necessary parameters and the defined callback. This example is for an Activity context. ```java mContext.acquireToken(MainActivity.this, resource, clientId, redirect, user_loginhint, PromptBehavior.Auto, "", callback); ``` -------------------------------- ### Sample Key Generation for ADAL Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Common-Issues-With-AndroidKeyStore Example code demonstrating how to generate a 256-bit AES secret key using PBEWithSHA256And256BitAES-CBC-BC and set it for ADAL. Ensure the generated key is 32 bytes. ```java SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithSHA256And256BitAES-CBC-BC"); SecretKey generatedSecretKey = keyFactory.generateSecret(new PBEKeySpec(your_password, byte-code-for-your-salt, 100, 256)); SecretKey secretKey = new SecretKeySpec(generatedSecretKey.getEncoded(), algorithm); AuthenticationSettings.INSTANCE.setSecretKey(secretKey.getEncoded()); ``` -------------------------------- ### Example Reply/Redirect URI Format Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/sso Illustrates the format for configuring a reply/redirect URI in the Azure portal when using broker-assisted SSO. This format includes the package name and a Base64UrlEncoded signature derived from the certificate fingerprint. ```text msauth://packagename/Base64UrlEncodedSignature(Cert fingerprint) ``` -------------------------------- ### Initialize AuthenticationContext Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Instantiate an AuthenticationContext object in your main Activity. This example uses SharedPreferences for caching. ```java // Authority is in the form of https://login.windows.net/yourtenant.onmicrosoft.com mContext = new AuthenticationContext(MainActivity.this, authority, true); // This will use SharedPreferences as default cache ``` -------------------------------- ### Example Commit Log Structure Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/contributing.md Follow this structure for writing clear and informative commit messages. The header line should be concise, followed by a blank line, and then a detailed body wrapped at 72 columns. ```git fix: explaining the commit in one line Body of commit message is a few lines of text, explaining things in more detail, possibly giving some background about the issue being fixed, etc etc. The body of the commit message can be several paragraphs, and please do proper word-wrap and keep columns shorter than about 72 characters or so. That way `git log` will show things nicely even when it is indented. ``` -------------------------------- ### Acquire Token Interactively Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Call this method to initiate an interactive token acquisition flow. It starts a user-facing authentication process if a valid token is not found in the cache. ```java mAuthContext.acquireToken(MainActivity.this, RESOURCE_ID, CLIENT_ID, REDIRECT_URI, PromptBehavior.Auto, getAuthInteractiveCallback()); ``` -------------------------------- ### Set Android SDK Environment Variables Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Maven Configure environment variables to point to your Android SDK installation and its tools. This is necessary for Maven commands to locate SDK components. ```shell export ANDROID_HOME=/Applications/adt-bundle-mac-x86_64-20140702/sdk export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools:$ANDROID_HOME/platforms:$ANDROID_HOME/extras ``` -------------------------------- ### Initialize AuthenticationContext Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Initializes the AuthenticationContext with the application context, authority URL, and a boolean for authority validation. This is the primary way to start using the ADAL library for authentication. ```java mAuthContext = new AuthenticationContext(getApplicationContext(), AUTHORITY_URL, false); ``` -------------------------------- ### Get Broker Redirect URI Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Retrieves the specific redirect URI required for broker-based authentication. This URI is in the format msauth://packagename/Base64UrlencodedSignature and is crucial for broker integration. ```java String brokerRedirectUri = mContext.getBrokerRedirectUri(); ``` -------------------------------- ### acquireToken Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Acquires tokens interactively by starting an interactive flow if a valid token is not found in the cache. This method is called on an AuthenticationContext instance. ```APIDOC ## acquireToken ### Description This method is used to acquire tokens interactively. It initiates an interactive user flow if a valid or unexpired token is not present in the cache. It requires an `AuthenticationContext` instance to be called. ### Method Signature `acquireToken(activity, resource, clientId, redirectUri, prompt, callback, fragment)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters * `activity` (Activity): The activity instance initiating the call. Required for launching the authentication activity. * `resource` (String): The Resource URI of the Web API for which an access token is requested. * `clientId` (String): The application ID of the public client application registered in Azure AD. * `redirectUri` (String): Optional. If not defined in the application, this can be set to the application's package name. * `loginHint` (String): Optional. Used to pre-populate the username field in the authentication form, especially when `validateAuthority` is false. * `extraQueryParameters` (String): Optional. Appended as a query string to the HTTP authentication request to the authority. * `prompt` (PromptBehavior): Optional. A query parameter for the authorization URL. Defaults to `PromptBehavior.Auto`. Accepted values include `Auto`, `Always`, `REFRESH_SESSION`, and `FORCE_PROMPT`. * `callback` (AuthenticationCallback): An implementation of `AuthenticationCallback` to handle the result of the token acquisition. * `fragment` (IWindowComponent): Optional. If authentication logic is in a Fragment, it needs to be wrapped in `IWindowComponent` and passed here. ### Request Example ```java mAuthContext.acquireToken(MainActivity.this, RESOURCE_ID, CLIENT_ID, REDIRECT_URI, PromptBehavior.Auto, getAuthInteractiveCallback()); ``` ### Response #### Success Response An `AuthenticationResult` object containing the access token and other relevant information is provided to the `onSuccess` method of the `AuthenticationCallback`. #### Response Example ```java // Inside onSuccess(AuthenticationResult authenticationResult) if(authenticationResult==null || TextUtils.isEmpty(authenticationResult.getAccessToken()) || authenticationResult.getStatus()!= AuthenticationResult.AuthenticationStatus.Succeeded){ Log.e(TAG, "Authentication Result is invalid"); return; } Log.d(TAG, "Successfully authenticated"); Log.d(TAG, "ID Token: " + authenticationResult.getIdToken()); mAuthResult = authenticationResult; ``` #### Error Response An `Exception` is provided to the `onError` method of the `AuthenticationCallback` in case of failure. #### Error Response Example ```java // Inside onError(Exception exception) 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"); } } ``` ### Notes In releases 1.13.2, 1.13.3, and 1.14.0, the `onError` and `onSuccess` callbacks might not be invoked on the UI thread. This issue is tracked [here](https://github.com/AzureAD/azure-activedirectory-library-for-android/issues/1076). ``` -------------------------------- ### Sample Aggregated Telemetry Event Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Telemetry An example of an aggregated telemetry event, presented in JSON format. This data structure represents collapsed events per request when aggregation is enabled. ```json { "Microsoft.ADAL.correlation_id Value": "f50311ba-7b15-4a28-813b-2f4a77276826", "Microsoft.ADAL.is_frt": "", "Microsoft.ADAL.login_hint": "+soK2KCefj3mxyJKdO8Z8knXq5jDyp1vaFqgGXoXPlI=", "Microsoft.ADAL.is_rt": "", "Microsoft.ADAL.tenant_id": "Hh+oQ57BV4gKSp8urSNGyMHFUVZzXuhIJ9QPLQIzHvw=", "Microsoft.ADAL.device_id": "gGvkO0ZW1G8yp+ZujF6dle4W1Bkz+peSLEHUsJ7eUSk=", "Microsoft.ADAL.application_name": "com.microsoft.aad.adal.sample", "Microsoft.ADAL.application_version": "1.0", "Microsoft.ADAL.authority_type": "Microsoft.ADAL.aad", "Microsoft.ADAL.is_successful": "true", "Microsoft.ADAL.authority_validation_status": "Microsoft.ADAL.authority_validation_status_not_done", "Microsoft.ADAL.cache_event_count": "1", "Microsoft.ADAL.api_id": "104", "Microsoft.ADAL.idp": "live.com", "Microsoft.ADAL.client_id": "f1048c32-84e4-4833-b8a5-f0a475f1c27a", "Microsoft.ADAL.response_time": "128", "Microsoft.ADAL.request_id": "6e653e42-a86d-4147-a1ff-f1752fa47f57", "Microsoft.ADAL.is_mrrt": "", "Microsoft.ADAL.user_id": "+soC2CCefj3mxyJKdO8Z8knXq5jDyp1vaFqgGXoXPlI=" } ``` -------------------------------- ### Get Current Cache Store Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Retrieve the default cache store from an AuthenticationContext instance. This is useful for accessing or customizing the token cache. ```java ITokenCacheStore cache = mContext.getCache(); ``` -------------------------------- ### Get Default Token Cache Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Retrieve the default ITokenCacheStore implementation, which uses SharedPreferences, from an AuthenticationContext. You can also provide a custom cache implementation during AuthenticationContext initialization. ```java ITokenCacheStore cache = mContext.getCache(); ``` ```java # You can also provide your cache implementation, if you want to customize it. mContext = new AuthenticationContext(MainActivity.this, authority, true, yourCache); ``` -------------------------------- ### Acquire Token with UI Prompt Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Use acquireToken to initiate an interactive token acquisition flow, which may prompt the user for login. ```java mAuthContext.acquireToken(MainActivity.this, RESOURCE_ID, CLIENT_ID, REDIRECT_URI, PromptBehavior.Auto, getAuthCallback()); ``` -------------------------------- ### Configure Broker Signature and Package Name Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Broker Set the broker's signature and package name, and enable broker usage within your application's authentication settings. ```java AuthenticationSettings.INSTANCE.setBrokerSignature(BROKER_SIGNATURE); AuthenticationSettings.INSTANCE.setBrokerPackageName(BROKER_PACKAGE_NAME); AuthenticationSettings.INSTANCE.setUseBroker(true); ``` -------------------------------- ### Acquire Token with Fragment Wrapper Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md When using a Fragment, wrap it in an IWindowComponent before calling acquireToken to ensure proper context handling. ```java mContext.acquireToken( wrapFragment(MainFragment.this), resource, clientId, redirect, user_loginhint, PromptBehavior.Auto, "", ``` -------------------------------- ### Clone Repository and Set Upstream Remote Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/contributing.md Clone the project repository and add the upstream remote for tracking changes. This is the initial step for contributing. ```bash $ git clone git@github.com:username/azure-activedirectory-library-for-android.git $ cd azure-activedirectory-library-for-android $ git remote add upstream git@github.com:MSOpenTech/azure-activedirectory-library-for-android.git ``` -------------------------------- ### Configure Android Manifest Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Add necessary internet and network state permissions, and register the AuthenticationActivity in your AndroidManifest.xml. ```xml .... ``` -------------------------------- ### Get Broker User Account Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Retrieves the currently registered broker user account. This method is used to identify the user associated with the broker app for authentication purposes. ```java String brokerAccount = mContext.getBrokerUser(); ``` -------------------------------- ### Sample SecurityException in ADAL Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/java.lang.SecurityException-in-PRNGFixes.java This is a sample stack trace of the java.lang.SecurityException that occurs on Android API versions 16-18 due to issues with /dev/urandom. ```java E/AndroidRuntime: FATAL EXCEPTION: main java.lang.SecurityException: Failed to read from /dev/urandom at com.microsoft.aad.adal.PRNGFixes$LinuxPRNGSecureRandom.engineNextBytes(PRNGFixes.java:259) at java.security.SecureRandom.nextBytes(SecureRandom.java:273) at java.util.UUID.randomUUID(UUID.java:130) at com.microsoft.aad.adal.AuthenticationContext.getRequestCorrelationId(AuthenticationContext.java:1062) at com.microsoft.aad.adal.AuthenticationContext.acquireToken(AuthenticationContext.java:351) [...] ``` -------------------------------- ### Clone ADAL Android SDK via Git Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Use this command to clone the source code of the SDK via git. Ensure to use the --recurse-submodules flag. ```bash git clone --recurse-submodules git@github.com:AzureAD/azure-activedirectory-library-for-android.git cd ./azure-activedirectory-library-for-android/src ``` -------------------------------- ### Initialize AuthenticationContext Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Create an instance of AuthenticationContext to manage authentication flows. Pass the application context, authority URL, and a boolean for validateAuthority. ```java mAuthContext = new AuthenticationContext(getApplicationContext(), AUTHORITY_URL,false); ``` -------------------------------- ### Enable Broker Usage Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Explicitly enables the use of a broker for authentication, such as Microsoft Intune's Company Portal or Azure Authenticator App. This setting must be true to utilize broker-based authentication. ```java AuthenticationSettings.INSTANCE.setUseBroker(true); ``` -------------------------------- ### Provide Custom Cache Implementation Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Instantiate AuthenticationContext with a custom cache implementation. This allows for tailored cache storage and retrieval logic. ```java mContext = new AuthenticationContext(MainActivity.this, authority, true, yourCache); ``` -------------------------------- ### Configure Git User Information Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/contributing.md Set your global Git user name and email address. This is required for making commits. ```bash $ git config --global user.name "J. Random User" $ git config --global user.email "j.random.user@example.com" ``` -------------------------------- ### Authentication Callback for Silent Token Acquisition Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Implement this callback to handle the success or failure of an asynchronous silent token acquisition. It includes logic for retrying with interactive sign-in if the silent acquisition fails. ```java private AuthenticationCallback getAuthSilentCallback() { return new AuthenticationCallback() { @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); } }; } ``` -------------------------------- ### Authentication Callback Implementation Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Implement this callback to handle the result of the acquireToken operation. It processes successful authentication results or catches exceptions on failure. ```java private AuthenticationCallback getAuthInteractiveCallback() { return new AuthenticationCallback() { @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"); } } } }; } ``` -------------------------------- ### Wrap Fragment for Authentication Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Utility method to wrap a Fragment in an IWindowComponent for authentication flows. This is necessary when authentication logic is handled within a Fragment. ```java private IWindowComponent wrapFragment(final Fragment fragment){ return new IWindowComponent() { Fragment refFragment = fragment; @Override public void startActivityForResult(Intent intent, int requestCode) { refFragment.startActivityForResult(intent, requestCode); } }; } ``` -------------------------------- ### Enable Broker for SSO Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/sso Enable broker-assisted SSO by setting the useBroker flag to true in AuthenticationSettings. This is a crucial step for leveraging token brokers. ```java AuthenticationSessings.Instance.setUseBroker(true); ``` -------------------------------- ### ITokenCacheStore Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Interface for managing the token cache. ADAL provides a default implementation using SharedPreferences. ```APIDOC ## ITokenCacheStore ### Description Interface for token cache operations. Allows for custom cache implementations or using the default SharedPreferences cache. ### Usage Get the current cache from `AuthenticationContext`: ```java ITokenCacheStore cache = mContext.getCache(); ``` Provide a custom cache implementation during `AuthenticationContext` creation: ```java mContext = new AuthenticationContext(MainActivity.this, authority, true, yourCache); ``` ``` -------------------------------- ### AndroidManifest.xml Permissions and Activity Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md This XML snippet shows the necessary internet and network state permissions, and registers the AuthenticationActivity within the application manifest. ```xml .... ``` -------------------------------- ### acquireTokenSilentSync Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Acquires an access token from the cache synchronously. This method is suitable when an immediate response is required and blocking the main thread is acceptable. ```APIDOC ## acquireTokenSilentSync ### Description Acquires an access token from the cache synchronously. ### Method `acquireTokenSilentSync` ### Parameters * `resource` (string) - The Resource URI of the Web API. * `clientId` (string) - The application id of your public client application. * `userId` (string) - The user ID obtained from `UserInfo`. ### Request Example ```java mAuthContext.acquireTokenSilentSync(RESOURCE_ID, CLIENT_ID, userId); ``` ``` -------------------------------- ### Configure Custom Log Callback Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Logging Set up a custom callback to handle log messages generated by ADAL. This allows you to direct logs to a file or other custom destinations based on log level or error codes. ```java Logger.getInstance().setExternalLogger(new ILogger() { @Override public void Log(String tag, String message, String additionalMessage, LogLevel level, ADALError errorCode) { ... // You can write this to logfile depending on level or errorcode. Log.d(TAG, message + " " + additionalMessage); } }); ``` -------------------------------- ### Acquire Token Silently (Synchronous) Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Use acquireTokenSilentSync to retrieve a token from the cache without any user interaction. This method is synchronous. ```java mAuthContext.acquireTokenSilentSync(RESOURCE_ID, CLIENT_ID, userId); ``` -------------------------------- ### Set Log Level Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Logging Configure the minimum severity level for log messages to be captured. Options range from Verbose (most detailed) to Error (least detailed). ```java Logger.getInstance().setLogLevel(Logger.LogLevel.Verbose); ``` -------------------------------- ### Cocoapods Dependency Management Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/RELEASES.md Use this syntax in your Podfile to specify a dependency that accepts the latest ADALiOS build greater than 1.1 but not including 1.2. ```ruby pod 'ADALiOS', '~> 1.1' ``` -------------------------------- ### NuGet Dependency Management Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/RELEASES.md This NuGet dependency configuration ensures that all 1.1.0 to 1.1.x updates are included, but not versions 1.2 or higher. ```xml ``` -------------------------------- ### Define Authentication Callback Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Implement an AuthenticationCallback to handle success or failure responses, including token retrieval and error logging. Note potential UI thread invocation issues in specific library versions. ```java private AuthenticationCallback callback = new AuthenticationCallback() { @Override public void onError(Exception exc) { if (exc instanceof AuthenticationException) { textViewStatus.setText("Cancelled"); Log.d(TAG, "Cancelled"); } else { textViewStatus.setText("Authentication error:" + exc.getMessage()); Log.d(TAG, "Authentication error:" + exc.getMessage()); } } @Override public void onSuccess(AuthenticationResult result) { mResult = result; if (result == null || result.getAccessToken() == null || result.getAccessToken().isEmpty()) { textViewStatus.setText("Token is empty"); Log.d(TAG, "Token is empty"); } else { // request is successful Log.d(TAG, "Status:" + result.getStatus() + " Expired:" + result.getExpiresOn().toString()); textViewStatus.setText(PASSED); } } }; ``` -------------------------------- ### Capture Logcat Output to File Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Logging Redirect all log messages from logcat to a specified file on your system. This is useful for capturing detailed diagnostic information for later analysis. ```bash adb logcat > "C:\logmsg\logfile.txt" ``` -------------------------------- ### Retrieve Current Broker User Account Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Broker Obtain the currently signed-in user's account information from the broker. This requires an initialized AuthenticationContext. ```java AuthenticationContext mContext = new AuthenticationContext (...); // Will show you the current user account that's signed into the Broker String curUser = mContext.getBrokerUser(); ``` -------------------------------- ### Push Feature Branch to Origin Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/contributing.md Push your local feature branch to your remote repository (origin). This makes your changes available for a pull request. ```bash $ git push origin my-feature-branch ``` -------------------------------- ### Skip Broker for Specific Scenarios Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Broker Optionally disable broker usage to bypass SSO and directly authenticate, which may be useful for specific scenarios. ```java AuthenticationSettings.INSTANCE.setSkipBroker(true); ``` -------------------------------- ### Register Telemetry Dispatcher Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Telemetry Obtain the Telemetry singleton and register a custom IDispatcher implementation to receive telemetry events. Configure whether event aggregation is required. ```java private static final Telemetry sTelemetry = Telemetry.getInstance(); private static final boolean sTelemetryAggregationIsRequired = true; static { sTelemetry.registerDispatcher(new IDispatcher() { @Override public void dispatchEvent(Map events) { // Events from ADAL will be sent to this callback for(Map.Entry entry: events.entrySet()) { Log.d(TAG, entry.getKey() + ": " + entry.getValue()); } } }, sTelemetryAggregationIsRequired); } ``` -------------------------------- ### Add ADAL Dependency Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Include the ADAL library in your app's Gradle dependencies. Optionally exclude specific transitive dependencies if they conflict with your project. ```gradle repositories { mavenCentral() } dependencies { // your dependencies here... implementation('com.microsoft.aad:adal:1.14.+') { // if your app includes android support libraries or Gson in its dependencies // exclude that groupId from ADAL's compile task by un-commenting the appropriate line below // exclude group: 'com.android.support' // exclude group: 'com.google.code.gson' } } ``` -------------------------------- ### Setting Encryption Key in ADAL Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Common-Issues-With-AndroidKeyStore Use this API to provide a symmetric encryption key to the ADAL library. The key must be 32 bytes and remain consistent across the application's lifetime and processes. ```java AuthenticationSettings.Instance.setSecretyKey(byte[]) ``` -------------------------------- ### Write Log Messages to a File Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md A utility method to write log messages to a private file within the application's directory. This method ensures logs are appended to the file. ```java private syncronized void writeToLogFile(Context ctx, String msg) { File directory = ctx.getDir(ctx.getPackageName(), Context.MODE_PRIVATE); File logFile = new File(directory, "logfile"); FileOutputStream outputStream = new FileOutputStream(logFile, true); OutputStreamWriter osw = new OutputStreamWriter(outputStream); osw.write(msg); osw.flush(); osw.close(); } ``` -------------------------------- ### Sample SSL Handshake Error Message Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/SSL-Certificate-Validation-with-ADFS This is a sample error message indicating an SSL handshake failure with specific error codes and certificate details. It helps in identifying the nature of the SSL problem. ```log E BasicWebViewClient: ERROR_FAILED_SSL_HANDSHAKE:2017-09-29 14:22:24--Received ssl error ver:1.12.0 Error info:Code:-11 primary error: 3 Certificate: Issued to: CN=*..,OU=,O=,C=FR; Issued by: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US; ``` -------------------------------- ### acquireTokenSilentAsync Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/API-Wiki Acquires an access token from the cache asynchronously. This method is preferred for non-blocking operations, using a callback to handle the result. ```APIDOC ## acquireTokenSilentAsync ### Description Acquires an access token from the cache asynchronously. ### Method `acquireTokenSilentAsync` ### Parameters * `resource` (string) - The Resource URI of the Web API. * `clientId` (string) - The application id of your public client application. * `userId` (string) - The user ID obtained from `UserInfo`. * `callback` (AuthenticationCallback) - Callback to handle the result. ### Request Example ```java mAuthContext.acquireTokenSilentAsync(RESOURCE_ID, CLIENT_ID, userId, getAuthSilentCallback()); ``` ``` -------------------------------- ### Create a Feature Branch Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/contributing.md Create a new branch for your feature or bug fix. This isolates your changes from the main development branches. ```bash $ git checkout -b my-feature-branch ``` -------------------------------- ### Acquire Token Silently (Asynchronous) Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ADAL-Basics Use acquireTokenSilentAsync to retrieve a token from the cache asynchronously without any user interaction. This is the preferred method for background token retrieval. ```java mAuthContext.acquireTokenSilentAsync(RESOURCE_ID, CLIENT_ID, userId, getAuthCallback()); ``` -------------------------------- ### Keep ADAL and Common Identity Classes Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/ProGuard Use these ProGuard rules to prevent shrinking and obfuscation of ADAL and common identity classes. This is recommended for easier debugging and to ensure reflection-based functionalities work correctly. ```gradle #Keep ADAL classes -keep class com.microsoft.aad.adal.** { *; } -keep class com.microsoft.identity.common.** { *; } #Keep Gson for ADAL https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg -keepattributes Signature -keepattributes *Annotation* -dontwarn sun.misc.** -keep class com.google.gson.examples.android.model.** { *; } -keep class * implements com.google.gson.TypeAdapterFactory -keep class * implements com.google.gson.JsonSerializer -keep class * implements com.google.gson.JsonDeserializer -dontwarn org.bouncycastle.** -dontwarn com.microsoft.identity.common.internal.providers.oauth2.AuthorizationActivity ``` -------------------------------- ### ClientInfo Serializable Implementation Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/changelog.txt Ensures that ClientInfo implements Serializable, which is necessary for ADAL/AuthenticationResult to be serialized correctly. This is a bugfix for COMMON/#379. ```java ClientInfo must implement Serializable so that ADAL/AuthenticationResult can be serialized. ``` -------------------------------- ### NullPointerException with IKeystoreService Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Common-Issues-With-AndroidKeyStore This exception arises when a remote service attempts to access the Keystore, resulting in a null object reference for the IKeystoreService. ```java java.lang.NullPointerException: Attempt to invoke interface method 'int android.security.IKeystoreService.exist(java.lang.String, int)' on a null object reference ``` -------------------------------- ### Configure Encryption Key (Deprecated) Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Provides a password-based encryption key for ADAL, used for lower SDK versions. This method is deprecated and should be avoided in new development. ```java SecretKeyFactory keyFactory = SecretKeyFactory .getInstance("PBEWithSHA256And256BitAES-CBC-BC"); SecretKey generatedSecretKey = keyFactory.generateSecret(new PBEKeySpec(your_password, byte-code-for-your-salt, 100, 256)); SecretKey secretKey = new SecretKeySpec(generatedSecretKey.getEncoded(), "AES"); AuthenticationSettings.INSTANCE.setSecretKey(secretKey.getEncoded()); ``` -------------------------------- ### Android Manifest Permissions for AccountManager Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/DEVELOPER_BROKER_PERMISSIONS_MISSING Add these permissions to your AndroidManifest.xml to resolve the DEVELOPER_BROKER_PERMISSIONS_MISSING error. This is an alternative to updating the broker and ADAL versions. ```xml ``` -------------------------------- ### Capture Logs from Logcat to a File Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Redirect log messages from Android's logcat to a specified file on your system. This is useful for capturing all system and application logs. ```shell adb logcat > "C:\\logmsg\\logfile.txt" ``` -------------------------------- ### InvalidKeyException due to RSA routines Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Common-Issues-With-AndroidKeyStore This exception can occur when the lock screen type is changed, potentially leading to the keystore being wiped out. It indicates an issue with RSA padding checks. ```java Caused by: java.security.InvalidKeyException: javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02 ``` -------------------------------- ### IllegalArgumentException: key.length == 0 Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Common-Issues-With-AndroidKeyStore This exception is another indicator that the AndroidKeyStore may have been wiped out, possibly due to changes in the device's lock screen type. ```java Caused by: java.lang.IllegalArgumentException: key.length == 0 ``` -------------------------------- ### Override Default English Strings Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Resource-Overrides These are the default English string resources provided by the ADAL library. Override these in your application's `res/values/strings.xml` file to provide localized versions. ```xml Loading... Broker is processing Username Password Sign In Login Cancel ``` -------------------------------- ### Exclude Surface Duo SDK in ADAL Dependency Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/changelog.txt When including your own copy of the Surface Duo SDK, exclude the SDK within ADAL to prevent conflicts. This is typically done in your app's build.gradle file. ```gradle implementation ("com.microsoft.aad:adal:3.0.1") { exclude group: 'com.microsoft.device.display' } ``` -------------------------------- ### Enable/Disable PII and OII Logging Source: https://github.com/azuread/azure-activedirectory-library-for-android/wiki/Logging Control whether Personally Identifiable Information (PII) or Organizationally Identifiable Information (OII) is included in ADAL logs. By default, PII/OII logging is disabled to protect sensitive data. ```java // By default, the `Logger` does not capture any PII or OII // PII or OII will be logged Logger.getInstance().setEnablePII(true); // PII or OII will NOT be logged Logger.getInstance().setEnablePII(false); ``` -------------------------------- ### Synchronous Silent Token Acquisition Source: https://github.com/azuread/azure-activedirectory-library-for-android/blob/dev/README.md Acquires an authentication token silently using cached credentials without user interaction. Requires the user ID obtained from a previous interactive call. ```java mContext.acquireTokenSilentSync(String resource, String clientId, String userId); ```