MSAL Java sample demonstrating how a daemon console application can call Microsoft Graph using its own identity
About this sample
Overview
This app demonstrates how to use the Microsoft identity platform to access the data of Microsoft business customers in a long-running, non-interactive process. It uses the Microsoft Authentication Library (MSAL) for Java to acquire an access token, which it then uses to call Microsoft Graph and accesses organizational data. The sample utilizes the OAuth 2 client credentials grant and a secret value configured in Azure to obtain an access token for calls to Microsoft Graph.
Scenario
The console application:
- Acquires an access token from Microsoft Entra ID using its own identity (without a user).
- It then calls the Microsoft Graph
/usersendpoint to retrieve a list of users, which it then displays on the screen (as a Json blob).

For more information on the concepts used in this sample, be sure to read the Microsoft identity platform endpoint client credentials protocol documentation.
How to run this sample
To run this sample, you'll need:
- Working installation of Java 8 or greater and Maven.
- a Microsoft Entra tenant. For more information on how to get a Microsoft Entra tenant, see How to get a Microsoft Entra tenant.
- One or more user accounts in your Microsoft Entra tenant.
Step 1: Clone or download this repository
From your shell or command line:
git clone https://github.com/Azure-Samples/ms-identity-java-daemon.git
or download and extract the repository .zip file.
Step 2: Register the sample with your Microsoft Entra tenant
To register the project, you can:
- either follow the steps Step 2: Register the sample with your Microsoft Entra tenant and Step 3: Configure the sample to use your Microsoft Entra tenant
- or use PowerShell scripts that:
- automatically creates the Microsoft Entra applications and related objects (passwords, permissions, dependencies) for you.
- modify the project's configuration files.
If you want to use this automation, read the instructions in App Creation Scripts Please note that the configuration of your code (Step 3) still needs to be done manually.
Follow the steps below to manually walk through the steps to register and configure the applications.
Choose the Microsoft Entra tenant where you want to create your applications
As a first step you'll need to:
- Sign in to the Microsoft Entra admin center using either a work or school account or a personal Microsoft account.
- If your account is present in more than one Microsoft Entra tenant, select your profile at the top right corner in the menu on top of the page, and then switch directory. Change your portal session to the desired Microsoft Entra tenant.
- In the portal menu, select the Microsoft Entra ID service, and then select App registrations.
Register the client app (java-daemon-console)
Navigate to the Microsoft identity platform for developers App registrations page.
Select New registration.
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
java-daemon-console. - In the Supported account types section, select Accounts in this organizational directory only ({tenant name}).
- Click Register button at the bottom to create the application.
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
On the application Overview page, find the Application (client) ID and Directory (tenant) ID values and record it for later. You'll need it to configure the configuration file(s) later in your code.
In the Application menu blade, click on the Certificates & secrets, in the Client secrets section, choose New client secret:
- Type a key description (for instance
app secret), - Select a key duration of either In 1 year, In 2 years, or Never Expires as per your security concerns.
- The generated key value will be displayed when you click the Add button. Copy the generated value for use in the steps later.
- You'll need this key later in your code's configuration files. This key value will not be displayed again, and is not retrievable by any other means, so make sure to note it from the Microsoft Entra admin center before navigating to any other screen or blade.
- Type a key description (for instance
In the Application menu blade, click on the API permissions in the left to open the page where we add access to the Apis that your application needs.
- Click the Add a permission button and then,
- Ensure that the Microsoft APIs tab is selected
- In the Commonly used Microsoft APIs section, click on Microsoft Graph
- In the Application permissions section, ensure that the right permissions are checked: User.Read.All
- Select the Add permissions button at the bottom.
At this stage, the permissions are assigned correctly but since the client app does not allow users to interact, the user's themselves cannot consent to these permissions. To get around this problem, we'd let the tenant administrator consent on behalf of all users in the tenant. Click the Grant admin consent for {tenant} button, and then select Yes when you are asked if you want to grant consent for the requested permissions for all account in the tenant. You need to be the tenant admin to be able to carry out this operation.
Step 3: Configure the client app (java-daemon-console) to use your app registration
Open the project in your IDE to configure the code.
In the steps below, "ClientID" is the same as "Application ID" or "AppId" and "Tenant ID" is same as "Directory ID".
- Open the
msal-client-credential-secret\src\main\resources\application.propertiesclass - Set the
CLIENT_IDproperty to the application/client ID value you recorded earlier - Replace
Tenant_Info_Herein theAUTHORITYproperty with the directory/tenant ID value you recorded earlier - Set the
SECRETproperty to the secret value you recorded earlier
Step 4: Run the sample
You can test the sample directly by running the main method of ClientCredentialGrant.java from your IDE.
From your shell or command line:
$ mvn clean compile assembly:single
This will generate a msal-client-credential-secret-1.0.0.jar file in your /targets directory. Run this using your Java executable like below:
$ java -jar msal-client-credential-secret-1.0.0.jar
After running, the application should display the list of user in the configured tenant.
About the code
The relevant code for this sample is in the ClientCredentialGrant.java file.
Create the MSAL confidential client application.
Important notes: even if we are building a console application, it is a daemon, and therefore a confidential client application, as it does not access Web APIs on behalf of a user, but on its own application behalf.
The app object needs to be reused, as it holds a token cache. This will work for up single tenant requests. For multi-tenant apps, once you get to millions of tokens, the app object will consume too much memory. See msal-client-credential-secret-high-availability sample in this directory for a high scale multi-tenant app.
ConfidentialClientApplication app = ConfidentialClientApplication.builder( clientId, ClientCredentialFactory.createFromSecret(secret)) .authority(authority) .build();Define the scopes.
Specific to client credentials, you don't specify the individual scopes you want to access. You have statically declared them during the application registration step. Therefore the only possible scope is "resource/.default" (here "https://graph.microsoft.com/.default") which means "the static permissions defined in the application"
// With client credentials flows the scope is ALWAYS of the shape "resource/.default", as the // application permissions need to be set statically (in the portal), and then granted by a tenant administrator ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder( Collections.singleton(scope)) .build();Acquire the token
Uses the ConfidentialClientApplication, built with the configured authority/client ID/secret, to acquire an access token
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam); return future.get();Call the API and read result
In this case calling "https://graph.microsoft.com/v1.0/users" with the access token as a bearer token.
URL url = new URL("https://graph.microsoft.com/v1.0/users"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //... try(BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))){ String inputLine; response = new StringBuilder(); while (( inputLine = in.readLine()) != null) { response.append(inputLine); } } return response.toString();
Troubleshooting
Did you forget to provide admin consent? This is needed for daemon apps
If you get an Forbidden error when calling the API, this is because the tenant administrator has not granted permissions
to the application. Check the steps in Register the client app (daemon-console) above.
Community Help and Support
Use Stack Overflow to get support from the community.
Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before.
Make sure that your questions or comments are tagged with [msal java].
If you find a bug in the sample, please raise the issue on GitHub Issues.
If you find a bug in msal4j, please raise the issue on MSAL4J GitHub Issues.
To provide a recommendation, visit the following User Voice page.
Contributing
If you'd like to contribute to this sample, see CONTRIBUTING.MD.
This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
More information
For more information, see:
- MSAL4J conceptual documentation.
- Permissions and Consent
- OAuth 2 client credentials grant
- Quickstart: Register an application with the Microsoft identity platform
- Quickstart: Configure a client application to access web APIs
- The documentation for Microsoft identity platform is available from https://aka.ms/aadv2
- Other samples for Microsoft identity platform are available from https://aka.ms/aaddevsamplesv2