Защита размещенного приложения ASP.NET Core Blazor WebAssembly с помощью идентификатора Microsoft Entra

В этой статье объясняется, как создать размещенное решение, использующее идентификатор Microsoft Entra (ME-ID) для проверки подлинности. Blazor WebAssembly В этой статье основное внимание уделяется одному приложению клиента с регистрацией одного клиента Azure.

В этой статье не описывается регистрация идентификатора me-id с несколькими клиентами. Дополнительные сведения см. в разделе "Создание мультитенантного приложения".

В этой статье рассматривается использование клиента Microsoft Entra , как описано в кратком руководстве по настройке клиента. Если приложение зарегистрировано в клиенте Azure Active Directory B2C, как описано в руководстве. Создание клиента Azure Active Directory B2C, но следует инструкциям в этой статье, URI идентификатора приложения управляется по-разному с помощью ME-ID. Дополнительные сведения см. в разделе "Использование клиента Azure Active Directory B2C" этой статьи.

Дополнительные сведения о сценариях безопасности после чтения этой статьи см. в разделе ASP.NET Основных Blazor WebAssembly дополнительных сценариев безопасности.

Пошаговое руководство

В подразделах пошагового руководства объясняется, как:

  • Создание клиента в Azure
  • Регистрация приложения API сервера в Azure
  • Регистрация клиентского приложения в Azure
  • Blazor Создание приложения
  • Изменение конфигурации Server appsettings.json
  • Изменение схемы области маркера доступа по умолчанию
  • Выполнить приложение

Создание клиента в Azure

Следуйте инструкциям в кратком руководстве. Настройка клиента для создания клиента в ME-ID.

Регистрация приложения API сервера в Azure

Зарегистрируйте приложение ME-ID для приложения API сервера:

  1. Перейдите к идентификатору Microsoft Entra в портал Azure. Выберите приложения> Регистрация приложений на боковой панели. Нажмите кнопку Новая регистрация.
  2. Укажите имя приложения (например, Blazor Server ME-ID).
  3. Выберите поддерживаемые типы учетных записей. Можно выбрать Учетные записи только в этом каталоге организации (один клиент).
  4. Приложению API сервера не требуется универсальный код ресурса (URI ) перенаправления в этом сценарии, поэтому оставьте раскрывающийся список "Выбрать платформу " без выбора и не введите универсальный код ресурса (URI перенаправления).
  5. В этой статье предполагается, что приложение зарегистрировано в клиенте Microsoft Entra . Если приложение зарегистрировано в клиенте Azure Active Directory B2C, установлен флажок "Разрешения>предоставить администратору согласие на открытие и offline_access разрешения" присутствует и установлен. Установите флажок, чтобы отключить этот параметр. При использовании клиента Azure Directory флажок отсутствует.
  6. Выберите Зарегистрировать.

Запишите следующие сведения:

  • Идентификатор приложения API сервера (клиента) (например, 00001111-aaaa-2222-bbbb-3333cccc4444).
  • Идентификатор каталога (клиента) (например, aaaabbbb-0000-cccc-1111-dddd2222eeee).
  • Основной домен me-ID/Publisher/Tenant (например, contoso.onmicrosoft.com): домен доступен в качестве домена издателя в колонке фирменной символики портал Azure для зарегистрированного приложения.

В разрешениях API удалите разрешение Microsoft Graph>User.Read, так как приложению API сервера не требуется дополнительный доступ к API для простого входа пользователей и вызов конечных точек API сервера.

В разделе Предоставление API:

  1. Подтвердите или добавьте URI идентификатора приложения в форматеapi://{SERVER API APP CLIENT ID}.
  2. Выберите Добавить область.
  3. Выберите Сохранить и продолжить.
  4. Укажите значение в поле Имя области (например, API.Access).
  5. Укажите значение в поле Отображаемое имя согласия администратора (например, Access API).
  6. Укажите значение в поле Описание согласия администратора (например, Allows the app to access server app API endpoints.).
  7. Убедитесь в том, что параметру Состояние присвоено значение Включено.
  8. Выберите Добавить область.

