A web app that calls web APIs: Acquire a token for the app

You've built your client application object. Now, you use it to acquire a token to call a web API. In ASP.NET or ASP.NET Core, calling a web API is done in the controller:

  • Get a token for the web API by using the token cache. To get this token, you call the Microsoft Authentication Library (MSAL) AcquireTokenSilent method (or the equivalent in Microsoft.Identity.Web).
  • Call the protected API, passing the access token to it as a parameter.

The code for ASP.NET is similar to the code shown for ASP.NET Core:

  • A controller action, protected by an [Authorize] attribute, extracts the tenant ID and user ID of the ClaimsPrincipal member of the controller (ASP.NET uses HttpContext.User). This ensures that only authenticated users can use the app. Microsoft.Identity.Web adds extension methods to the Controller that provide convenience services to call Microsoft Graph or a downstream web API, or to get an authorization header, or even a token. The methods used to call an API directly are explained in detail in A web app that calls web APIs: Call an API. With these helper methods, you don't need to manually acquire a token.

If, however, you do want to manually acquire a token or build an authorization header, the following code shows how to use Microsoft.Identity.Web to do so in a controller. It calls an API (Microsoft Graph) using the REST API instead of the Microsoft Graph SDK.

To get an authorization header, you get an IAuthorizationHeaderProvider service from the controller using an extension method GetAuthorizationHeaderProvider. To get an authorization header to call an API on behalf of the user, use CreateAuthorizationHeaderForUserAsync. To get an authorization header to call a downstream API on behalf of the application itself, in a daemon scenario, use CreateAuthorizationHeaderForAppAsync.

The following snippet shows the action of the HomeController, which gets an authorization header to call Microsoft Graph as a REST API:

[Authorize]
public class HomeController : Controller
{
 [AuthorizeForScopes(Scopes = new[] { "https://microsoftgraph.chinacloudapi.cn/user.read" })]
 public async Task<IActionResult> Profile()
 {
  // Get an authorization header.
  IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
  string[] scopes = new string[]{"https://microsoftgraph.chinacloudapi.cn/user.read"};
  string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);

  // Use the access token to call a protected web API.
  HttpClient client = new HttpClient();
  client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
  string json = await client.GetStringAsync(url);
 }
}

The following snippet shows the action of the HomeController, which gets an access token to call Microsoft Graph as a REST API:

[Authorize]
public class HomeController : Controller
{
 [AuthorizeForScopes(Scopes = new[] { "https://microsoftgraph.chinacloudapi.cn/user.read" })]
 public async Task<IActionResult> Profile()
 {
  // Get an authorization header.
  ITokenAcquirer tokenAcquirer = TokenAcquirerFactory.GetDefaultInstance().GetTokenAcquirer();
  string[] scopes = new string[]{"https://microsoftgraph.chinacloudapi.cn/user.read"};
  string token = await tokenAcquirer.GetTokenForUserAsync(scopes);

  // Use the access token to call a protected web API.
  HttpClient client = new HttpClient();
  client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
  string json = await client.GetStringAsync(url);
 }
}

Next steps

Move on to the next article in this scenario, Call a web API.