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

You've built your client application object. Now, you'll 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 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). To get a token to call the downstream API, you inject the ITokenAcquisition 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, getting a token for the user (GetAccessTokenForUserAsync) or for the application itself (GetAccessTokenForAppAsync) in a daemon scenario.

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 ITokenAcquisition tokenAcquisition;

 public HomeController(ITokenAcquisition tokenAcquisition)
 {
  this.tokenAcquisition = tokenAcquisition;
 }

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

}

The ITokenAcquisition service is injected by ASP.NET by using 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 tokenAcquisition.GetAccessTokenForUserAsync(scopes);

 // Use the access token to call a protected web API.
 HttpClient client = new HttpClient();
 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", 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.