-
Notifications
You must be signed in to change notification settings - Fork 366
Username Password Authentication
In your desktop application you can use the Username/Password flow to acquire a token silently. No UI is required when using the application.
This flow is not recommended because your application asking users for their password is not secure. See this article for more details. The preferred flow for acquiring a token silently on Windows domain joined machines is Integrated Windows Authentication.
Apart from the Integrated Windows Authentication constraints, the following constraints also apply:
- Available starting with MSAL 2.1.0
- The Username/Password flow is not compatible with conditional access and multi-factor authentication. This means that if your app runs in an Azure AD tenant where the tenant admin requires multi-factor authentication, you cannot use this flow (many organization do that)
- It works only for Work and school accounts (not MSA)
- The flow is available on .net desktop and .net core, but not on UWP
PublicClientApplication
contains the method AcquireTokenByUsernamePasswordAsync
You can use an empty username in which case the library will try to query Windows for the AD or AAD joined user. However depending on the way your Windows administrator has setup the policies, it can be possible that applications on your windows machine are not allowed to lookup the logged-in user.
The following sample presents the most current case, with explanations of the kind of exceptions you can get, and their mitigations
static async Task GetATokenForGraph()
{
string authority = "https://login.microsoftonline.com/contoso.com";
string[] scopes = new string[] { "user.read" };
PublicClientApplication app = new PublicClientApplication(clientId, authority);
var accounts = await app.GetAccountsAsync();
AuthenticationResult result = null;
if (accounts.Any())
{
result = await app.AcquireTokenSilentAsync(scopes, accounts.FirstOrDefault());
}
else
{
try
{
var securePassword = new SecureString();
foreach (char c in "dummy") // you should fetch the password keystroke by keystroke
securePassword.AppendChar(c);
result = await app.AcquireTokenByUsernamePasswordAsync(scopes, "[email protected]", securePassword);
}
catch (MsalUiRequiredException ex)
{
// MsalUiRequiredException: AADSTS65001: The user or administrator has not consented to use the application
// with ID '{appId}' named '{appName}'.Send an interactive authorization request for this user and resource.
// Explanation: you need to get user consent for the scopes first.
// Mitigation: This can be done, if you are not using .NET Core (which does not have any Web UI)
// by doing (once only) an AcquireToken interactive.
// If you are don't want to do an AcquireTokenInteractive, you might want to suggest the user to navigate
// to a URL to consent: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read
// Alternatively, configure your application in the AAD portal to not require consent for the respective scope
// MsalUiRequiredException AADSTS50079: The user is required to use multi-factor authentication.
// Explanation: as detailed in the constraints section, U/P auth flow does not deal with conditional access
// Mitigation: use Integrated Windows Authentication if the app runs on domain joined / AAD joined machines
// or Interactive authentication on .NET framework, or Device Code flow otherwise
}
catch (MsalServiceException ex)
{
// Kind of errors you could have (in ex.Message)
// MsalServiceException: AADSTS90010: The grant type is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint.
// you used common.
// Mitigation: as explained in the message from Azure AD, the authoriy needs to be tenanted or otherwise organizations
// MsalServiceException: AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.
// Explanation: this can happen if your application was not registered as a public client application in Azure AD
// Mitigation: in the Azure portal, edit the manifest for your application and set the `allowPublicClient` to `true`
// MsalServiceException: AADSTS50079: The user is required to use multi-factor authentication.
// Explanation: as explained in the constraints section, U/P auth flow does not deal with conditional access
// Mitigation: use Integrated Windows Authentication or revert to ADAL
}
catch (MsalClientException ex)
{
// Error Code: unknown_user Message: Could not identify logged in user
// Explanation: You passed in an empty username and the library was unable to query the current Windows logged-in user or this user is not AD or AAD
// joined (work-place joined users are not supported).
// Mitigation 1: on UWP, check that the application has the following capabilities: Enterprise Authentication,
// Private Networks (Client and Server), User Account Information
// Mitigation 2: Implement your own logic to fetch the username (e.g. [email protected]) and use the
// AcquireTokenByIntegratedWindowsAuthAsync overload that takes in the username
}
}
Console.WriteLine(result.Account.Username);
}
- Home
- Why use MSAL.NET
- Is MSAL.NET right for me
- Scenarios
- Register your app with AAD
- Client applications
- Acquiring tokens
- MSAL samples
- Known Issues
- AcquireTokenInteractive
- WAM - the Windows broker
- .NET Core
- Maui Docs
- Custom Browser
- Applying an AAD B2C policy
- Integrated Windows Authentication for domain or AAD joined machines
- Username / Password
- Device Code Flow for devices without a Web browser
- ADFS support
- Acquiring a token for the app
- Acquiring a token on behalf of a user in Web APIs
- Acquiring a token by authorization code in Web Apps
- High Availability
- Token cache serialization
- Logging
- Exceptions in MSAL
- Provide your own Httpclient and proxy
- Extensibility Points
- Clearing the cache
- Client Credentials Multi-Tenant guidance
- Performance perspectives
- Differences between ADAL.NET and MSAL.NET Apps
- PowerShell support
- Testing apps that use MSAL
- Experimental Features
- Proof of Possession (PoP) tokens
- Using in Azure functions
- Extract info from WWW-Authenticate headers
- SPA Authorization Code