services | platforms | endpoint | page_type | languages | author | products | description | urlFragment | |||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
active-directory |
Java |
Microsoft identity platform |
sample |
|
ramya25 |
|
Java console application letting users sign-in with their username/password and call Microsoft Graph API |
call-msgraph-with-username-password |
This sample demonstrates how to use Microsoft Authentication Library for Java to:
- Authenticate the user silently using username and password.
- Call to a web API (in this case, the Microsoft Graph)
The application obtains a token through username and password, and then calls the Microsoft Graph to get information about the signed-in user.
Note that Username/Password is needed in some cases (for instance devops scenarios) but it's not recommended because:
- This requires having credentials in the application, which does not happen with the other flows.
- The credentials should only be used when there is a high degree of trust between the resource owner and the client and when other authorization grant types are not available (such as an authorization code).
- Do note that this attempts to authenticate and obtain tokens for users using this flow will often fail with applications registered with Azure AD. Some of the situations and scenarios that will cause the failure are listed below
- When the user needs to consent to permissions that this application is requesting.
- When a conditional access policy enforcing multi-factor authentication is in force.
- Azure AD Identity Protection can block authentication attempts if this user account is compromised.
- The user's password is expired and requires a reset.
While this flow seems simpler than the others, applications using these flows often encounter more problems as compared to other flows.
The modern authentication protocols (SAML, WS-Fed, OAuth and OpenID), in principal, discourage apps from handling user credentials themselves. The aim is to decouple the authentication method from an app. Azure AD controls the login experience to avoid exposing secrets (like passwords) to a website or an app.
This enables IdPs like Azure AD to provide seamless single sign-on experiences, enable users to authenticate using factors other than passwords (phone, face, biometrics) and Azure AD can block or elevate authentication attempts if it discerns that the user’s account is compromised or the user is trying to access an app from an untrusted location and such.
To run this sample, you'll need:
- Working installation of Java and Maven.
- An Internet connection.
- 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 Azure AD tenant. This sample will not work with a Microsoft account (formerly Windows Live account). Therefore, if you signed in to the Azure portal with a Microsoft account and have never created a user account in your directory before, you need to do that now.
Getting started with the sample is easy. It is configured to run out of the box with minimal setup.
To successfully use this sample, you need a working installation of Java and Maven.
From your shell or command line:
git clone https://github.com/Azure-Samples/ms-identity-java-desktop.git
cd "Username-Password-Flow"
To register the project, you can:
- either follow the steps in the paragraphs below
- or use PowerShell scripts that:
- automatically create for you the Azure AD applications and related objects (passwords, permissions, dependencies)
- modify the projects' configuration files.
If you want to use this automation, read the instructions in App Creation Scripts
As a first step you'll need to:
- Sign in to the Azure portal using either a work or school account or a personal Microsoft account.
- 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. Change your portal session to the desired Azure AD tenant.
- In the portal menu, click on All services, and choose Azure Active Directory.
In the next steps, you might need the tenant name (or directory name) or the tenant ID (or directory ID). These are presented in the Properties of the Azure Active Directory window respectively as Name and Directory ID
-
Navigate to the Microsoft identity platform for developers App registrations page.
-
Click New registration.
-
When the Register an application page 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-Console-Application
. - In the Supported account types section, select Accounts in any organizational directory.
- 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 Overview page, find the Application (client) ID value and record it for later. You'll need it to configure the APP_ID value in
UsernamePasswordFlow.Java
later. -
In the Application menu blade, select Manifest, and:
- In the manifest editor, set the
allowPublicClient
property to true - Select Save in the bar above the manifest editor.
- In the manifest editor, set the
-
In the Application menu blade, select API permissions
- Ensure that the User.Read permission is listed in the permissions list (which is automatically added when you register your application).
-
At this stage permissions are assigned correctly but the client app does not allow interaction. Therefore no consent can be presented via UI and accepted to use the service app. Click the Grant/revoke 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 accounts in the tenant. You need to be an Azure AD tenant admin to do this.
In the steps below, ClientID is the same as Application ID or AppId.
- Open the
src\main\resources\application.properties
file - Set the
CLIENT_ID
property to the client ID value you recorded earlier - Set the
USER_NAME
andUSER_PASSWORD
properties to the username and password of the user you wish to authenticate in this sample
From your shell or command line:
$ mvn clean compile assembly:single
This will generate a public-client-msal4j-sample-jar-with-dependencies.jar
file in your /targets directory. Run this using your Java executable like below:
$ java -jar public-client-msal4j-sample-jar-with-dependencies.jar
Simply run the .jar file as described in step 5 or run the main method of UsernamePasswordFlow.java
in your IDE to watch the sample acquire a token for the user you configured.
The code to acquire a token is located entirely in src\main\java\UsernamePasswordFlow.Java
. The public client application is created using the MSAL build pattern, by passing the Application ID, an authority, and an implementation of the token cache interface.
PublicClientApplication pca = PublicClientApplication.builder(clientId)
.authority(authority)
.setTokenCacheAccessAspect(tokenCacheAspect)
.build();
A call to acquire the token is first made using the public client application, by creating a SilentParameters
object to send to the application's acquireTokenSilently()
method. The SilentParameters
builder takes in an account (taken from the token cache) and a set of scopes. acquireTokenSilently()
retrieves that account's token from the cache if one exists and isn't expired. If the token is expired, an attempt to retireve a new token is made if the cache contains a refresh token.
If there is no token in the cache for the given account or some issue occurs when trying to use a refresh token, the code falls back to the username/password flow described below
SilentParameters silentParameters =
SilentParameters
.builder(scope)
.account(account)
.build();
result = pca.acquireTokenSilently(silentParameters).join();
A call to acquire the token is first made using the public client application, by creating a UserNamePasswordParameters
object to send to the application's acquireToken()
method. The UserNamePasswordParameters
builder takes in the username and password of a user, and a set of scopes. acquireToken()
attempts to acquires a token from the authority configured in the application via the username/password authentication.
UserNamePasswordParameters parameters =
UserNamePasswordParameters
.builder(scope, username, password.toCharArray())
.build();
result = pca.acquireToken(parameters).join();
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.
To provide a recommendation, visit the following User Voice page.
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 [email protected] with any additional questions or comments.
For more information, see MSAL4J conceptual documentation.
- Quickstart: Configure a client application to access web APIs
- Understanding Azure AD application consent experiences
- Understand user and admin consent
- About how OAuth 2.0 protocols work in this scenario and other scenarios, see Authentication Scenarios for Azure AD.
For more information about how OAuth 2.0 protocols work in this scenario and other scenarios, see Authentication Scenarios for Azure AD.