Quickstart: Protect an ASP.NET Core web API with Microsoft identity platform

In this quickstart, you download an ASP.NET Core web API code sample and review its code that restricts access to resources to authorized accounts only. The sample supports authorization of personal Microsoft accounts and accounts in any Azure Active Directory (Azure AD) organization.

Prerequisites

Step 1: Register the application

First, register the web API in your Azure AD tenant and add a scope by following these steps:

  1. Sign in to the Azure portal.
  2. If you have access to multiple tenants, use the Directory + subscription filter in the top menu to select the tenant in which you want to register an application.
  3. Search for and select Azure Active Directory.
  4. Under Manage, select App registrations, then New registration.
  5. Enter a Name for your application, for example AspNetCoreWebApi-Quickstart. Users of your app might see this name, and you can change it later.
  6. Select Register.
  7. Under Manage, select Expose an API
  8. Select Add a scope and select Save and continue to accept the default Application ID URI.
  9. In the Add a scope pane, enter the following values:
    • Scope name: access_as_user
    • Who can consent?: Admins and users
    • Admin consent display name: Access AspNetCoreWebApi-Quickstart
    • Admin consent description: Allows the app to access AspNetCoreWebApi-Quickstart as the signed-in user.
    • User consent display name: Access AspNetCoreWebApi-Quickstart
    • User consent description: Allow the application to access AspNetCoreWebApi-Quickstart on your behalf.
    • State: Enabled
  10. Select Add scope to complete the scope addition.

Step 2: Download the ASP.NET Core project

Step 3: Configure the ASP.NET Core project

In this step, configure the sample code to work with the app registration you created earlier.

  1. Extract the .zip archive into a folder near the root of your drive. For example, into C:\Azure-Samples.

  2. Open the solution in the webapi folder in your code editor.

  3. Open the appsettings.json file and modify the following:

    "ClientId": "Enter_the_Application_Id_here",
    "TenantId": "Enter_the_Tenant_Info_Here"
    
    • Replace Enter_the_Application_Id_here with the Application (client) ID of the application you registered in the Azure portal. You can find Application (client) ID in the app's Overview page.
    • Replace Enter_the_Tenant_Info_Here with one of the following:
      • If your application supports Accounts in this organizational directory only, replace this value with the Directory (tenant) ID (a GUID) or tenant name (for example, contoso.onmicrosoft.com). You can find the Directory (tenant) ID on the app's Overview page.
      • If your application supports Accounts in any organizational directory, replace this value with organizations
      • If your application supports All Microsoft account users, leave this value as common

For this quickstart, don't change any other values in the appsettings.json file.

How the sample works

The web API receives a token from a client application, and the code in the web API validates the token. This scenario is explained in more detail in Scenario: Protected web API.

Startup class

The Microsoft.AspNetCore.Authentication middleware uses a Startup class that's executed when the hosting process initializes. In its ConfigureServices method, the AddMicrosoftIdentityWebApi extension method provided by Microsoft.Identity.Web is called.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(Configuration, "AzureAd");
    }

The AddAuthentication() method configures the service to add JwtBearer-based authentication.

The line containing .AddMicrosoftIdentityWebApi adds Microsoft identity platform authorization to your web API. It's then configured to validate access tokens issued by the Microsoft identity platform endpoint based on the information in the AzureAD section of the appsettings.json configuration file:

appsettings.json key Description
ClientId Application (client) ID of the application registered in the Azure portal.
Instance Security token service (STS) endpoint for the user to authenticate. This value is typically https://login.microsoftonline.com/, indicating the Azure public cloud.
TenantId Name of your tenant or its tenant ID (a GUID), or common to sign in users with work or school accounts or Microsoft personal accounts.

The Configure() method contains two important methods, app.UseAuthentication() and app.UseAuthorization(), that enable their named functionality:

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // more code
    app.UseAuthentication();
    app.UseAuthorization();
    // more code
}

Protect a controller, a controller's method, or a Razor page

You can protect a controller or controller methods using the [Authorize] attribute. This attribute restricts access to the controller or methods by only allowing authenticated users, which means that authentication challenge can be started to access the controller if the user isn't authenticated.

namespace webapi.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase

Validate the scope in the controller

The code in the API then verifies that the required scopes are in the token by using HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);

namespace webapi.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        // The Web API will only accept tokens 1) for users, and 2) having the "access_as_user" scope for this API
        static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);

            // some code here
        }
    }
}

Help and support

If you need help, want to report an issue, or would like to learn about your support options, see Help and support for developers.

Next steps

The GitHub repository that contains this ASP.NET Core web API code sample includes instructions and more code samples that show you how to:

  • Add authentication to a new ASP.NET Core web API
  • Call the web API from a desktop application
  • Call downstream APIs like Microsoft Graph and other Microsoft APIs