Запишите следующие сведения:

  • GUID URI идентификатора приложения (например, запись 00001111-aaaa-2222-bbbb-3333cccc4444 из URI идентификатора api://00001111-aaaa-2222-bbbb-3333cccc4444приложения)
  • Имя области (например, API.Access)

Внимание

Если для URI идентификатора приложения используется настраиваемое значение, изменения конфигурации требуются как для приложений, так Server и Client для приложений после создания приложений из Blazor WebAssembly шаблона проекта. Дополнительные сведения см. в разделе "Использование пользовательского URI идентификатора приложения".

Регистрация клиентского приложения в Azure

Зарегистрируйте приложение ME-ID для клиентского приложения:

  1. Перейдите к идентификатору Microsoft Entra в портал Azure. На боковой панели выберите Регистрация приложений. Нажмите кнопку Новая регистрация.
  2. Укажите имя приложения (например, Blazor идентификатор клиента ME-ID).
  3. Выберите поддерживаемые типы учетных записей. Можно выбрать Учетные записи только в этом каталоге организации (один клиент).
  4. Задайте раскрывающийся список URI перенаправления для одностраничного приложения (SPA) и укажите следующий URI перенаправления: https://localhost/authentication/login-callback Если вы знаете URI перенаправления рабочей среды для узла Azure по умолчанию (например, azurewebsites.net) или узла личного домена (к примеру, contoso.com), можно также добавить URI перенаправления рабочей среды одновременно с URI перенаправления localhost. Не забудьте включить номер для портов помимо :443 в любые добавленные URI перенаправления рабочей среды.
  5. В этой статье предполагается, что приложение зарегистрировано в клиенте Microsoft Entra . Если приложение зарегистрировано в клиенте Azure Active Directory B2C, установлен флажок "Разрешения>предоставить администратору согласие на открытие и offline_access разрешения" присутствует и установлен. Установите флажок, чтобы отключить этот параметр. При использовании клиента Azure Directory флажок отсутствует.
  6. Выберите Зарегистрировать.

Примечание.

Указание номера порта для localhost URI перенаправления ME-ID не требуется. Дополнительные сведения см. в разделе об ограничениях и ограничениях URI перенаправления (URL-адрес ответа): исключения Localhost (документация по Entra).

Запишите идентификатор приложения Client (клиента) (например, 11112222-bbbb-3333-cccc-4444dddd5555).

В конфигурациях платформы проверки подлинности>>одностраничное приложение:

  1. Подтвердите наличие URI перенаправления https://localhost/authentication/login-callback .
  2. В разделе неявного предоставления убедитесь, что флажки для маркеров доступа и маркеров идентификатора не выбраны. Неявное предоставление не рекомендуется для Blazor приложений с помощью MSAL версии 2.0 или более поздней версии. Дополнительные сведения см. в статье Защита ASP.NET Core Blazor WebAssembly.
  3. Для остальных параметров можно оставить значения по умолчанию.
  4. Нажмите кнопку "Сохранить", если вы внесли изменения.

В разделе Разрешения API выполните следующие действия:

  1. Убедитесь, что у приложения имеется разрешение Microsoft Graph>User.Read.
  2. Выберите Добавить разрешение, а затем — Мои API.
  3. Выберите приложение API сервера в столбце "Имя" (например, Blazor Server ME-ID). Вы должны быть владельцем регистрации приложения (и регистрации приложения API, если это отдельное приложение), чтобы просмотреть API в области "Мои API" портал Azure. Дополнительные сведения см. в разделе "Назначение владельца приложения" (документация по Microsoft Entra).
  4. Откройте список API.
  5. Разрешите доступ к API (например, API.Access).
  6. Выберите Добавить разрешения.
  7. Нажмите кнопку Предоставить согласие администратора для {имя клиента}. Выберите Да для подтверждения.

Внимание

Если у вас нет полномочий на предоставление согласия администратора клиенту в последнем шаге настройки разрешений API, так как согласие на использование приложения делегировано пользователям, необходимо дополнительно выполнить следующие действия:

  • Приложение должно использовать домен доверенного издателя.
  • В конфигурации приложения Server на портале Azure выберите Предоставление API. В разделе Авторизованные клиентские приложения нажмите на кнопку Добавить клиентское приложение. Добавьте идентификатор приложения Client (клиента) (например, 11112222-bbbb-3333-cccc-4444dddd5555).

Blazor Создание приложения

В пустой папке замените заполнители в следующей команде на записанные ранее сведения и выполните команду в командной оболочке:

dotnet new blazorwasm -au SingleOrg --api-client-id "{SERVER API APP CLIENT ID}" --app-id-uri "{SERVER API APP ID URI GUID}" --client-id "{CLIENT APP CLIENT ID}" --default-scope "{DEFAULT SCOPE}" --domain "{TENANT DOMAIN}" -ho -o {PROJECT NAME} --tenant-id "{TENANT ID}"

Предупреждение

Избегайте использования дефисов (-) в имени {PROJECT NAME} приложения, которое нарушает формирование идентификатора приложения OIDC. Логика в шаблоне проекта Blazor WebAssembly использует имя проекта для идентификатора приложения OIDC в конфигурации решения. Также допускаются название в регистре Pascal (BlazorSample) и использование символов подчеркивания (Blazor_Sample). Дополнительные сведения см. в разделе Тире в качестве разделителей в имени размещенного проекта Blazor WebAssembly. Безопасность OIDC (dotnet/aspnetcore #35337).

Заполнитель Название на портале Azure Пример
{PROJECT NAME} BlazorSample
{CLIENT APP CLIENT ID} Идентификатор приложения (клиента) для приложения Client 11112222-bbbb-3333-cccc-4444dddd5555
{DEFAULT SCOPE} Имя области API.Access
{SERVER API APP CLIENT ID} Идентификатор приложения (клиента) для приложения API сервера 00001111-aaaa-2222-bbbb-3333cccc4444
{SERVER API APP ID URI GUID} GUID URI идентификатора приложения 00001111-aaaa-2222-bbbb-3333cccc4444 (GUID ONLY, соответствует параметру {SERVER API APP CLIENT ID})
{TENANT DOMAIN} Основной домен/домен издателя/домен клиента contoso.onmicrosoft.com
{TENANT ID} Идентификатор каталога (клиента) aaaabbbb-0000-cccc-1111-dddd2222eeee

Выходное расположение, указанное с -o|--output параметром, создает папку проекта, если она не существует и становится частью имени проекта. Не используйте дефис (-) в имени приложения, чтобы не нарушить формирование идентификатора приложения OIDC (см. предупреждение выше).

Внимание

Если для URI идентификатора приложения используется настраиваемое значение, изменения конфигурации требуются как для приложений, так Server и Client для приложений после создания приложений из Blazor WebAssembly шаблона проекта. Дополнительные сведения см. в разделе "Использование пользовательского URI идентификатора приложения".

Выполнить приложение

Запустите приложение из Server проекта. При использовании Visual Studio выполните одно из следующих действий.

  • Щелкните стрелку раскрывающегося списка рядом с кнопкой "Запустить ". Откройте раздел "Настройка запускаемых проектов " из раскрывающегося списка. Выберите параметр "Единый запуск проекта ". Подтвердите или измените проект запускаемого проекта на Server проект.

  • Убедитесь, что Server проект выделен в Обозреватель решений перед началом работы приложения с любым из следующих подходов:

    • Нажмите кнопку Запустить.
    • В меню выберите Отладка>Начать отладку.
    • Нажмите клавишу F5.
  • В командной оболочке перейдите в Server папку проекта решения. dotnet watch Выполните команду (илиdotnet run).

Настройка User.Identity.Name

Руководство в этом разделе описывает необязательное заполнение User.Identity.Name значения из name утверждения.

Server API приложения заполняет User.Identity.Name значение из http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name типа утверждения (например, bbbb0000-cccc-1111-dddd-2222eeee3333@contoso.onmicrosoft.com).

Чтобы настроить приложение на получение значения из типа утверждения name:

Части решения

В этом разделе описываются части решения, созданного на основе Blazor WebAssembly шаблона проекта, и описывается, как решения Client и Server проекты настроены для справки. В этом разделе нет конкретных рекомендаций для базового рабочего приложения, если вы создали приложение с помощью руководства в разделе "Пошаговое руководство ". Руководство в этом разделе полезно для обновления приложения для проверки подлинности и авторизации пользователей. Однако альтернативный подход к обновлению приложения — создать новое приложение из руководства в разделе "Пошаговое руководство " и переместить компоненты, классы и ресурсы приложения в новое приложение.

appsettings.jsonКонфигурация

Этот раздел относится к приложению Server решения.

В файле appsettings.json содержатся параметры для настройки обработчика носителя JWT, используемого для проверки маркеров доступа. Добавьте следующий AzureAd раздел конфигурации:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "{TENANT DOMAIN}",
    "TenantId": "{TENANT ID}",
    "ClientId": "{SERVER API APP CLIENT ID}",
    "CallbackPath": "/signin-oidc",
    "Scopes": "{SCOPES}"
  }
}

