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.

Microsoft.Identity.Web adds extension methods that provide convenience services for calling Microsoft Graph or a downstream web API. These methods 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, the following code shows an example of using Microsoft.Identity.Web to do so in a home controller. It calls Microsoft Graph using the REST API (instead of the Microsoft Graph SDK). Usually, you don't need to get a token, you need to build an Authorization header that you add to your request. To get an authorization header, you inject the IAuthorizationHeaderProvider service by dependency injection in your controller's constructor (or your page constructor if you use Blazor), and you use it in your controller actions. This interface has methods that produce a string containing the protocol (Bearer, Pop, ...) and a token. 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 controller methods are protected by an [Authorize] attribute that ensures only authenticated users can use the web app.

[Authorize]
public class HomeController : Controller
{
 readonly IAuthorizationHeaderProvider authorizationHeaderProvider;

 public HomeController(IAuthorizationHeaderProvider authorizationHeaderProvider)
 {
  this.authorizationHeaderProvider = authorizationHeaderProvider;
 }

 // Code for the controller actions (see code below)

}

ASP.NET Core makes IAuthorizationHeaderProvider available by dependency injection.

Here's simplified code for the action of the HomeController, which gets a token to call Microsoft Graph:

[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
 // Acquire the access token.
 string[] scopes = new string[]{"user.read"};
 string accessToken = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);

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

To better understand the code required for this scenario, see the phase 2 (2-1-Web app Calls Microsoft Graph) step of the ms-identity-aspnetcore-webapp-tutorial tutorial.

The AuthorizeForScopes attribute on top of the controller action (or of the Razor page if you use a Razor template) is provided by Microsoft.Identity.Web. It ensures that the user is asked for consent if needed, and incrementally.

There are other complex variations, such as:

  • Calling several APIs.
  • Processing incremental consent and Conditional Access.

These advanced steps are covered in chapter 3 of the 3-WebApp-multi-APIs tutorial.

Next steps

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