快速入門:保護 ASP.NET Core Web API

在這個快速入門中,您將使用 Microsoft.Identity.Web 和 Microsoft Entra ID 保護一個 ASP.NET Core Web API。 你加入驗證中介軟體,驗證持有憑證並限制授權呼叫者的存取。

如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

先決條件

選項一:從範本建立(最快)

使用內建 Microsoft Entra 認證的 ASP.NET Core 範本,來架構受保護的 API 專案。

1. 建立專案

執行以下指令建立一個新的 Web API 專案,並以單一組織認證,並進入專案目錄:

dotnet new webapi --auth SingleOrg --name MyWebApi
cd MyWebApi

2. 設定應用程式註冊

請將 appsettings.json 中的佔位值替換成你的 Microsoft Entra 應用程式註冊資料:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  }
}

3. 執行 API

開始申請:

dotnet run

您的 API 現在受保護於 https://localhost:5001

完成! 請求現在需要有效的存取令牌。


選項二:新增現有的網頁 API

如果你已經有 ASP.NET Core 網頁 API,請依以下步驟加入 Microsoft Entra 認證。

1. 安裝 NuGet 套件

加上 Microsoft。Identity.Web NuGet 套件用於您的專案:

dotnet add package Microsoft.Identity.Web

2. 在 Program.cs中設定認證

在您的應用程式啟動流程中註冊認證與授權服務。 以下程式碼配置 JWT 承載認證與 Microsoft Entra 驗證:

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

var builder = WebApplication.CreateBuilder(args);

// Add authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");

// Add authorization
builder.Services.AddAuthorization();

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthentication(); //  Add authentication middleware
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 在appsettings.json上加入設定

在您的租戶和應用程式資料中加入 Microsoft Entra 設定區塊。 將 Microsoft.Identity.Web 的日誌層級設為 Information,以協助排除令牌驗證問題:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.Identity.Web": "Information"
    }
  }
}

4. 保護您的 API 端點

將屬性 [Authorize] 套用到需要有效存取權杖的控制器或動作上。

要求所有端點都進行認證:

以下控制器要求所有操作皆有有效的存取權杖,並說明如何存取使用者權利要求:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

[Authorize] //  Require valid access token
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        // Access user information
        var userId = User.FindFirst("oid")?.Value;
        var userName = User.Identity?.Name;

        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = "Protected data"
        });
    }
}

要求特定內視鏡:

使用屬性 [RequiredScope] 來對個別動作強制執行細緻權限:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web;

[Authorize]
[ApiController]
[Route("api/[controller]")]
public class TodoController : ControllerBase
{
    [HttpGet]
    [RequiredScope("access_as_user")] //  Require specific scope
    public IActionResult GetAll()
    {
        return Ok(new[] { "Todo 1", "Todo 2" });
    }

    [HttpPost]
    [RequiredScope("write")] //  Different scope for write operations
    public IActionResult Create([FromBody] string item)
    {
        return Created("", item);
    }
}

5. 執行與測試

啟動應用程式並確認未驗證的請求是否被拒絕:

dotnet run

用像 Postman 或 curl 這類工具來測試。 未驗證請求會返回 401 Unauthorized

curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" https://localhost:5001/api/weatherforecast

成功! 你的 API 現在會驗證承載憑證。


應用程式註冊設定

在你的 API 能夠驗證權杖之前,你需要先註冊 Microsoft Entra 應用程式。 請在 Azure 入口網站依照以下步驟操作。

1. 註冊您的 API

  1. 登入 Azure 入口網站
  2. 請導航至 Microsoft Entra ID>應用程式註冊>新註冊
  3. 輸入名稱(例如「我的網頁 API」)
  4. 選擇 單一租戶 (API 中最常見)
  5. API 無需重定向 URI
  6. 按一下 [註冊]

2. 公開 API 範圍