Пример:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "contoso.onmicrosoft.com",
    "TenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
    "ClientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
    "CallbackPath": "/signin-oidc",
    "Scopes": "API.Access"
  }
}

Внимание

Server Если приложение зарегистрировано для использования пользовательского URI идентификатора приложения в ME-ID (не в формате api://{SERVER API APP CLIENT ID}по умолчанию), см. раздел "Использование пользовательского URI идентификатора приложения". Изменения требуются как в приложениях Server , так и Client в них.

Пакет проверки подлинности

Этот раздел относится к приложению Server решения.

Поддержка проверки подлинности и авторизации вызовов веб-API ASP.NET Core с платформой Майкрософт identity предоставляется пакетом Microsoft.Identity.Web .

Примечание.

Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

Приложение Server размещенного Blazor решения, созданного на основе Blazor WebAssembly шаблона, включает Microsoft.Identity.Web.UI пакет. Пакет добавляет пользовательский интерфейс для проверки подлинности пользователей в веб-приложениях и не используется платформой Blazor. Server Если приложение не будет использоваться для непосредственной проверки подлинности пользователей, это безопасно удалить ссылку на пакет из Server файла проекта приложения.

Поддержка службы проверки подлинности

Этот раздел относится к приложению Server решения.

Метод AddAuthentication настраивает службы проверки подлинности в приложении и обработчик носителя JWT в качестве метода проверки подлинности по умолчанию. Метод AddMicrosoftIdentityWebApi настраивает службы для защиты веб-API с помощью платформы Майкрософт identity версии 2.0. Этот метод ожидает получить раздел AzureAd в конфигурации приложения, где настроены параметры для инициализации методов аутентификации.

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));

