Skip to content

Acquiring Tokens

Jean-Marc Prieur edited this page Oct 18, 2018 · 38 revisions

Acquiring a token: this depends on the kind of application

There are many ways of acquiring a token. They are detailed in the next topics. Some require user interactions through a web browser. Some don't require any user interactions. In general the way to acquire a token is different depending on if the application is a public client application (Desktop / Mobile) or a confidential client application (Web App, Web API, daemon application like a windows service)

MSAL.NET caches tokens

For both Public client and confidential client applications, MSAL.NET maintains a token cache (or two caches in the case of confidential client applications), and applications should try to get a token from the cache first before any other means, except in the case of Client Credentials, which does look at the application cache.

In the case of UWP, Xamarin iOS and Xamarin Android, the token cache serialization to an isolated storage is provided by MSAL.NET. In the case of .NET Desktop (.NET Framework and .NET Core) platforms, though, the application needs to customize the token cache serialization.

Public client application:

  • will often acquire token interactively, having the user sign-in.

    Remember that this is not possible yet in .NET Core as .NET core does not provide UI capabilities and this is required for interactive authentication

  • But it's also possible for a desktop application running on a Windows machine which is joined to a domain or to Azure AD, to get a token silently for the user signed-in on the machine, leveraging Windows Integrated Authentication (WIA/Kerberos).
  • On .NET framework desktop client applications , it's also possible (but not recommended) to get a token with a username and password (U/P).

    Note that you should not use username/password in confidential client applications

  • Finally, for applications running on devices which don't have a Web browser, it's possible to acquire a token through the device code flow mechanism, which provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs-in, which has Azure AD get them a token back on the browser-less device.
Summary for public client applications

The following table summarizes the ways available to acquire tokens in public client applications depending on the Operating system, and therefore the chosen platform, and the kind of application.

Operating System Library Platform Kind of App Interactive Auth IWA U/P Device Code
Windows desktop .NET Framework Desktop (WPF, Windows.Forms, Console) Y Y Y (Y)
Windows 10 UWP Store app Y Y
Windows 8.1 WinRT Win 8.1 Store App Y Y
Android Xamarin Android Mobile Y
iOS Xamarin iOS Mobile Y Y (iOT)
Mac OS, Linux, Windows .NET Core Console N/C Y

Confidential client applications will rather:

  • Acquire token for the application itself, not for a user, using client credentials, which can be an application secret or a certificate. This can be used for syncing tools, or tools which process users in general, not a particular user.
  • In the case of Web Apps or Web APIs calling the Microsoft Graph in the name of the user (and, in the future, calling another Web API in the name of the user), using the On Behalf Of flow and still identifying the application itself with client credentials to acquire a token based on some User assertion (SAML for instance, or a JWT token). This can be used for applications which need to access resources of a particular user in service to service calls.
  • For Web apps, acquire tokens by authorization code after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an open id connect application, which lets the user sign-in using Open ID connect, but then wants to access Web APIs for this particular user.
summary for confidential client applications

The following table summarizes the ways available to acquire tokens in confidential client applications depending on the Operating system, and therefore the chosen platform, and the kind of application.

Operating System Library Platform Kind of App Client Credential On behalf of Auth Code
Windows .NET Framework Web App Y Y
Windows, MacOS, Linux (ASP).NET Core Web App Y Y
Windows .NET Framework Web API Y Y
Windows, MacOS, Linux (ASP).NET Core Web API Y Y
Windows .NET Framework Daemon app (windows service) Y
Windows, MacOS, Linux .NET Core Daemon Y

AuthenticationResult properties in MSAL.NET

In all cases above, methods to acquire tokens return an AuthenticationResult (or in the case of the async methods a Task<AuthenticationResult>.

In MSAL.NET, AuthenticationResult exposes:

  • AccessToken for the Web API to access resources. This is a string, usually a base64 encoded JWT but the client should never look inside the access token. The format isn't guaranteed to remain stable and it can be encrypted for the resource. People writing code depending on access token content on the client is one of the biggest sources of errors and client logic breaks
  • IdToken for the user (this is a JWT)
  • ExpiresOn tells the date/time when the token expires
  • TenantId contains the tenant in which the user was found. Note that in the case of guest users (Azure AD B2B scenarios), the TenantId is the guest tenant, not the unique tenant. When the token is delivered in the name of a user, AuthenticationResult also contains information about this user. For confidential client flows where tokens are requested with no user (for the application), this User information is null.
  • The Scopes for which the token was issued (See Scopes not resources)
  • The unique Id for the user.

IUser (MSAL 1.x)

The information about the user is also simpler than in ADAL.NET:

  • The displayable id
  • The unique identifier (named Identifier)
  • The identity provider
  • And the name (given name)

image

IAccount (MSAL 2.x)

MSAL.NET 2.x now defines the notion of Account (through the IAccount interface). This breaking change provides the right semantics: the fact that the same user can have several accounts, in different Azure AD directories. Also MSAL.NET provides better information in the case of guest scenarios, as home account information is provided. The following diagram shows the structure of the IAccount interface:

image

The AccountId class identifies an account in a specific tenant. It has the following properties:

Property Description
TenantId A string representation for a GUID, which is the ID of the tenant where the account resides
ObjectId A string representation for a GUID which is the ID of the user who owns the account in the tenant
Identifier Unique identifier for the account (this is the concatenation of ObjectId and TenantId separated by a comma and are not base64 encoded)

The IAccount interface represents information about a single account. The same user can be present in different tenants, that is, a user can have multiple accounts. Its members are:

Property Description
Username A string containing the displayable value in UserPrincipalName (UPN) format, for example, john.doe@contoso.com. This can be null, whereas the HomeAccountId and HomeAccountId.Identifier won’t be null. This property replaces the DisplayableId property of IUser in previous versions of MSAL.NET.
Environment A string containing the identity provider for this account, for example, login.microsoftonline.com. This property replaces the IdentityProvider property of IUser, except that IdentityProvider also had information about the tenant (in addition to the cloud environment), whereas here this is only the host.
HomeAccountId AccountId of the home account for the user. This uniquely identifies the user across AAD tenants.

Getting started with MSAL.NET

Acquiring tokens

Desktop/Mobile apps

Web Apps / Web APIs / daemon apps

Advanced topics

News

FAQ

Other resources

Clone this wiki locally