Быстрый старт: Защита веб-API ASP.NET Core

В этом кратком руководстве вы защищаете веб-API ASP.NET Core с использованием Microsoft Entra ID и Microsoft.Identity.Web. Вы добавляете аутентификационное промежуточное ПО, которое проверяет токены и ограничивает доступ к авторизованным пользователям.

Если у вас нет подписки на Azure, создайте бесплатную учетную запись перед началом.

Необходимые условия

Вариант 1. Создание из шаблона (самый быстрый)

Используйте шаблон ASP.NET Core со встроенной проверкой подлинности Microsoft Entra, чтобы создать шаблон защищенного проекта API.

1. Создание проекта

Выполните следующие команды, чтобы создать проект веб-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.

Готово! Теперь запросы требуют допустимого токена доступа.


Вариант 2. Добавление в существующий веб-API

Если у вас уже есть веб-API ASP.NET Core, добавьте 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. URI перенаправления для API-интерфейсов не требуется
  6. Щелкните Зарегистрировать.

2. Предоставление области действия API

Определите разрешения (области), которые клиентские приложения могут запрашивать при вызове API.

  1. В регистрации приложения API перейдите к разделу "Предоставление API"
  2. Нажмите кнопку "Добавить область"
  3. Примите URI идентификатора приложения по умолчанию или настройте его (например, api://your-api-client-id)
  4. Добавьте область:
    • Имя области:access_as_user
    • Кто может согласиться: Администраторы и пользователи
    • Отображаемое имя согласия администратора: "Access My Web API"
    • Описание согласия администратора: "Позволяет приложению получать доступ к веб-API от имени пользователя, вошедшего в систему"
  5. Нажмите кнопку "Добавить область"

3. Обратите внимание на идентификатор приложения

Скопируйте идентификатор приложения (клиента) со страницы обзора регистрации приложения. Это значение - ваше ClientId в appsettings.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'а

Настройте проверку подлинности OAuth 2.0 в Postman для получения токена и вызова вашего API.

  1. Создание нового запроса в Postman
  2. Настройте проверку подлинности OAuth 2.0:
    • Тип предоставления: Код авторизации (для контекста пользователя) или учетные данные клиента (для контекста приложения)
    • URL-адрес проверки подлинности:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize
    • URL токена доступа:https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token
    • Идентификатор клиента: Идентификатор клиента клиентского приложения
    • Секрет клиента: Секрет клиентского приложения
    • Размах: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 возвращает 401 даже с токеном.

Возможные причины:

  • Аудитория токенов (aud требование) не соответствует вашему API ClientId.
  • Срок действия токена истек
  • Токен для неправильного тенанта
  • Требуемая область отсутствует

Решение: Декодирование маркера на jwt.ms и проверка утверждений. Подробные сведения об устранении неполадок см. в разделе "Ведение журнала и диагностика ".

AADSTS50013: недопустимая подпись

Проблема: Проверка подписи токена завершается ошибкой.

Решение: Убедитесь, что ваш TenantId и ClientId правильный. Токен должен быть выдан ожидаемым авторитетом. Включите подробное ведение журнала для просмотра ошибок проверки.

Области действия не найдены в токене

Проблема:[RequiredScope] атрибут дает сбой.

Solution:

  1. Убедитесь, что клиентское приложение имеет разрешение на доступ к области
  2. Убедитесь, что согласие администратора предоставлено (при необходимости)
  3. См. Руководство по авторизации для получения полных шаблонов проверки области.
  4. Убедитесь, что диапазон запрашивается при получении токена (например, api://your-api/.default или конкретные диапазоны)

Дополнительные сведения обустранении неполадок с веб-API