Примечание.

При регистрации одной схемы проверки подлинности схема проверки подлинности автоматически используется в качестве схемы по умолчанию приложения, и не требуется указать схему или AddAuthentication через нее AuthenticationOptions. Дополнительные сведения см. в разделе "Обзор проверки подлинности ядра" ASP.NET и объявление ASP.NET Core (aspnet/Announcements #490).

UseAuthentication и UseAuthorization позволяют обеспечить, что:

  • Приложение пытается проанализировать и проверить маркеры в входящих запросах.
  • Любой запрос, пытающийся получить доступ к защищенному ресурсу без соответствующих учетных данных, завершится ошибкой.
app.UseAuthentication();
app.UseAuthorization();

WeatherForecast контроллер

Этот раздел относится к приложению Server решения.

Контроллер WeatherForecast (Controllers/WeatherForecastController.cs) предоставляет защищенный API с атрибутом, [Authorize] примененным к контроллеру. Важно понять следующее:

  • Атрибут [Authorize] в этом контроллере API является единственной вещью, которая защищает этот API от несанкционированного доступа.
  • Атрибут [Authorize], используемый в приложении Blazor WebAssembly, служит подсказкой для приложения о том, что пользователь должен пройти авторизацию, чтобы приложение работало правильно.
[Authorize]
[ApiController]
[Route("[controller]")]
[RequiredScope(RequiredScopesConfigurationKey = "AzureAd:Scopes")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        ...
    }
}

wwwroot/appsettings.jsonКонфигурация

Этот раздел относится к приложению Client решения.

Конфигурация предоставлена в файле wwwroot/appsettings.json:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/{TENANT ID}",
    "ClientId": "{CLIENT APP CLIENT ID}",
    "ValidateAuthority": true
  }
}

Пример:

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/e86c78e2-...-918e0565a45e",
    "ClientId": "11112222-bbbb-3333-cccc-4444dddd5555",
    "ValidateAuthority": true
  }
}

Пакет проверки подлинности

Этот раздел относится к приложению Client решения.

Когда приложение создается для использования рабочих или учебных учетных записей (SingleOrg), оно автоматически получает ссылку на пакет для библиотеки проверки подлинности Майкрософт (Microsoft.Authentication.WebAssembly.Msal). В пакете содержится набор примитивов, которые помогают приложению проверять подлинность пользователей и получать маркеры для вызова защищенных API.

При добавлении проверки подлинности в приложение вручную добавьте пакет Microsoft.Authentication.WebAssembly.Msal в приложение.

Примечание.

Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.

Пакет Microsoft.Authentication.WebAssembly.Msal транзитивно добавляет пакет Microsoft.AspNetCore.Components.WebAssembly.Authentication в приложение.

Поддержка службы проверки подлинности

Этот раздел относится к приложению Client решения.

HttpClient Добавлена поддержка экземпляров, которые включают маркеры доступа при выполнении запросов к приложениюServer.

В файле Program:

builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI", client => 
        client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
    .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
    .CreateClient("{PROJECT NAME}.ServerAPI"));

Заполнитель {PROJECT NAME} — это имя проекта при создании решения. Например, если укажите имя BlazorSample проекта, создающее имя.HttpClient BlazorSample.ServerAPI

Поддержка проверки подлинности пользователей регистрируется в контейнере службы с помощью метода расширения AddMsalAuthentication, предоставляемого в пакете Microsoft.Authentication.WebAssembly.Msal. Этот метод настраивает службы, необходимые для взаимодействия приложения с поставщиком Identity (IP).

В файле Program:

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

Метод AddMsalAuthentication принимает обратный вызов для настройки параметров, необходимых для проверки подлинности приложения. Значения, необходимые для настройки приложения, можно получить из конфигурации ME-ID портала Azure при регистрации приложения.

Области маркеров доступа

Этот раздел относится к приложению Client решения.

Области маркеров доступа по умолчанию представляют собой список областей маркеров доступа, которые:

  • Включен в запрос на вход.
  • используются для предоставления маркера доступа сразу после проверки подлинности.

Дополнительные области можно добавить по мере необходимости в Program файле:

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.DefaultAccessTokenScopes.Add("{SCOPE URI}");
});

Укажите дополнительные области с помощью AdditionalScopesToConsent:

options.ProviderOptions.AdditionalScopesToConsent.Add("{ADDITIONAL SCOPE URI}");

Примечание.

AdditionalScopesToConsent Не удается подготовить делегированные разрешения пользователя для Microsoft Graph с помощью пользовательского интерфейса согласия идентификатора Microsoft Entra ID, когда пользователь сначала использует приложение, зарегистрированное в Microsoft Azure. Дополнительные сведения см. в статье Использование API Graph с ASP.NET Core Blazor WebAssembly.

Пример области маркера доступа по умолчанию:

