Getting Started | Library | API Reference | Support |
---|
The MSAL Android library gives your app the ability to begin using the Microsoft identity platform by supporting Microsoft Entra ID and Microsoft Accounts in a converged experience using industry standard OAuth2 and OpenID Connect protocols.
This sample walks you through the process of integrating authentication with Microsoft Identity Platform (formerly Microsoft Entra ID for developers) in your android application. In this sample we'd walk you through the code you need to write in the various lifecycle events of your app to achieve the following objectives.
- Sign-in a user
- Device-wide SSO and Conditional Access support through the Auth Broker
- Select between Single Account Mode and Multiple Account Mode
- How to handle shared device mode
- Get a token for the Microsoft Graph
- Call the Microsoft Graph
- Sign out the user
This sample app is a multi-tenant app, which means that it can sign-in users from any Microsoft Entra tenant and Microsoft Accounts. It also demonstrates how a developer can build apps to connect with enterprise users and access their Azure + O365 data via Microsoft Graph. During the auth flow, the users will be required to sign-in first, if it is their first time signing-in to the app, the user would be asked to consent to the permissions required by the application.
The majority of the logic in this sample shows how to sign-in an end user and make a call to the Microsoft Graph to get basic information about the signed-in user.
Microsoft provides applications for every mobile platform that allow for the bridging credentials across applications from different vendors and for enhanced features that require a single secure place from where to validate credentials. These applications are called Brokers. The brokers available for Android are Microsoft Authenticator and Company Portal. Learn more about Brokers here.
The MSAL for Android will automatically use the broker if they are present on the device.
Note: If you have older versions of Microsoft Authenticator or Company Portal App installed in the device where this sample application will be run, then the user might not be able to test the scenarios presented here. Please make sure that you have installed the latest version of Microsoft Authenticator or Company Portal on your device.
In the Single Account
Mode, only one user can sign into the application at a time. If the app wants to support just one signed-in user, it is recommended to use the Single Account
Mode.
The following code snippet from SingleAccountModeFragment class shows how the application is set to the Single Account
Mode in the code:
PublicClientApplication.createSingleAccountPublicClientApplication(
getContext(),
R.raw.auth_config_single_account);
In the auth_config_single_account.json file, the account_mode
is set as following:.
"account_mode" : "SINGLE",
Shared Device
Mode will allow you to configure Android devices to be shared by multiple employees, while providing Microsoft Identity backed management of the device. Employees will be able to sign-in to their devices and access customer information quickly. When they are finished with their shift or task, they will be able to globally Sign-Out of the device and it will be immediately ready for the next employee to use.
Note
Applications that run on Shared Devices must be in Single Account Mode. Applications that only support Multiple Account Mode will not run on a Shared Device.
In the code, you can use the isSharedDevice()
flag to determine if an application is in the Shared Device Mode. Your app can use this flag to modify UX accordingly.
Code snippet from SingleAccountModeFragment class showing usage of the isSharedDevice()
flag:
deviceModeTextView.setText(mSingleAccountApp.isSharedDevice() ? "Shared" : "Non-Shared");
Note
You can only put a device in to Shared Mode using the Authenticator app and with a user who is in the Cloud Device Administrator role. You can configure the membership of your Organizational Roles by going to the Microsoft Entra admin center and selecting:
Microsoft Entra ID -> Show more -> Roles and Administrators -> Roles and Administrators -> Cloud Device Administrator
In the Multiple Account
Mode, the application supports multiple accounts and can switch between accounts of the user and get data from that user's account.
Code snippet from MultipleAccountModeFragment class shows how the application is set in the Multiple Account
Mode in the code:
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(),
R.raw.auth_config_multiple_account);
In the auth_config_multiple_account.json file, the account_mode
is set as following:.
"account_mode" : "MULTIPLE",
If your app also supports multiple accounts as well as shared device mode, you will have to perform type check and cast to the appropriate interface to perform an operation shown as below.
private IPublicClientApplication mApplication;
if (mApplication instanceOf IMultipleAccountPublicClientApplication) {
IMultipleAccountPublicClientApplication multipleAccountApplication = (IMultipleAccountPublicClientApplication) mApplication;
...
} else if (mApplication instanceOf ISingleAccountPublicClientApplication) {
ISingleAccountPublicClientApplication singleAccountApplication = (ISingleAccountPublicClientApplication) mApplication;
...
}
Note
If you're writing an application that will only be used on shared devices, we recommend you write your application to support only the Single Account
Mode.
For more information on the concepts used in this sample, be sure to read the Shared device mode documentation
To run this sample, you'll need:
- Android SDK
- An internet connection
- a Microsoft Entra tenant. For more information on how to get a Microsoft Entra tenant, see How to get a Microsoft Entra tenant
- For Customer Identity and Access Management (CIAM), they will need to designate the tenant as a CIAM tenant as it is being created.
- One or more user accounts in your Microsoft Entra tenant.
Note: As a convenience, this sample ships with a default
redirect_uri
preconfigured in theAndroidManifest.xml
so that you don't have to first register your own app object. Aredirect_uri
is partly based on your app's signing key. The sample project is configured to sign using the includeddebug.keystore
so that the providedredirect_uri
will work.
From your shell or command line:
git clone https://github.com/Azure-Samples/ms-identity-android-java.git
The following steps are for Android Studio. But you can choose and work with any editor of your choice.
Open Android Studio, and select open an existing Android Studio project. Find the cloned project and open it.
From menu, select Run > Run 'app'. Once the app launches,
-
Click on the hamburger icon
- Single Account Mode: Select this to explore Single Account
- Multiple Account Mode: Select this to explore Multiple Account
- B2C Mode: Select this to Explore B2C
- Depending on the mode selected, click on
sign-in
orGet Graph Data Interactively
orrun user flow
, it takes you to Sign in (add account
) page. - Sign in with Microsoft Entra ID, MSA or B2C account.
- If this is your first time running the scenario, you will see a consent dialogue. Select 'yes' to proceed.
- Once successfully signed-in, basic user details will be displayed.
To explore more about the application, follow on screen options.
Note: This sample application is configured to run out-of-the-box. To register your own application and run the sample with those settings, follow below steps.
To begin registering your app, start at the Microsoft Entra admin center
To create an app registration,
- Click
New Registration
. - Name your app, select the audience you're targeting, and click
Register
. - On the next screen click on
Authentication
and thenAdd Platform
. - Select
Android
from the options shown on the right hand side. - On the 'Configure your Android App' page
- Enter the Package Name from your Android Manifest.
- Enter the Signature Hash. Follow the instructions in the portal to generate Signature hash.
- Click
Configure
at the bottom of the page.
- Take note of the MSAL Configuration as it is used later in
AndroidManifest.xml
andauth_config.json
.
Configure the sample application with your app registration by replacing the sample code in auth_config.json
and AndroidManifest.xml
-
Copy and paste the MSAL Configuration JSON from the Microsoft Entra admin center into
auth_config_multiple_account.json
under the res\raw folder. -
Inside the
AndroidManifest.xml
,-
replace
android:host
with the package nameandroid:host="<packaage_name>"
-
replace
android:path
with signature hash.android:path="<SignatureHash>"
- `auth_config.json` contains this information as a reference inside the `redirect_uri` field. - The Signature Hash should NOT be URL encoded in the `AndroidManifest.xml`.
Refer Microsoft Entra ID Android Quickstart for more details
-
From menu, select Build > Clean Project and Run > Run 'app'.
The following files have the code that would be of interest to you.
Contains code showing how the Single Account
Mode is implemented. The includes authentication, obtaining the token, and making a Graph api call using the token obtained .
The following steps provide more details.
-
Create a SingleAccount PublicClientApplication:
PublicClientApplication.createSingleAccountPublicClientApplication(getContext(), R.raw.auth_config_single_account, new IPublicClientApplication.ISingleAccountApplicationCreatedListener() { @Override public void onCreated(ISingleAccountPublicClientApplication application) { ... } });
-
Signing in a user:
mSingleAccountApp.signIn(getActivity(), getScopes(), getAuthInteractiveCallback());
-
Acquiring token:
- Interactive:
mSingleAccountApp.acquireToken(getActivity(), getScopes(),getAuthInteractiveCallback());
- Silent:
mSingleAccountApp.acquireTokenSilentAsync(getScopes(), AUTHORITY, getAuthSilentCallback());
-
Calling Graph API to get basic user details and displaying data:
private void callGraphAPI(final IAuthenticationResult authenticationResult) { MSGraphRequestWrapper.callGraphAPIWithVolley( getContext(), graphResourceTextView.getText().toString(), authenticationResult.getAccessToken(), new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { /* Successfully called graph */ ... } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { ... } }); }
-
Sign-out:
mSingleAccountApp.signOut(new ISingleAccountPublicClientApplication.SignOutCallback() { @Override public void onSignOut() { ... } });
When sign-out is performed it removes the signed-in account and cached tokens from this app (or device, if the device is in shared mode)
Contains code showing how the Multiple Account
Mode is implemented. The includes authentication and obtaining the token, and making a graph api call using the obtained token.
-
Create a MultipleAccount PublicClientApplication:
PublicClientApplication.createMultipleAccountPublicClientApplication(getContext(), R.raw.auth_config_multiple_account, new IPublicClientApplication.IMultipleAccountApplicationCreatedListener() { @Override public void onCreated(IMultipleAccountPublicClientApplication application) { ... } });
-
Acquiring token:
- Interactive:
mMultipleAccountApp.acquireToken(getActivity(), getScopes(), getAuthInteractiveCallback());
- Silent:
mMultipleAccountApp.acquireTokenSilentAsync(getScopes(), accountList.get(accountListSpinner.getSelectedItemPosition()),AUTHORITY, getAuthSilentCallback());
-
Get Accounts:
mMultipleAccountApp.getAccounts(new IPublicClientApplication.LoadAccountsCallback() { @Override public void onTaskCompleted(final List<IAccount> result) { ... } });
-
Remove account:
mMultipleAccountApp.removeAccount(accountList.get(accountListSpinner.getSelectedItemPosition()), new IMultipleAccountPublicClientApplication.RemoveAccountCallback() { @Override public void onRemoved() { ... } });
Contains code showing how the B2C
Mode is implemented. The includes authentication and obtaining the token, and making a graph api call using the obtained token.
Because B2C treats each policy as a separate authority, B2CUser
was introduced to represent a single user that could hold one or more IAccount object for each policies.
If you'd like to use your own app registration, you will also need to update B2CConfiguration.java to match with your configuration json file.
-
Acquire token / run user flow
AcquireTokenParameters parameters = new AcquireTokenParameters.Builder() .startAuthorizationFromActivity(getActivity()) .fromAuthority(B2CConfiguration.getAuthorityFromPolicyName(policyListSpinner.getSelectedItem().toString())) .withScopes(B2CConfiguration.getScopes()) .withPrompt(Prompt.LOGIN) .withCallback(getAuthInteractiveCallback()) .build(); b2cApp.acquireToken(parameters);
-
Construct
B2CUser
objects from an account list (obtained from )b2cApp.getAccounts(new IPublicClientApplication.LoadAccountsCallback() { @Override public void onTaskCompleted(final List<IAccount> result) { users = B2CUser.getB2CUsersFromAccountList(result); ... } }); public static List<B2CUser> getB2CUsersFromAccountList(@NonNull final List<IAccount> accounts) { final HashMap<String, B2CUser> b2CUserHashMap = new HashMap<>(); for (IAccount account : accounts) { /** * NOTE: Because B2C treats each policy as a separate authority, the access tokens, refresh tokens, and id tokens returned from each policy are considered logically separate entities. * In practical terms, this means that each policy returns a separate IAccount object whose tokens cannot be used to invoke other policies. * * You can use the 'Subject' claim to identify that those accounts belong to the same user. */ final String subject = B2CUser.getSubjectFromAccount(account); B2CUser user = b2CUserHashMap.get(subject); if (user == null) { user = new B2CUser(); b2CUserHashMap.put(subject, user); } user.accounts.add(account); ... } }
-
Acquire token silently (In
B2CUser
)for (IAccount account : accounts) { if (policyName.equalsIgnoreCase(getB2CPolicyNameFromAccount(account))) { AcquireTokenSilentParameters parameters = new AcquireTokenSilentParameters.Builder() .fromAuthority(B2CConfiguration.getAuthorityFromPolicyName(policyName)) .withScopes(scopes) .forAccount(account) .withCallback(callback) .build(); multipleAccountPublicClientApplication.acquireTokenSilentAsync(parameters); ... } }
-
Sign out (In
B2CUser
)for (IAccount account : accounts) { multipleAccountPublicClientApplication.removeAccount(account); }
This class is used to support CIAM users and confirming that the user can authenticate and get an access token. The CIAM implementation is frequently being updated, so this section of the sample could change in the near future. Please note that at this time, CIAM does not integrate with MS Graph, so we could not fetch MS Graph information in this fragment of the sample app. Instead, we will output the access token to confirm successful authentication. Below is a diaram showing this shortened approach:
This fragment's acquireToken
, getAccounts
, acquireTokenSilentAsync
, and removeAccount
are similar to those found in MultipleAccountModeFragment
, but updated to use non-deprecated methods.
Note: This fragment reads configuration information from
auth_config_ciam.json
. To get this fragment of the sample to work, you will have to manually input theclient_id
andauthority_url
fields to point towards your CIAM tenant (reference the Register your Own Application section for more information). Theauthority_url
should look like this: "https://TENANT_NAME.ciamlogin.com/TENANT_NAME.onmicrosoft.com/". The authority type should remain asCIAM
.
We use Stack Overflow with the community to provide support. We highly recommend you ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before.
If you find and bug or have a feature request, please raise the issue on GitHub Issues.
To provide a recommendation, visit our User Voice page.
We enthusiastically welcome contributions and feedback. You can clone the repo and start contributing now. Read our Contribution Guide for more information.
This project has adopted the Microsoft Open Source Code of Conduct.
For more information seethe Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
This library controls how users sign-in and access services. We recommend you always take the latest version of our library in your app when possible. We use semantic versioning so you can control the risk associated with updating your app. As an example, always downloading the latest minor version number (e.g. x.y.x) ensures you get the latest security and feature enhancements but our API surface remains the same. You can always see the latest version and release notes under the Releases tab of GitHub.
If you find a security issue with our libraries or services please report it to secure@microsoft.com with as much detail as possible. Your submission may be eligible for a bounty through the Microsoft Bounty program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting this page and subscribing to Security Advisory Alerts.
-
The documentation for the Microsoft identity platform is available from Microsoft identity platform (v2.0) overview.
-
Other samples for the Microsoft identity platform are available from Microsoft identity platform code samples.
-
The conceptual documentation for MSAL Android is available from Microsoft authentication library for android conceptual documentation.
-
Tutorial: Use shared-device mode in your Android application