受保护的 Web API:代码配置

若要配置受保护 Web API 的代码,请了解:

  • API 受保护的定义是什么。
  • 如何配置持有者令牌。
  • 如何验证令牌。

ASP.NET 和 ASP.NET Core API 受保护是什么意思?

与 Web 应用一样,ASP.NET 和 ASP.NET Core Web API 也受到保护,因为它们的控制器操作以 [Authorize] 属性为前缀。 仅当使用已授权的标识调用 API 时,才能调用控制器操作。

考虑以下问题:

  • 只有应用可以调用 Web API。 API 如何识别调用它的应用的标识?
  • 如果应用代表某个用户调用 API,该用户的标识是什么?

持有者令牌

调用应用时在标头中设置的持有者令牌包含有关应用标识的信息。 除非 Web 应用接受来自守护程序应用的服务到服务调用,否则该令牌还包含有关用户的信息。

以下 C# 代码示例演示了某个客户端在使用适用于 .NET 的 Microsoft 身份验证库 (MSAL.NET) 获取令牌后调用 API:

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);

重要

客户端应用程序向 Web API 的 Microsoft 标识平台请求持有者令牌。 该 API 是唯一应该验证令牌并查看其中包含的声明的应用程序。 客户端应用永远不会尝试检查令牌中的声明。

将来,Web API 可能要求加密令牌。 这项要求会阻止可以查看访问令牌的客户端应用进行访问。

JwtBearer 配置

本部分介绍如何配置持有者令牌。

配置文件

仅当想要接受来自单个租户(业务线应用)的访问令牌时,才需要指定 TenantId。 否则,它可以保留为 common。 可以采用的不同值包括:

  • 一个 GUID(租户 ID = 目录 ID)
  • common 可以是任何组织
  • organizations 可以是任何组织
{
  "AzureAd": {
    "Instance": "https://login.partner.microsoftonline.cn/",
    "ClientId": "Enter_the_Application_(client)_ID_here",
    "TenantId": "common"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

为 Web API 使用自定义应用 ID URI

如果已接受 Azure 门户建议的默认应用 ID URI,则无需指定受众(请参阅应用程序 ID URI 和作用域)。 否则,请添加 Audience 属性,其值为 Web API 的应用 ID URI。 这通常以 api:// 开头。

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

代码初始化

对包含 [Authorize] 属性的控制器操作调用某个应用时,ASP.NET 和 ASP.NET Core 将从 Authorization 标头的持有者令牌中提取访问令牌。 然后,该访问令牌将转发到 JwtBearer 中间件,而该中间件会调用适用于 .NET 的 Microsoft IdentityModel 扩展。

Microsoft.Identity.Web

Microsoft 建议在使用 ASP.NET Core 开发 Web API 时使用 Microsoft.Identity.Web NuGet 包。

Microsoft.Identity.Web 提供 ASP.NET Core、身份验证中间件和适用于 .NET 的 Microsoft 身份验证库 (MSAL) 之间的连接。 它支持更清晰、更强大的开发人员体验,并利用 Microsoft 身份平台和 Azure AD B2C 的强大功能。

ASP.NET for .NET 6.0

若要创建使用 Microsoft.Identity.Web 的新 Web API 项目,请使用 .NET 6.0 CLI 或 Visual Studio 中的项目模板。

Dotnet core CLI

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

Visual Studio - 若要在 Visual Studio 中创建 Web API 项目,请选择“文件”>“新建”>“项目”>“ASP.NET Core Web API”。

.NET CLI 和 Visual Studio 项目模板都会创建一个与此代码片段类似的 Program.cs 文件。 注意 Microsoft.Identity.Web using 指令和包含身份验证和授权的行。

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();