options.ProviderOptions.DefaultAccessTokenScopes.Add(
    "api://00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");

Дополнительные сведения см. в следующих разделах статьи Дополнительные сценарии:

Режим входа

Этот раздел относится к приложению Client решения.

По умолчанию платформа использует режим входа в систему и возвращается в режим перенаправления входа, если не удается открыть всплывающее окно. Настройте MSAL для использования режима перенаправления входа, задав для свойства LoginMode MsalProviderOptions значение redirect.

builder.Services.AddMsalAuthentication(options =>
{
    ...
    options.ProviderOptions.LoginMode = "redirect";
});

Параметр по умолчанию — popupи строковое значение не учитывает регистр.

Файл импорта

Этот раздел относится к приложению Client решения.

Пространство имен Microsoft.AspNetCore.Components.Authorization становится доступным для всего приложения с помощью файла _Imports.razor:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared

Страница индексации

Этот раздел относится к приложению Client решения.

Страница индекса (wwwroot/index.html) содержит сценарий, определяющий AuthenticationService в JavaScript. AuthenticationService обрабатывает низкоуровневые сведения о протоколе OIDC. Приложение внутренне вызывает методы, определенные в сценарии для выполнения операций проверки подлинности.

<script src="_content/Microsoft.Authentication.WebAssembly.Msal/AuthenticationService.js"></script>

Компонент приложения

Этот раздел относится к приложению Client решения.

Компонент App (App.razor) аналогичен компоненту App, который находится в приложениях Blazor Server:

  • Компонент CascadingAuthenticationState управляет доступом AuthenticationState к rest приложению.
  • Компонент AuthorizeRouteView гарантирует, что текущий пользователь имеет право доступа к определенной странице или иным образом работать с компонентом RedirectToLogin.
  • Компонент RedirectToLogin управляет перенаправлением неавторизованных пользователей на страницу входа.

Из-за различий в платформе между выпусками ASP.NET Core в этом разделе отсутствует разметка Razor для компонента App (App.razor). Чтобы изучить разметку этого компонента для конкретного выпуска, используйте один из следующих подходов:

  • создайте приложение, подготовленное для проверки подлинности, на основе шаблона проекта по умолчанию Blazor WebAssembly для версии ASP.NET Core, которую предполагается использовать. Изучите компонент App (App.razor) в созданном приложении;

  • изучите компонент App (App.razor) в справочных материалах. Выберите версию из селектора ветви и найдите компонент в ProjectTemplates папке репозитория, так как App расположение компонента изменилось в течение многих лет.

    Примечание.

    По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Компонент RedirectToLogin

Этот раздел относится к приложению Client решения.

Компонент RedirectToLogin (RedirectToLogin.razor):

  • управляет перенаправлением неавторизованных пользователей на страницу входа.
  • Текущий URL-адрес, который пользователь пытается получить доступ, сохраняется таким образом, чтобы его можно было вернуть на ту страницу, если проверка подлинности выполнена успешно:
    • Состояние журнала навигации в ASP.NET Core в .NET 7 или более поздней версии.
    • Строка запроса в ASP.NET Core в .NET 6 или более ранней версии.

Изучите компонент RedirectToLogin в справочных материалах. Расположение компонента изменилось с течением времени, поэтому используйте средства поиска GitHub для поиска компонента.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Компонент LoginDisplay

Этот раздел относится к приложению Client решения.

Компонент LoginDisplay (LoginDisplay.razor) отображается в компоненте MainLayout (MainLayout.razor) и управляет следующими поведениями.

  • Для прошедших проверку подлинности пользователей:
    • Отображает имя текущего пользователя.
    • Отображает ссылку на страницу профиля пользователя в ASP.NET Core Identity.
    • отображает кнопку для выхода из приложения.
  • Для анонимных пользователей:
    • Предоставляет возможность регистрации.
    • Предоставляет возможность входа в систему.

Из-за различий в платформе между выпусками ASP.NET Core в этом разделе отсутствует разметка Razor для компонента LoginDisplay. Чтобы изучить разметку этого компонента для конкретного выпуска, используйте один из следующих подходов:

  • создайте приложение, подготовленное для проверки подлинности, на основе шаблона проекта по умолчанию Blazor WebAssembly для версии ASP.NET Core, которую предполагается использовать. Изучите компонент LoginDisplay в созданном приложении.

  • Изучите компонент LoginDisplay в справочных материалах. Расположение компонента изменилось с течением времени, поэтому используйте средства поиска GitHub для поиска компонента. В качестве шаблонного содержимого используется Hosted со значением true.

    Примечание.

    По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Компонент проверки подлинности

Этот раздел относится к приложению Client решения.

Страница, созданная компонентом Authentication (Pages/Authentication.razor), определяет маршруты, необходимые для обработки различных этапов проверки подлинности.

Компонент RemoteAuthenticatorView:

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Примечание.