定義客戶端應用程式在呼叫 API 時可以請求的權限(作用域)。

  1. 在你的 API 應用程式註冊中,請點選 Expose an API
  2. 點選 新增內窺鏡
  3. 接受預設的應用程式 ID URI 或自訂(例如, api://your-api-client-id
  4. 新增一個範圍:
    • 範圍名稱:access_as_user
    • 誰可以同意: 管理員與使用者
    • 管理員同意顯示名稱: 「存取我的網頁 API」
    • 管理員同意說明: 「允許應用程式代表已登入使用者存取網頁API」
  5. 點擊 新增示波器

3. 註明應用程式ID

從應用程式註冊總覽頁面複製 應用程式(客戶端)ID 。 這個值就是你的 ClientIdappsettings.json


建立客戶端應用程式註冊(用於測試)

要測試你的受保護 API,請註冊一個獨立的客戶端應用程式,該應用程式負責取得權杖並呼叫 API。

1. 註冊客戶端應用程式

  1. Microsoft Entra ID>應用程式註冊 中,建立另一個註冊
  2. 命名它(例如「我的 API 用戶端」)
  3. 選擇帳戶類型
  4. 新增重定向 URI: https://localhost:7000/signin-oidc (如果是網頁應用程式)
  5. 按一下 [註冊]

2. 授予 API 權限

授權客戶端應用程式用你定義的範圍呼叫你的 API。

  1. 在客戶端應用程式註冊中,請前往 API 權限
  2. 點選 新增權限>我的 API
  3. 選擇您的 API 註冊
  4. 檢查 access_as_user 範圍
  5. 點擊 新增權限
  6. 點擊 授予管理員同意 (如有需要)

3. 建立客戶端秘密(給機密客戶用)

如果你的客戶端應用程式運行在伺服器上(而非瀏覽器或行動裝置),請建立一個客戶端秘密來進行認證。

  1. 轉到 證書和機密
  2. 點選 新用戶端密鑰
  3. 新增描述和有效期限
  4. 按一下 「新增」
  5. 立刻複製秘密值 ——你將無法再看到它

測試你所受保護的 API

透過發送經過認證的請求,驗證你的 API 是否正確驗證了憑證。

使用 Postman

在 Postman 設定 OAuth 2.0 驗證,獲取權杖並呼叫您的 API。

  1. 在 Postman 中建立新的 HTTP 請求
  2. 設定 OAuth 2.0 認證:
    • 補助類型: 授權碼(用於使用者情境)或用戶端憑證(用於應用程式情境)
    • 認證網址:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • 存取權杖網址:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • 客戶識別碼: 你的客戶應用程式的客戶 ID
    • 客戶秘密: 你的客戶端應用程式的祕密
    • 範圍:api://your-api-client-id/access_as_user
  3. 點擊 「取得新的存取權杖」
  4. 使用憑證來存取你的 API

使用程式碼(C# 範例)

以下範例使用 MSAL.NET 透過客戶端憑證流程取得權杖,並呼叫受保護的 API:

// In a console app or client application
using Microsoft.Identity.Client;

var app = ConfidentialClientApplicationBuilder
    .Create("client-app-id")
    .WithClientSecret("client-secret")
    .WithAuthority("https://login.microsoftonline.com/{tenant-id}")
    .Build();

var result = await app.AcquireTokenForClient(
    new[] { "api://your-api-client-id/.default" }
).ExecuteAsync();

var accessToken = result.AccessToken;

// Use the token to call your API
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", accessToken);

var response = await client.GetAsync("https://localhost:5001/api/weatherforecast");

常見配置選項

Microsoft。Identity.Web 支援多種設定模式以適應不同情境。

設定中需要特定的範圍

您可以不必使用[RequiredScope]屬性,而是可以在appsettings.json中全域設定所需的範圍。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-api-client-id",
    "Scopes": "access_as_user"
  }
}

接受多個租戶的代幣

要接受來自任何 Microsoft Entra 租戶的標記,請將 TenantId 設為 common

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "common",
    "ClientId": "your-api-client-id"
  }
}

配置令牌驗證

如果您的 API 呼叫下游 API(例如 Microsoft Graph),請啟用令牌擷取並設定令牌快取:

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi() // If your API calls other APIs
    .AddInMemoryTokenCaches();

下一步

現在你已經有了受保護的 API,請探索以下主題:

Troubleshooting

401 未經授權

問題: API 即使有 token,也會回傳 401。

可能的原因:

  • 代幣受眾(aud 聲稱)與你的 API 不符 ClientId
  • 代幣已過期
  • 代幣是給錯誤的租戶
  • 缺少所需的範圍

解決方案:jwt.ms 解碼該令牌並驗證說法。 詳細的故障排除請參見 日誌與診斷

AADSTS50013:無效簽章

問題: 令牌簽章驗證失敗。

解決方案:請確保您的TenantIdClientId的資訊正確無誤。 該令牌必須由預期的權威機構發行。 啟用詳細記錄以查看驗證錯誤。

標記中未出現的範圍

問題:[RequiredScope] 屬性失敗。

Solution:

  1. 確認客戶端應用程式對該範圍有權限
  2. 確保已獲得管理員同意(如有需要)
  3. 完整範圍驗證模式請參閱授權指南
  4. 取得令牌時請確認是否已請求該範圍(例如 api://your-api/.default 或特定範圍)

更多:Web API 故障排除指南