Protected web API: Code configuration

To configure the code for your protected web API, understand:

  • What defines APIs as protected.
  • How to configure a bearer token.
  • How to validate the token.

What defines ASP.NET and ASP.NET Core APIs as protected?

Like web apps, ASP.NET and ASP.NET Core web APIs are protected because their controller actions are prefixed with the [Authorize] attribute. The controller actions can be called only if the API is called with an authorized identity.

Consider the following questions:

  • Only an app can call a web API. How does the API know the identity of the app that calls it?
  • If the app calls the API on behalf of a user, what's the user's identity?

Bearer token

The bearer token that's set in the header when the app is called holds information about the app identity. It also holds information about the user unless the web app accepts service-to-service calls from a daemon app.

Here's a C# code example that shows a client calling the API after it acquires a token with the Microsoft Authentication Library for .NET (MSAL.NET):

var scopes = new[] {$"api://.../access_as_user"};
var result = await app.AcquireToken(scopes)
                      .ExecuteAsync();

httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);

Important

A client application requests the bearer token to the Microsoft identity platform for the web API. The API is the only application that should verify the token and view the claims it contains. Client apps should never try to inspect the claims in tokens.

In the future, the web API might require that the token be encrypted. This requirement would prevent access for client apps that can view access tokens.

JwtBearer configuration

This section describes how to configure a bearer token.

Config file

You need to specify the TenantId only if you want to accept access tokens from a single tenant (line-of-business app). Otherwise, it can be left as common. The different values can be:

  • A GUID (Tenant ID = Directory ID)
  • common can be any organization and personal accounts
  • organizations can be any organization
  • consumers are Microsoft personal accounts
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "Enter_the_Application_(client)_ID_here",
    "TenantId": "common"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Using a custom App ID URI for a web API

If you've accepted the default App ID URI proposed by the Azure portal, you don't need to specify the audience (see Application ID URI and scopes). Otherwise, add an Audience property whose value is the App ID URI for your web API. This typically starts with api://.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "Enter_the_Application_(client)_ID_here",
    "TenantId": "common",
    "Audience": "Enter_the_Application_ID_URI_here"
  },
}

Code initialization

When an app is called on a controller action that holds an [Authorize] attribute, ASP.NET and ASP.NET Core extract the access token from the Authorization header's bearer token. The access token is then forwarded to the JwtBearer middleware, which calls Microsoft IdentityModel Extensions for .NET.

Microsoft.Identity.Web

Microsoft recommends you use the Microsoft.Identity.Web NuGet package when developing a web API with ASP.NET Core.

Microsoft.Identity.Web provides the glue between ASP.NET Core, the authentication middleware, and the Microsoft Authentication Library (MSAL) for .NET. It allows for a clearer, more robust developer experience and leverages the power of the Microsoft identity platform and Azure AD B2C.

ASP.NET for .NET 6.0

To create a new web API project that uses Microsoft.Identity.Web, use a project template in the .NET 6.0 CLI or Visual Studio.

Dotnet core CLI

# Create new web API that uses Microsoft.Identity.Web
dotnet new webapi --auth SingleOrg

Visual Studio - To create a web API project in Visual Studio, select File > New > Project > ASP.NET Core Web API.

Both the .NET CLI and Visual Studio project templates create a Program.cs file that looks similar to this code snippet. Notice Microsoft.Identity.Web using directive and the lines containing authentication and authorization.

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();