В ASP.NET Core в .NET 6 или более поздней версии поддерживается статический анализ со значением NULL и компилятора .NET. До выпуска ASP.NET Core в .NET 6 string тип отображается без обозначения типа NULL (?).

Компонент FetchData

Этот раздел относится к приложению Client решения.

Компонент FetchData показывает, как:

  • подготовить маркер доступа;
  • использовать маркер доступа для вызова API защищенных ресурсов в приложении Server.

Директива @attribute [Authorize] указывает на систему авторизации Blazor WebAssembly, в которой пользователь должен пройти авторизацию для перехода к этому компоненту. Наличие атрибута в приложении Client не мешает вызову API на сервере без соответствующих учетных данных. Приложение Server также должно использовать [Authorize] на соответствующих конечных точках, чтобы правильно защитить их.

IAccessTokenProvider.RequestAccessToken запрашивает маркера доступа, который можно добавить в запрос для вызова API. Если маркер кэшируется или служба может подготовить новый маркер доступа без вмешательства пользователя, запрос маркера будет выполнен. В противном случае запрос маркера завершается ошибкой AccessTokenNotAvailableException, которая перехватывается инструкцией try-catch.

Чтобы получить фактический токен для включения в запрос, приложение должно проверить, что запрос был обработан, вызвав tokenResult.TryGetToken(out var token).

Если запрос был успешным, переменная маркера заполняется маркером доступа. Свойство AccessToken.Value маркера предоставляет строку литерала для включения в заголовок запроса Authorization.

Если маркер не удалось подготовить без взаимодействия с пользователем, в результате чего произошел сбой запроса:

  • ASP.NET Core в .NET 7 или более поздней версии: приложение переходит к AccessTokenResult.InteractiveRequestUrl использованию заданного AccessTokenResult.InteractionOptions , чтобы разрешить обновление маркера доступа.
  • ASP.NET Core в .NET 6 или более ранней версии: результат маркера содержит URL-адрес перенаправления. При переходе по этому URL-адресу пользователь переходит на страницу входа и возвращается к текущей странице после успешной проверки подлинности.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http

...

@code {
    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
    }
}

Использование клиента Azure Active Directory B2C

Если приложение зарегистрировано в клиенте Azure Active Directory B2C, как описано в руководстве. Создание клиента Azure Active Directory B2C, но следует инструкциям в этой статье, URI идентификатора приложения управляется по-разному с помощью ME-ID.

Вы можете проверить тип клиента существующего клиента, выбрав ссылку "Управление клиентами" в верхней части обзора организации ME-ID. Проверьте значение столбца типа клиента для организации. Этот раздел относится к приложениям, которые следуют инструкциям в этой статье, но зарегистрированные в клиенте Azure Active Directory B2C .

Вместо URI идентификатора приложения, соответствующего формату api://{SERVER API APP CLIENT ID OR CUSTOM VALUE}, URI идентификатора приложения имеет формат https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}. Это различие влияет на Client конфигурации приложений:Server

  • Для приложения API сервера задайте Audience в файле параметров приложения (appsettings.json) значение, соответствующее аудитории приложения (URI идентификатора приложения), предоставленному портал Azure без косой черты:

    "Audience": "https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}"
    

    Пример:

    "Audience": "https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444"
    
  • Program В файле Client приложения задайте аудиторию области (URI идентификатора приложения) для сопоставления аудитории приложения API сервера:

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE}/{DEFAULT SCOPE}");
    

    В предыдущей области URI/аудитории идентификатора приложения является https://{TENANT}.onmicrosoft.com/{SERVER API APP CLIENT ID OR CUSTOM VALUE} частью значения, которая не включает косую черту (/) и не включает имя области ({DEFAULT SCOPE}).

    Пример:

    options.ProviderOptions.DefaultAccessTokenScopes
        .Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
    

    В предыдущей области URI/аудитории идентификатора приложения является https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444 частью значения, которая не включает косую черту (/) и не включает имя области (API.Access).

Использование пользовательского URI идентификатора приложения

Если URI идентификатора приложения является пользовательским значением, необходимо вручную обновить URI области маркера доступа по умолчанию в Client приложении и добавить аудиторию в Server конфигурацию ME-ID приложения.

Внимание

Следующая конфигурация не требуется при использовании URI api://{SERVER API APP CLIENT ID}идентификатора приложения по умолчанию.

Пример URI идентификатора urn://custom-app-id-uri приложения и имени API.Accessобласти:

  • Program В файле Client приложения:

    options.ProviderOptions.DefaultAccessTokenScopes.Add(
        "urn://custom-app-id-uri/API.Access");
    
  • Server В appsettings.json приложении добавьте Audience запись только с кодом URI идентификатора приложения и без косой черты:

    "Audience": "urn://custom-app-id-uri"
    

Устранение неполадок

Ведение журнала

Чтобы включить ведение журнала отладки или трассировки для Blazor WebAssembly проверки подлинности, см. раздел Blazor ведения журнала проверки подлинности на стороне клиента ASP.NET Core с селектором версий статьи, установленным для ASP.NET Core 7.0 или более поздней версии.

