page_type | languages | products | name | urlFragment | description | |||||
---|---|---|---|---|---|---|---|---|---|---|
sample |
|
|
Enable your Java Servlet web app to sign in users and call Microsoft Graph with the Microsoft identity platform |
ms-identity-java-servlet-webapp-call-graph |
This sample demonstrates a Java Servlet web app that signs in users and obtains an access token to call MS Graph with the Microsoft identity platform |
Enable your Java Servlet web app to sign in users and call Microsoft Graph with the Microsoft identity platform
- Overview
- Scenario
- Contents
- Prerequisites
- Setup
- Register the sample application with your Azure Active Directory tenant
- Running the sample
- Explore the sample
- We'd love your feedback!
- About the code
- Deploy to Azure
- More information
- Community Help and Support
- Contributing
This sample demonstrates a Java Servlet web app that signs in users and obtains an access token for calling Microsoft Graph. It uses the Microsoft Authentication Library (MSAL) for Java.
- This web application uses MSAL for Java (MSAL4J) to sign in a user and obtain an Access Token for Microsoft Graph from Azure AD:
- The Access Token proves that the user is authorized to access the Microsoft Graph API endpoint as defined in the scope.
File/folder | Description |
---|---|
AppCreationScripts/ |
Scripts to automatically configure Azure AD app registrations. |
src/main/java/com/microsoft/azuresamples/msal4j/callgraphwebapp/ |
This directory contains the classes that define the web app's backend business logic. |
src/main/java/com/microsoft/azuresamples/msal4j/authservlets/ |
This directory contains the classes that are used for sign in and sign out endpoints. |
____Servlet.java |
All of the endpoints available are defined in .java classes ending in ____Servlet.java. |
src/main/java/com/microsoft/azuresamples/msal4j/helpers/ |
Helper classes for authentication. |
AuthenticationFilter.java |
Redirects unauthenticated requests to protected endpoints to a 401 page. |
src/main/resources/authentication.properties |
Azure AD and program configuration. |
src/main/webapp/ |
This directory contains the UI (JSP templates) |
CHANGELOG.md |
List of changes to the sample. |
CONTRIBUTING.md |
Guidelines for contributing to the sample. |
LICENSE |
The license for the sample. |
- Java 8 or above
- Maven 3
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see How to get an Azure AD tenant
- A user account in your own Azure AD tenant if you want to work with accounts in your organizational directory only (single-tenant mode). If have not yet created a user account in your AD tenant yet, you should do so before proceeding.
- A user account in any organization's Azure AD tenant if you want to work with accounts in any organizational directory (multi-tenant mode). This sample must be modified to work with a personal Microsoft account. If have not yet created a user account in your AD tenant yet, you should do so before proceeding.
- A personal Microsoft account (e.g., Xbox, Hotmail, Live, etc) if you want to work with personal Microsoft accounts
From your shell or command line:
git clone https://github.com/Azure-Samples/ms-identity-java-servlet-webapp-authentication.git
cd 2-Authorization-I/call-graph
or download and extract the repository .zip file.
⚠️ To avoid file path length limitations on Windows, clone the repository into a directory near the root of your hard drive.
There is one project in this sample. To register the app on the portal, you can:
- either follow manual configuration steps below
- or use PowerShell scripts that:
- automatically creates the Azure AD applications and related objects (passwords, permissions, dependencies) for you.
- modify the projects' configuration files.
- by default, the automation scripts set up an application that works with accounts in your organizational directory only.
Expand this section if you want to use PowerShell automation.
-
On Windows, run PowerShell and navigate to the root of the cloned directory
-
In PowerShell run:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
-
Run the script to create your Azure AD application and configure the code of the sample application accordingly.
-
In PowerShell run:
cd .\AppCreationScripts\ .\Configure.ps1
Other ways of running the scripts are described in App Creation Scripts The scripts also provide a guide to automated application registration, configuration and removal which can help in your CI/CD scenarios.
As a first step you'll need to:
- Sign in to the Azure portal.
- If your account is present in more than one Azure AD tenant, select your profile at the top right corner in the menu on top of the page, and then switch directory to change your portal session to the desired Azure AD tenant.
Register a new web app in the Azure Portal. Following this guide, you must:
-
Navigate to the Microsoft identity platform for developers App registrations page.
-
Select New registration.
-
In the Register an application page that appears, enter your application's registration information:
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
java-servlet-webapp-call-graph
. - Under Supported account types, select an option.
- Select Accounts in this organizational directory only if you're building an application for use only by users in your tenant (single-tenant).
- Select Accounts in any organizational directory if you'd like users in any Azure AD tenant to be able to use your application (multi-tenant).
- Select Accounts in any organizational directory and personal Microsoft accounts for the widest set of customers (multi-tenant that also supports Microsoft personal accounts).
- Select Personal Microsoft accounts for use only by users of personal Microsoft accounts (e.g., Hotmail, Live, Skype, Xbox accounts).
- In the Redirect URI section, select Web in the combo-box and enter the following redirect URI:
http://localhost:8080/msal4j-servlet-graph/auth/redirect
.
- In the Name section, enter a meaningful application name that will be displayed to users of the app, for example
-
Select Register to create the application.
-
In the app's registration screen, find and note the Application (client) ID. You use this value in your app's configuration file(s) later in your code.
-
Select Save to save your changes.
-
In the app's registration screen, click on the Certificates & secrets blade in the left to open the page where we can generate secrets and upload certificates.
-
In the Client secrets section, click on New client secret:
- Type a key description (for instance
app secret
), - Select one of the available key durations (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 Azure portal before navigating to any other screen or blade.
- Type a key description (for instance
-
In the app's registration screen, click on the API permissions blade in the left to open the page where we add access to the Apis that your application needs.
- Click the Add permissions button and then,
- Ensure that the Microsoft APIs tab is selected.
- In the Commonly used Microsoft APIs section, click on Microsoft Graph
- In the Delegated permissions section, select the User.Read in the list. Use the search box if necessary.
- Click on the Add permissions button in the bottom.
Open the project in your IDE to configure the code.
In the steps below, "ClientID" is the same as "Application ID" or "AppId".
- Open the
./src/main/resources/authentication.properties
file - Find the string
{enter-your-tenant-id-here}
. Replace the existing value with:- Your Azure AD tenant ID if you registered your app with the Accounts in this organizational directory only option.
- The word
organizations
if you registered your app with the Accounts in any organizational directory option. - The word
common
if you registered your app with the Accounts in any organizational directory and personal Microsoft accounts option. - The word
consumers
if you registered your app with the Personal Microsoft accounts option
- Find the string
{enter-your-client-id-here}
and replace the existing value with the application ID (clientId) of thejava-servlet-webapp-call-graph
application copied from the Azure portal. - Find the string
{enter-your-client-secret-here}
and replace the existing value with the key you saved during the creation of thejava-servlet-webapp-call-graph
app, in the Azure portal.
- Navigate to the directory containing the pom.xml file for this sample (the same directory as this README), and run the following Maven command:
mvn clean package
- This should generate a
.war
file which can be run on a variety of application servers
Our samples can be deployed to a number of application servers, such as Tomcat, WebLogic, or Webshpere, and MSAL Java itself can generally be integrated into existing applications without changes to your existing deployment set up.
You can find instructions for deploying our samples here on MSAL Java's Github wiki.
- Note the signed-in or signed-out status displayed at the center of the screen.
- Click the context-sensitive button at the top right (it will read
Sign In
on first run) - Follow the instructions on the next page to sign in with an account in the Azure AD tenant.
- On the consent screen, note the scopes that are being requested.
- Note the context-sensitive button now says
Sign out
and displays your username to its left. - The middle of the screen now has an option to click for ID Token Details: click it to see some of the ID token's decoded claims.
- Click the Call Graph button to make a call to Microsoft Graph's /me endpoint and see a selection of user details obtained.
- You can also use the button on the top right to sign out.
ℹ️ Did the sample not work for you as expected? Did you encounter issues trying this sample? Then please reach out to us using the GitHub Issues page.
Were we successful in addressing your learning objective? Consider taking a moment to share your experience with us.
This sample uses MSAL for Java (MSAL4J) to sign a user in and obtain a token for MS Graph API. It leverages Microsoft Graph SDK for Java to obtain data from Graph. You must add these libraries to your projects using Maven. If you want to replicate this sample's behavior, you may choose to copy the pom.xml
file, and the contents of the helpers
and authservlets
packages in the src/main/java/com/microsoft/azuresamples/msal4j
package. You'll also need the authentication.properties file. These classes and files contain generic code that can be used in a wide array of applications. The rest of the sample may be copied as well, but the other classes and files are built specifically to address this sample's objective.
A ConfidentialClientApplication instance is created in the AuthHelper.java class. This object helps craft the AAD authorization URL and also helps exchange the authentication token for an access token.
// getConfidentialClientInstance method
IClientSecret secret = ClientCredentialFactory.createFromSecret(SECRET);
confClientInstance = ConfidentialClientApplication
.builder(CLIENT_ID, secret)
.authority(AUTHORITY)
.build();
The following parameters need to be provided upon instantiation:
- The Client ID of the app
- The Client Secret, which is a requirement for Confidential Client Applications
- The Azure AD Authority, which includes your AAD tenant ID.
In this sample, these values are read from the authentication.properties file using a properties reader in the class Config.java.
-
The first step of the sign-in process is to send a request to the
/authorize
endpoint on for our Azure Active Directory Tenant. Our MSAL4JConfidentialClientApplication
instance is leveraged to construct an authorization request URL. Our app redirects the browser to this URL, which is where the user will sign in.final ConfidentialClientApplication client = getConfidentialClientInstance(); AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters.builder(Config.REDIRECT_URI, Collections.singleton(Config.SCOPES)) .responseMode(ResponseMode.QUERY).prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build(); final String authorizeUrl = client.getAuthorizationRequestUrl(parameters).toString(); contextAdapter.redirectUser(authorizeUrl);
- AuthorizationRequestUrlParameters: Parameters that must be set in order to build an AuthorizationRequestUrl.
- REDIRECT_URI: Where AAD will redirect the browser (along with auth code) after collecting user credentials. It must match the redirect URI in the Azure AD app registration on Azure Portal
- SCOPES: Scopes are permissions requested by the application.
- Normally, the three scopes
openid profile offline_access
suffice for receiving an ID Token response. - Full list of scopes requested by the app can be found in the authentication.properties file. You can add more scopes like User.Read and so on.
- Normally, the three scopes
-
The user is presented with a sign-in prompt by Azure Active Directory. If the sign-in attempt is successful, the user's browser is redirected to our app's redirect endpoint. A valid request to this endpoint will contain an authorization code.
-
Our ConfidentialClientApplication instance then exchanges this authorization code for an ID Token and Access Token from Azure Active Directory.
// First, validate the state, then parse any error codes in response, then extract the authCode. Then: // build the auth code params: final AuthorizationCodeParameters authParams = AuthorizationCodeParameters .builder(authCode, new URI(Config.REDIRECT_URI)).scopes(Collections.singleton(Config.SCOPES)).build(); // Get a client instance and leverage it to acquire the token: final ConfidentialClientApplication client = AuthHelper.getConfidentialClientInstance(); final IAuthenticationResult result = client.acquireToken(authParams).get();
- AuthorizationCodeParameters: Parameters that must be set in order to exchange the Authorization Code for an ID and/or access token.
- authCode: The authorization code that was received at the redirect endpoint.
- REDIRECT_URI: The redirect URI used in the previous step must be passed again.
- SCOPES: The scopes used in the previous step must be passed again.
-
If
acquireToken
is successful, the token claims are extracted. If the nonce check passes, the results are placed incontext
(an instance ofIdentityContextData
) and saved to the session. The application can then instantiate this from the session (by way of an instance ofIdentityContextAdapterServlet
) whenever it needs access to it:// parse IdToken claims from the IAuthenticationResult: // (the next step - validateNonce - requires parsed claims) context.setIdTokenClaims(result.idToken()); // if nonce is invalid, stop immediately! this could be a token replay! // if validation fails, throws exception and cancels auth: validateNonce(context); // set user to authenticated: context.setAuthResult(result, client.tokenCache().serialize());
See AuthenticationFilter.java
for how the sample app filters access to routes. In the authentication.properties
file, the key app.protect.authenticated
contains the comma-separated routes that are to be accessed by authenticated users only.
# e.g., /token_details requires any user to be signed in and does not require special roles or groups claim(s)
app.protect.authenticated=/token_details
When the user navigates to /call_graph
, the application creates an instance of the IGraphServiceClient (Java Graph SDK), passing along the signed-in user's access token. The Graph client from hereon places the access token in the Authorization headers of its requests. The app then asks the Graph Client to call the /me
endpoint to yield details for the currently signed-in user.
The following code is all that is required for an application developer to write for accessing the /me
endpoint, provided that they already have a valid access token for Graph Service with the User.Read
scope.
//CallGraphServlet.java
User user = GraphHelper.getGraphClient(contextAdapter).me().buildRequest().get();
- Scopes tell Azure AD the level of access that the application is requesting.
- Based on the requested scopes, Azure AD presents a consent dialogue to the user upon signing in.
- If the user consents to one or more scopes and obtains a token, the scopes-consented-to are encoded into the resulting
access_token
. - Note the scope requested by the application by referring to authentication.properties. By default, the application sets the scopes value to
User.Read
. - This particular MS Graph API scope is for accessing the information of the currently-signed-in user. The graph endpoint for accessing this info is
https://graph.microsoft.com/v1.0/me
- Any valid requests made to this endpoint must bear an
access_token
that contains the scopeUser.Read
in the Authorization header.
Follow this guide to deploy this app to Azure App Service.
-
Microsoft identity platform (Azure Active Directory for developers)
-
Quickstart: Register an application with the Microsoft identity platform (Preview)
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 [azure-active-directory
ms-identity
adal
msal
].
If you find a bug in the sample, please raise the issue on GitHub Issues.
To provide a recommendation, visit the following User Voice page.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com