Распространенные ошибки

  • Неправильная настройка приложения или поставщика Identity (IP)

    Наиболее частые ошибки вызваны неправильной настройкой. Ниже приводятся несколько примеров.

    • В зависимости от требований сценария, отсутствующие или неправильные элементы, такие как центр сертификации, экземпляр, идентификатор арендатора, домен арендатора, идентификатор клиента или URI перенаправления, не позволяют приложению осуществлять проверку подлинности клиентов.
    • Неверные области запросов не позволяют клиентам получать доступ к конечным точкам веб-API сервера.
    • Неправильные или отсутствующие разрешения API сервера не позволяют клиентам получить доступ к конечным точкам веб-API сервера.
    • Запуск приложения на порте, отличном от настроенного в URI перенаправления регистрации приложения IP-адреса. Обратите внимание, что порт не требуется для идентификатора Microsoft Entra и приложения, работающего на localhost адресе тестирования разработки, но конфигурация порта приложения и порт, на котором выполняется приложение, должно соответствовать не-адресамlocalhost .

    В разделах конфигурации этой статьи приведены примеры правильной настройки. Внимательно изучите каждый раздел статьи и проверьте, правильно ли настроено приложение и поставщик удостоверений.

    Если конфигурация верна, выполните приведенные ниже действия.

    • Проанализируйте журналы приложений.

    • Изучите трафик между клиентским приложением и серверным приложением или приложением поставщика удостоверений с помощью инструментов разработчика браузера. Зачастую точное сообщение об ошибке или сообщение с указанием на то, что вызывает проблему, возвращается клиенту с помощью серверного приложения или приложения поставщика удостоверений после выполнения запроса. Руководство по инструментам разработчика можно найти в следующих статьях:

    • В выпусках, в Blazor которых используется веб-токен JSON (JWT), декодирует содержимое маркера, используемого для проверки подлинности клиента или доступа к веб-API сервера в зависимости от места возникновения проблемы. Дополнительные сведения о проверке содержимого JSON Web Token (JWT) см. в этом разделе.

    Команда разработчиков документации реагирует на отзывы о документах и ошибки в статьях (откройте запрос в разделе отзывов на этой странице), но не может предоставить поддержку продукта. Помощь в устранении неполадок в приложении предоставляют несколько общественных форумов поддержки. Мы рекомендуем следующее:

    Указанные выше форумы не принадлежат корпорации Майкрософт и не управляются ею.

    Чтобы сообщить об ошибках с воспроизведением платформы, которые не связаны с безопасностью и конфиденциальностью, откройте запрос с единицей продукта ASP.NET Core. Не открывайте запрос с единицей продукта, пока вы тщательно не изучите причину проблемы и не попытаетесь решить ее самостоятельно или с помощью сообщества на общедоступном форуме поддержки. Единица продукта не способна устранять неполадки отдельных приложений, которые не работают из-за неправильной конфигурации или вариантов использования с участием сторонних служб. Если отчет является конфиденциальным или конфиденциальным в природе или описывает потенциальный недостаток безопасности в продукте, который может использовать злоумышленники, см. статью "Отчеты о проблемах безопасности и ошибках" (dotnet/aspnetcoreрепозиторий GitHub).

  • Несанкционированный клиент для ME-ID

    info: сбой авторизации Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]. Эти требования не выполнены: DenyAnonymousAuthorizationRequirement: требуется прошедший проверку подлинности пользователь.

    Ошибка обратного вызова входа из ME-ID:

    • Ошибка: unauthorized_client
    • Описание: AADB2C90058: The provided application is not configured to allow public clients.

    Чтобы устранить эту ошибку, сделайте следующее:

    1. На портале Azure перейдите к манифесту приложения.
    2. Задайте для атрибута allowPublicClient значение null или true.

Файлы cookie и данные сайта

Файлы cookie и данные сайта могут сохраняться в разных обновлениях приложений и повлиять на тестирование и устранение неполадок. При внесении изменений в код приложения, изменений в учетную запись пользователя у поставщика или изменений конфигурации приложения поставщика очистите следующее:

  • файлы cookie входа пользователей;
  • файлы cookie приложения;
  • кэшированные и сохраненные данные сайта.

Один из подходов, позволяющих предотвратить влияние устаревших файлов cookie и данных сайта на тестирование и устранение неполадок заключается в следующем:

  • Настройка браузера
    • Для тестирования используйте браузер, в котором можно настроить удаление всех файлов cookie и данных сайта при каждом закрытии браузера.
    • Убедитесь, что при любых изменениях в приложении, в данных тестового пользователя или в конфигурации поставщика закрытие браузера выполняется вручную или интегрированной средой разработки.
  • Используйте пользовательскую команду, чтобы открыть браузер в режиме InPrivate или Incognito в Visual Studio:
    • Откройте диалоговое окно Просмотр с помощью, которое можно выбрать с помощью кнопки Запустить в Visual Studio.
    • Нажмите кнопку Добавить.
    • Укажите путь к браузеру в поле Программа. Следующие пути к исполняемым файлам являются типичными расположениями установки для Windows 10. Если браузер установлен в другом расположении или вы используете операционную систему, отличную от Windows 10, укажите путь к исполняемому файлу браузера.
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • В поле "Аргументы" укажите параметр командной строки, который браузер использует для открытия в режиме InPrivate или Incognito. Для некоторых браузеров требуется URL-адрес приложения.
      • Microsoft Edge: используйте -inprivate.
      • Google Chrome: используйте --incognito --new-window {URL}, где {URL} заполнитель является URL-адресом для открытия (например, https://localhost:5001).
      • Mozilla Firefox: используйте -private -url {URL}, где {URL} заполнитель является URL-адресом для открытия (например, https://localhost:5001).
    • Введите имя в поле Понятное имя. Например, Firefox Auth Testing.
    • Выберите кнопку ОК.
    • Чтобы не выбирать профиль браузера для каждой операции тестирования с помощью приложения, задайте профиль по умолчанию с помощью кнопки По умолчанию.
    • Убедитесь, что при любых изменениях в приложении, в данных тестового пользователя или в конфигурации поставщика закрытие браузера выполняется интегрированной средой разработки.

Обновление приложений

Приложения-функции могут перестать работать сразу после обновления пакета SDK для .NET Core на компьютере разработки или обновления версии пакетов в самом приложении. В некоторых случаях в результате важного обновления несогласованные версии пакетов могут привести к нарушению работы приложения. Большинство этих проблем можно исправить следующим образом:

  1. Очистите кэши пакетов NuGet локальных систем, выполнив команду dotnet nuget locals all --clear из командной оболочки.
  2. Удалите папки bin и obj проекта.
  3. Восстановите и перестройте проект.
  4. Удалите все файлы из папки развертывания на сервере, прежде чем повторно развернуть приложение.

Примечание.

Использование версий пакета, несовместимых с требуемой платформой приложения, не поддерживается. Дополнительные сведения о пакете см. на странице коллекций NuGet или обозревателя пакетов FuGet.

Server Запуск приложения

При тестировании и устранении неполадок в размещенном решении Blazor WebAssembly убедитесь, что вы используете приложение из проекта Server.

Проверка пользователя

Следующий User компонент можно использовать непосредственно в приложениях или служить основой для дальнейшей настройки.

User.razor:

@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService

<h1>@AuthenticatedUser?.Identity?.Name</h1>

<h2>Claims</h2>

@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
    <p class="claim">@(claim.Type): @claim.Value</p>
}

<h2>Access token</h2>

<p id="access-token">@AccessToken?.Value</p>

<h2>Access token claims</h2>

@foreach (var claim in GetAccessTokenClaims())
{
    <p>@(claim.Key): @claim.Value.ToString()</p>
}

@if (AccessToken != null)
{
    <h2>Access token expires</h2>

    <p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
    <p id="access-token-expires">@AccessToken.Expires</p>

    <h2>Access token granted scopes (as reported by the API)</h2>

    @foreach (var scope in AccessToken.GrantedScopes)
    {
        <p>Scope: @scope</p>
    }
}

@code {
    [CascadingParameter]
    private Task<AuthenticationState> AuthenticationState { get; set; }

    public ClaimsPrincipal AuthenticatedUser { get; set; }
    public AccessToken AccessToken { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        var state = await AuthenticationState;
        var accessTokenResult = await AuthorizationService.RequestAccessToken();

        if (!accessTokenResult.TryGetToken(out var token))
        {
            throw new InvalidOperationException(
                "Failed to provision the access token.");
        }

        AccessToken = token;

        AuthenticatedUser = state.User;
    }

    protected IDictionary<string, object> GetAccessTokenClaims()
    {
        if (AccessToken == null)
        {
            return new Dictionary<string, object>();
        }

        // header.payload.signature
        var payload = AccessToken.Value.Split(".")[1];
        var base64Payload = payload.Replace('-', '+').Replace('_', '/')
            .PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');

        return JsonSerializer.Deserialize<IDictionary<string, object>>(
            Convert.FromBase64String(base64Payload));
    }
}

Проверка содержимого JSON Web Token (JWT)

Чтобы декодировать JSON Web Token (JWT), используйте средство jwt.ms (Майкрософт). Значения в пользовательском интерфейсе остаются в браузере.

Пример закодированного JWT (сокращено для отображения):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Пример JWT, декодированного инструментом для приложения, которое проходит проверку подлинности в Azure AAD B2C:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
  "exp": 1610059429,
  "nbf": 1610055829,
  "ver": "1.0",
  "iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
  "sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
  "aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
  "iat": 1610055829,
  "auth_time": 1610055822,
  "idp": "idp.com",
  "tfp": "B2C_1_signupsignin"
}.[Signature]

Дополнительные ресурсы