Поделиться через


Проверка подлинности и авторизация в ASP.NET Core Blazor

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.

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

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.

Внимание

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

В текущем выпуске см . версию .NET 9 этой статьи.

В этой статье приводятся сведения о поддержке настройки и администрирования функций безопасности в ASP.NET Core для приложений Blazor.

Blazor использует существующие механизмы проверки подлинности ASP.NET Core для установки пользователя identity. Точный механизм зависит от того, как Blazor размещено приложение, на стороне сервера или на стороне клиента.

Сценарии безопасности различаются между кодом авторизации на стороне сервера и клиентом в Blazor приложениях. Для кода авторизации, выполняемого на сервере, проверки авторизации могут применять правила доступа для областей приложения и компонентов. Так как выполнение кода на стороне клиента может быть изменено, код авторизации, выполняемый на клиенте, не может быть доверенным для абсолютного применения правил доступа или управления отображением содержимого на стороне клиента.

Если принудительное применение правил авторизации должно быть гарантировано, не реализуйте проверки авторизации в клиентском коде. Создайте сборку Blazor Web App , которая зависит только от отрисовки на стороне сервера (SSR) для проверок авторизации и применения правил.

Если принудительное применение правил авторизации и безопасность данных и кода должны быть гарантированы, не разрабатывайте клиентское приложение. Blazor Server Создание приложения.

Соглашения об авторизации Razor Pages не применяются к маршрутизируемым компонентам Razor. Если компонент, отличный от routableRazor, внедрен в страницу Razor приложения Pages, соглашения авторизации страницы косвенно влияют на Razor компонент вместе с rest содержимым страницы.

ASP.NET Core Identity предназначен для работы в контексте связи HTTP-запроса и ответа, который обычно не является моделью взаимодействия с клиентом-сервером Blazor приложения. В приложениях ASP.NET Core, применяющих ASP.NET Core Identity для управления пользователями, следует использовать Razor Pages вместо компонентов Razor для пользовательского интерфейса, связанного с Identity, например для регистрации пользователей, входа, выхода и других задач управления пользователями. Сборка Razor компонентов, которые напрямую обрабатывают Identity задачи, возможна для нескольких сценариев, но не рекомендуется или поддерживается корпорацией Майкрософт.

Абстракции ASP.NET Core, например SignInManager<TUser> и UserManager<TUser>, не поддерживаются в компонентах Razor. Дополнительные сведения об использовании ASP.NET Core Identity с Blazorпомощью шаблонов ASP.NET Core Identity см. в серверном Blazor приложении.

Примечание.

Примеры кода в этой статье используют типы ссылок, допускающие значение NULL (NRTs) и статический анализ состояния .NET компилятора NULL, которые поддерживаются в ASP.NET Core в .NET 6 или более поздней версии. При назначении ASP.NET Core 5.0 или более ранней версии удалите обозначение типа NULL (?) из примеров в этой статье.

Безопасное обслуживание конфиденциальных данных и учетных данных

Не сохраняйте секреты приложений, строка подключения, учетные данные, пароли, персональные идентификационные номера (ПИН-коды), частный код .NET/C# или закрытые ключи и маркеры в клиентском коде, который всегда небезопасн. Клиентский Blazor код должен получить доступ к защищенным службам и базам данных через защищенный веб-API, который вы управляете.

В средах тестирования и промежуточной и рабочей среды код на стороне Blazor сервера и веб-API должны использовать безопасные потоки проверки подлинности, которые не поддерживают учетные данные в файлах кода проекта или конфигурации. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. на следующих ресурсах:

Для локальной разработки и тестирования на стороне клиента и сервера используйте средство Диспетчера секретов для защиты конфиденциальных учетных данных.

Управляемые удостоверения для служб Microsoft Azure

Для служб Microsoft Azure рекомендуется использовать управляемые удостоверения. Управляемые удостоверения безопасно проходят проверку подлинности в службах Azure без хранения учетных данных в коде приложения. Дополнительные сведения см. на следующих ресурсах:

Поддержка антифоргерии

Шаблон Blazor :

Компонент AntiforgeryToken отрисовывает маркер антифоргерии как скрытое поле, и этот компонент автоматически добавляется в экземпляры формы (EditForm). Дополнительные сведения см. в разделе ASP.NET Общие сведения о формах CoreBlazor.

Служба AntiforgeryStateProvider предоставляет доступ к маркеру антифоргерии, связанному с текущим сеансом. Вставляет службу и вызывает его GetAntiforgeryToken() метод для получения текущего AntiforgeryRequestToken. Дополнительные сведения см. в статье Вызов веб-API в приложении ASP.NET Core Blazor.

Blazor сохраняет маркеры запроса в состоянии компонента, что гарантирует, что маркеры защиты доступны для интерактивных компонентов, даже если у них нет доступа к запросу.

Примечание.

Устранение неполадок с антифоргерией требуется только при отправке данных формы на сервер, закодированный как application/x-www-form-urlencoded, multipart/form-dataили text/plain так как они являются единственными допустимыми энктипами формы.

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

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

Серверные Blazor приложения настраиваются для обеспечения безопасности таким же образом, как и ASP.NET приложения Core. Дополнительные сведения см. в статьях, посвященных обеспечению безопасности в ASP.NET Core.

Контекст проверки подлинности устанавливается только при запуске приложения, то есть когда приложение сначала подключается к WebSocket через SignalR подключение к клиенту. Проверка подлинности может быть основана на маркере cookie или другом маркере носителя, но проверка подлинности осуществляется через SignalR концентратор и полностью в пределах канала. Контекст проверки подлинности сохраняется в течение всего времени существования канала. Приложения периодически пересматривают состояние проверки подлинности пользователя каждые 30 минут.

Если приложение должно записывать пользователей для пользовательских служб или реагировать на обновления пользователя, см . статью ASP.NET Основных серверных и Blazor Web App дополнительных сценариев безопасности.

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

Внимание

Реализация пользовательского элемента NavigationManager для проверки подлинности во время навигации не рекомендуется. Если приложение должно выполнить пользовательскую логику состояния проверки подлинности во время навигации, используйте пользовательскую AuthenticationStateProvider.

Примечание.

Примеры кода в этой статье используют типы ссылок, допускающие значение NULL (NRTs) и статический анализ состояния .NET компилятора NULL, которые поддерживаются в ASP.NET Core в .NET 6 или более поздней версии. При назначении ASP.NET Core 5.0 или более ранней версии удалите обозначение типа NULL (?) из примеров, приведенных в этой статье.

Встроенная или настраиваемая AuthenticationStateProvider служба получает данные о состоянии проверки подлинности из ASP.NET Core HttpContext.User. Так состояние проверки подлинности интегрируется с существующими соответствующими механизмами проверки подлинности ASP.NET Core.

Дополнительные сведения о проверке подлинности на стороне сервера см. в разделе ASP.NET Проверка подлинности и авторизация CoreBlazor.

IHttpContextAccessor/HttpContext в Razor компонентах

IHttpContextAccessor необходимо избежать интерактивной отрисовки, так как не существует допустимой HttpContext возможности.

IHttpContextAccessor можно использовать для компонентов, которые статически отрисовываются на сервере. Тем не менее, мы рекомендуем избегать его, если это возможно.

HttpContext можно использовать в качестве каскадного параметра только в статически отрисованных корневых компонентах для общих задач, таких как проверка и изменение заголовков или других свойств компонента App (Components/App.razor). Значение всегда null предназначено для интерактивной отрисовки.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

В сценариях, где HttpContext требуется в интерактивных компонентах, рекомендуется передавать данные через постоянное состояние компонента с сервера. Дополнительные сведения см. в разделе ASP.NET Основных серверных и Blazor Web App дополнительных сценариев безопасности.

Не используйте IHttpContextAccessor/HttpContext непосредственно или косвенно в Razor компонентах серверных Blazor приложений. Blazor приложения выполняются вне контекста конвейера ASP.NET Core. Он HttpContext не гарантируется, что он доступен в пределах приложения IHttpContextAccessorи HttpContext не гарантируется, что он будет содержать контекст, который запустил Blazor приложение.

Рекомендуемый подход для передачи состояния Blazor запроса приложению осуществляется через параметры корневого компонента во время первоначальной отрисовки приложения. Кроме того, приложение может скопировать данные в службу с областью действия в событии жизненного цикла инициализации корневого компонента для использования в приложении. Дополнительные сведения см. в разделе ASP.NET Основных серверных и Blazor Web App дополнительных сценариев безопасности.

Критически важный аспект безопасности на стороне Blazor сервера заключается в том, что пользователь, подключенный к заданному каналу, может быть обновлен в какой-то момент после Blazor установки канала, но IHttpContextAccessorне обновляется. Дополнительные сведения об устранении этой ситуации с пользовательскими службами см. в ASP.NET основных и Blazor Web App дополнительных сценариях безопасности.

Общее состояние

Серверные Blazor приложения живут в памяти сервера, а несколько сеансов приложений размещаются в одном процессе. Для каждого сеанса Blazor приложения запускает канал с собственной областью контейнера внедрения зависимостей, поэтому службы с областью действия уникальны для каждого Blazor сеанса.

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

Не рекомендуется совместное использование состояния приложениями на одном сервере с помощью отдельных служб, если только вы не принимаете строгие меры предосторожности, поскольку при таком подходе могут возникать уязвимости, например утечка состояния пользователя между каналами.

Службы с отслеживанием состояния можно использовать в приложениях с отслеживанием состояния, Blazor если они специально предназначены для него. Например, использование однотонного кэша памяти приемлемо, так как кэш памяти требует ключа для доступа к данной записи. Если у пользователей нет контроля над ключами кэша, которые используются с кэшем, состояние, хранящееся в кэше, не утечет между каналами.

Общие рекомендации по управлению состоянием см. в разделе ASP.NET Core Blazor State Management.

Безопасность конфиденциальных данных и учетных данных на стороне сервера

В средах тестирования и промежуточной и рабочей среды код на стороне Blazor сервера и веб-API должны использовать безопасные потоки проверки подлинности, которые не поддерживают учетные данные в файлах кода проекта или конфигурации. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. на следующих ресурсах:

Для локальной разработки и тестирования на стороне клиента и сервера используйте средство Диспетчера секретов для защиты конфиденциальных учетных данных.

шаблон проекта;

Создайте серверное Blazor приложение, следуя инструкциям в статье "Инструментирование для ASP.NET Core Blazor".

Выбрав шаблон приложения на стороне сервера и настроив проект, выберите проверку подлинности приложения в разделе "Проверка подлинности".

  • Нет (по умолчанию): проверка подлинности отсутствует.
  • Отдельные учетные записи: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
  • Нет (по умолчанию): проверка подлинности отсутствует.
  • Отдельные учетные записи: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
  • Платформа Майкрософтidentity: дополнительные сведения см. в разделе ASP.NET Проверка подлинности и авторизация CoreBlazor.
  • Windows: используйте проверку подлинности Windows.

BlazorIdentity Пользовательский интерфейс (отдельные учетные записи)

Blazorподдерживает создание полного BlazorIdentity пользовательского интерфейса при выборе параметра проверки подлинности для отдельных учетных записей.

Код Blazor Web App шаблонов Identity для базы данных SQL Server. Версия командной строки использует SQLite и включает базу данных SQLite для Identity.

Шаблон:

  • Поддерживает интерактивные сценарии отрисовки на стороне сервера (интерактивная служба SSR) и клиентских сценариев отрисовки (CSR) с прошедшими проверку подлинности пользователями.
  • Добавляет IdentityRazor компоненты и связанную логику для обычных задач проверки подлинности, таких как вход пользователей и выход. Компоненты Identity также поддерживают расширенные Identity функции, такие как подтверждение учетной записи и восстановление паролей и многофакторная проверка подлинности с помощью стороннего приложения. Обратите внимание, что Identity сами компоненты не поддерживают интерактивность.
  • IdentityДобавляет связанные пакеты и зависимости.
  • Ссылается на Identity пакеты в _Imports.razor.
  • Создает пользовательский класс пользователя Identity (ApplicationUser).
  • Создает и регистрирует EF Core контекст базы данных (ApplicationDbContext).
  • Настраивает маршрутизацию для встроенных Identity конечных точек.
  • Включает Identity проверку и бизнес-логику.

Чтобы проверить Blazor компоненты платформыIdentity, получите доступ к ним в Pages папке и Shared папках Account в шаблоне Blazor Web App проекта (источник ссылки).

При выборе режимов интерактивного веб-просмотра или интерактивного автоматического отрисовки сервер обрабатывает все запросы проверки подлинности и авторизации, а Identity компоненты отображаются статически на сервере в Blazor Web Appосновном проекте.

Платформа предоставляет настраиваемый AuthenticationStateProvider в проектах сервера и клиента (.Client) для потока состояния проверки подлинности пользователя в браузер. Серверный проект вызывает AddAuthenticationStateSerialization, а клиентский проект вызывает AddAuthenticationStateDeserialization. Проверка подлинности на сервере, а не клиент позволяет приложению получать доступ к состоянию проверки подлинности во время предварительной подготовки и до инициализации среды выполнения .NET WebAssembly. Пользовательские AuthenticationStateProvider реализации используют службу состояния сохраняемого компонента (PersistentComponentState) для сериализации состояния проверки подлинности в примечаниях HTML, а затем считывает ее обратно из WebAssembly для создания нового AuthenticationState экземпляра. Дополнительные сведения см. в Blazor Web App разделе "Управление состоянием проверки подлинности".

Только для решений интерактивного сервера (эталонный источник) — это серверная сторонаAuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider которая обновляет метку безопасности для подключенного пользователя каждые 30 минут.

При выборе режимов интерактивного веб-просмотра или интерактивного автоматического отрисовки сервер обрабатывает все запросы проверки подлинности и авторизации, а Identity компоненты отображаются статически на сервере в Blazor Web Appосновном проекте. Шаблон проекта содержит класс (источник ссылки) в .Client проекте для синхронизации состояния проверки подлинности пользователя между сервером PersistentAuthenticationStateProvider и браузером. Класс представляет собой пользовательскую реализацию AuthenticationStateProvider. Поставщик использует службу состояния сохраняемого компонента (PersistentComponentState) для предварительной подготовки состояния проверки подлинности и сохранения его на странице.

В основном проекте Blazor Web Appпоставщика состояния проверки подлинности называется либоIdentityRevalidatingAuthenticationStateProvider (эталонный источник) (только решения для взаимодействия сервера), либо PersistingRevalidatingAuthenticationStateProvider (эталонный источник) (WebAssembly или автоматические интерактивные решения).

BlazorIdentityDbContext зависит от экземпляров, не созданных фабрикой, которая является преднамеренной, так как DbContext достаточно для компонентов шаблона Identity проекта для статического отображения без поддержки интерактивности.

Описание того, как глобальные режимы интерактивной отрисовки применяются к некомпонентамIdentity, одновременно применяя статический SSR для Identity компонентов, см. в разделе ASP.NET Режимы отрисовки CoreBlazor.

Дополнительные сведения о сохранении предопределенного состояния см. в разделе "Предварительная ASP.NET Основные Razor компоненты".

Дополнительные сведения об пользовательском BlazorIdentity интерфейсе и рекомендациях по интеграции внешних имен входа через социальные веб-сайты см. в статье "Новые возможности" identity в .NET 8.

Примечание.

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

Управление состоянием проверки подлинности в Blazor Web Apps

Этот раздел относится к Blazor Web Appследующим:

  • Отдельные учетные записи
  • Отрисовка на стороне клиента (CSR, взаимодействие на основе WebAssembly).

Поставщик состояния проверки подлинности на стороне клиента используется только внутри Blazor и не интегрирован с системой проверки подлинности ASP.NET Core. Во время предварительной подготовки учитывает метаданные, Blazor определенные на странице, и использует систему проверки подлинности ASP.NET Core, чтобы определить, прошел ли пользователь проверку подлинности. Когда пользователь переходит с одной страницы на другую, используется поставщик проверки подлинности на стороне клиента. Когда пользователь обновляет страницу (полная перезагрузка), поставщик состояния проверки подлинности на стороне клиента не участвует в решении проверки подлинности на сервере. Так как состояние пользователя не сохраняется сервером, состояние проверки подлинности, поддерживаемое клиентом, теряется.

Для этого лучше всего выполнить проверку подлинности в системе проверки подлинности ASP.NET Core. Поставщик состояния проверки подлинности на стороне клиента учитывает только состояние проверки подлинности пользователя. Примеры того, как это сделать с помощью поставщиков состояний проверки подлинности, демонстрируются шаблоном Blazor Web App проекта и описаны ниже.

В файле проекта Program сервера вызов AddAuthenticationStateSerialization, который сериализует AuthenticationState возвращаемый сервером AuthenticationStateProvider сервером компонент с помощью службы состояния сохраняемого компонента (PersistentComponentState):

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization();

API сериализует только серверное имя и утверждения роли для доступа в браузере. Чтобы включить все утверждения, установите SerializeAllClaims значение true в вызове AddAuthenticationStateSerializationна стороне сервера:

builder.Services.AddRazorComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization(
        options => options.SerializeAllClaims = true);

В файле проекта клиента (.Client) вызовAddAuthenticationStateDeserialization, который добавляет AuthenticationStateProvider AuthenticationState место десериализации с сервера с помощью AuthenticationStateData службы сохраняемого состояния компонента (PersistentComponentState).Program В серверном проекте должен быть соответствующий вызов AddAuthenticationStateSerialization .

builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
  • PersistingRevalidatingAuthenticationStateProvider (справочный источник): для Blazor Web Appустройств, использующих интерактивную отрисовку на стороне сервера (интерактивный SSR) и отрисовку на стороне клиента (CSR). Это серверная сторона AuthenticationStateProvider , которая обновляет метку безопасности для подключенного пользователя каждые 30 минут интерактивного канала. Она также использует службу состояния сохраняемого компонента для потока состояния проверки подлинности клиенту, который затем фиксируется в течение времени существования CSR.

  • PersistingServerAuthenticationStateProvider (ссылочный источник): для Blazor Web Apps, которые применяют только CSR. Это серверная сторона AuthenticationStateProvider , которая использует службу состояния сохраняемого компонента для потока состояния проверки подлинности клиенту, который затем исправлен в течение времени существования CSR.

  • PersistentAuthenticationStateProvider (ссылочный источник): для Blazor Web Apps, которые принимают CSR. Это клиентская сторона AuthenticationStateProvider , которая определяет состояние проверки подлинности пользователя путем поиска данных, сохраненных на странице при отрисовке на сервере. Это состояние проверки подлинности исправлено в течение времени существования CSR. Если пользователю нужно войти или выйти, требуется полная перезагрузка страницы. Это предоставляет только имя пользователя и электронную почту в целях отображения. Он не включает маркеры, которые проходят проверку подлинности на сервере при выполнении последующих запросов, которые обрабатываются отдельно с помощью cookie включенного в HttpClient запросы к серверу.

Примечание.

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

Формирование шаблонов Identity

Дополнительные сведения о шаблоне Identity в серверном Blazor приложении см. в разделе "Шаблон Identity " в проектах ASP.NET Core.

Identity Шаблон в серверное Blazor приложение:

Дополнительные утверждения и маркеры от внешних поставщиков

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

Служба приложений Azure в Linux с сервером Identity

При развертывании в Службе приложений Azure в Linux с сервером Identity нужно указать издателя явно. Дополнительные сведения см. в статье "Защита Identity серверной части веб-API для spAs".

Внедрение AuthenticationStateProvider служб, ограниченных компонентом

Не пытайтесь разрешить AuthenticationStateProvider в пользовательской области, так как это приводит к созданию нового экземпляра AuthenticationStateProvider , который неправильно инициализирован.

Чтобы получить доступ AuthenticationStateProvider к службе, ограниченной компонентом, введите @inject AuthenticationStateProvider директиву или [Inject] атрибут и передайте его в службу в качестве параметра. Этот подход гарантирует правильность инициализированного экземпляра приложения для каждого экземпляра пользовательского AuthenticationStateProvider приложения.

ExampleService.cs:

public class ExampleService
{
    public async Task<string> ExampleMethod(AuthenticationStateProvider authStateProvider)
    {
        var authState = await authStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            return $"{user.Identity.Name} is authenticated.";
        }
        else
        {
            return "The user is NOT authenticated.";
        }
    }
}

Зарегистрируйте службу как область действия. В серверном Blazor приложении службы с областью действия имеют время существования, равное длительности канала подключения клиента.

В файле Program:

builder.Services.AddScoped<ExampleService>();

В методе Startup.ConfigureServices в файле Startup.cs:

services.AddScoped<ExampleService>();

Следующий компонент InjectAuthStateProvider:

  • Компонент наследует OwningComponentBase.
  • Он AuthenticationStateProvider внедряется и передается ExampleService.ExampleMethodв .
  • ExampleService разрешено и OwningComponentBase.ScopedServices GetRequiredServiceвозвращает правильный инициализированный экземпляр ExampleService , который существует в течение всего времени существования канала пользователя.

InjectAuthStateProvider.razor:

@page "/inject-auth-state-provider"
@inherits OwningComponentBase
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}
@page "/inject-auth-state-provider"
@inject AuthenticationStateProvider AuthenticationStateProvider
@inherits OwningComponentBase

<h1>Inject <code>AuthenticationStateProvider</code> Example</h1>

<p>@message</p>

@code {
    private string? message;
    private ExampleService? ExampleService { get; set; }

    protected override async Task OnInitializedAsync()
    {
        ExampleService = ScopedServices.GetRequiredService<ExampleService>();

        message = await ExampleService.ExampleMethod(AuthenticationStateProvider);
    }
}

Дополнительные сведения см. в руководстве по OwningComponentBase внедрению зависимостей ASP.NET CoreBlazor.

Неавторизованное отображение содержимого при предварительной подготовке с помощью пользовательского AuthenticationStateProvider

Чтобы избежать отображения несанкционированного содержимого, например содержимого в AuthorizeView компоненте, при предварительном создании с помощью пользовательского AuthenticationStateProviderподхода следует использовать один из следующих подходов:

  • Отключить предварительную отрисовку: укажите режим отрисовки с prerender параметром, заданным false для компонента самого высокого уровня в иерархии компонентов приложения, который не является корневым компонентом.

    Примечание.

    Создание интерактивного корневого компонента, например App компонента, не поддерживается. Поэтому предварительная подготовка не может быть отключена непосредственно компонентом App .

    Для приложений, основанных на шаблоне Blazor Web App проекта, предварительная отрисовка обычно отключена, где Routes компонент используется в App компоненте (Components/App.razor) :

    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    Кроме того, отключите предварительную HeadOutlet отрисовку для компонента:

    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    

    Вы также можете выборочно управлять режимом отрисовки, примененным к экземпляру Routes компонента. Например, см. режимы отрисовки ASP.NET CoreBlazor.

  • Отключить предварительную отрисовку: откройте _Host.cshtml файл и измените render-mode атрибут вспомогательного элемента Serverтега компонента на:

    <component type="typeof(App)" render-mode="Server" />
    
  • Проверка подлинности пользователя на сервере перед началом работы приложения. Чтобы применить этот подход, приложение должно отвечать на первоначальный запрос пользователя с Identityпомощью страницы входа на основе или просмотра и запретить любые запросы к Blazor конечным точкам до тех пор, пока они не будут проверены. Дополнительные сведения см. в разделе "Создание приложения ASP.NET Core с пользовательскими данными, защищенными авторизацией". После проверки подлинности несанкционированное содержимое в предварительно созданных Razor компонентах отображается только в том случае, если пользователь действительно не авторизован для просмотра содержимого.

Управление пользовательским состоянием

Несмотря на слово "состояние" в имени, AuthenticationStateProvider не для хранения общего пользовательского состояния. AuthenticationStateProvider Указывает только состояние проверки подлинности пользователя в приложении, независимо от того, вошли ли они в приложение и вошли в систему как.

Проверка подлинности использует ту же ASP.NET проверки подлинности Core Identity , что Razor и приложения Pages и MVC. Состояние пользователя, хранящееся для потоков ASP.NET Core Identity , без Blazor добавления дополнительного кода в приложение. Следуйте инструкциям в статьях и руководствах по ASP.NET Core Identity , чтобы Identity функции вступают в силу в Blazor частях приложения.

Рекомендации по управлению общим состоянием за пределами ASP.NET Core Identityсм. в разделе ASP.NET Управление состоянием CoreBlazor.

Дополнительные абстракции безопасности

Два дополнительных абстракции участвуют в управлении состоянием проверки подлинности:

Примечание.

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

Управление состоянием проверки подлинности при выходе

Blazor Сервер сохраняет состояние проверки подлинности пользователей на протяжении всего времени существования канала, в том числе на вкладках браузера. Чтобы заранее выключить пользователя на вкладках браузера при выходе пользователя на одну вкладку, необходимо реализовать RevalidatingServerAuthenticationStateProvider (эталонный источник) коротким RevalidationInterval.

Примечание.

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

Срок действия URL-адреса временного перенаправления

Этот раздел относится к Blazor Web Apps.

RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration Используйте параметр, чтобы получить или задать время существования ASP.NET срок действия Core Data Protection для URL-адресов временных перенаправлений, создаваемых Blazor отрисовкой на стороне сервера. Они используются только временно, поэтому время существования должно быть достаточно длинным для клиента, чтобы получить URL-адрес и начать навигацию к нему. Однако оно также должно быть достаточно длинным, чтобы разрешить отклонение часов между серверами. Значение по умолчанию — пять минут.

В следующем примере значение распространяется на семь минут:

builder.Services.AddRazorComponents(options => 
    options.TemporaryRedirectionUrlValidityDuration = 
        TimeSpan.FromMinutes(7));

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

В клиентских приложениях проверки подлинности на стороне Blazor клиента можно обойти, так как все клиентские коды могут быть изменены пользователями. Это верно для всех клиентских технологий приложений, включая платформы SPA JavaScript и собственные приложения для любой операционной системы.

Добавьте следующий код:

Для обработки проверки подлинности используйте встроенную или пользовательскую AuthenticationStateProvider службу.

Дополнительные сведения о проверке подлинности на стороне клиента см. в статье Secure ASP.NET Core Blazor WebAssembly.

Служба AuthenticationStateProvider

AuthenticationStateProvider — это базовая служба, используемая компонентом AuthorizeView и каскадными службами проверки подлинности для получения состояния проверки подлинности для пользователя.

AuthenticationStateProvider — это базовая служба, используемая компонентом AuthorizeView и CascadingAuthenticationState компонентом для получения состояния проверки подлинности для пользователя.

Обычно вы не используете AuthenticationStateProvider напрямую. Выберите подход с использованием компонента AuthorizeView или Task<AuthenticationState>, как описано далее в этой статье. Основной недостаток при использовании AuthenticationStateProvider напрямую заключается в том, что компонент не получает автоматического уведомления при изменении базовых данных о состоянии аутентификации.

Сведения о реализации пользовательского AuthenticationStateProviderрежима см. в разделе ASP.NET Состояние проверки подлинности CoreBlazor, включающее рекомендации по реализации уведомлений об изменении состояния проверки подлинности пользователей.

Получение данных субъекта-участника утверждений пользователя

Служба AuthenticationStateProvider может предоставить данные текущего ClaimsPrincipal пользователя, как показано в следующем примере.

ClaimsPrincipalData.razor:

@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Any())
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

В предыдущем примере:

  • ClaimsPrincipal.Claims возвращает утверждения пользователя (claims) для отображения в пользовательском интерфейсе.
  • Строка, которая получает фамилию пользователя (surname) вызывает ClaimsPrincipal.FindAll с предикатом для фильтрации утверждений пользователя.
@page "/claims-principal-data"
@using System.Security.Claims
@inject AuthenticationStateProvider AuthenticationStateProvider

<h1>ClaimsPrincipal Data</h1>

<button @onclick="GetClaimsPrincipalData">Get ClaimsPrincipal Data</button>

<p>@authMessage</p>

@if (claims.Any())
{
    <ul>
        @foreach (var claim in claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@surname</p>

@code {
    private string? authMessage;
    private string? surname;
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider
            .GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not null && user.Identity.IsAuthenticated)
        {
            authMessage = $"{user.Identity.Name} is authenticated.";
            claims = user.Claims;
            surname = user.FindFirst(c => c.Type == ClaimTypes.Surname)?.Value;
        }
        else
        {
            authMessage = "The user is NOT authenticated.";
        }
    }
}

Если user.Identity.IsAuthenticated имеет значение true, а пользователь является ClaimsPrincipal, можно перечислить утверждения и оценить членство в ролях.

Дополнительные сведения о внедрении зависимостей и службах см. в статье Внедрение зависимостей ASP.NET Core Blazor и Внедрение зависимостей в ASP.NET Core. Сведения о реализации пользовательского AuthenticationStateProviderинтерфейса см. в разделе ASP.NET Состояние проверки подлинности CoreBlazor.

Предоставление состояния аутентификации в качестве каскадного параметра

Если данные о состоянии проверки подлинности необходимы для процедурной логики, например при выполнении действия, активированного пользователем, получите данные о состоянии проверки подлинности, определив каскадный параметр типа Task<AuthenticationState>, как показано в следующем примере.

CascadeAuthState.razor:

@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}
@page "/cascade-auth-state"

<h1>Cascade Auth State</h1>

<p>@authMessage</p>

@code {
    private string authMessage = "The user is NOT authenticated.";

    [CascadingParameter]
    private Task<AuthenticationState>? authenticationState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user?.Identity is not null && user.Identity.IsAuthenticated)
            {
                authMessage = $"{user.Identity.Name} is authenticated.";
            }
        }
    }
}

Если user.Identity.IsAuthenticated имеет значение true, можно перечислить утверждения и оценить членство в ролях.

Task<AuthenticationState> Настройте каскадный параметр с помощью AuthorizeRouteView каскадных служб проверки подлинности и каскадных служб проверки подлинности.

При создании Blazor приложения из одного из Blazor шаблонов проектов с включенной проверкой подлинности приложение включает AuthorizeRouteView и вызов AddCascadingAuthenticationState , показанный в следующем примере. Клиентское Blazor приложение также включает необходимые регистрации служб. Дополнительные сведения представлены в разделе "Настройка несанкционированного содержимого Router " в разделе компонента .

<Router ...>
    <Found ...>
        <AuthorizeRouteView RouteData="routeData" 
            DefaultLayout="typeof(Layout.MainLayout)" />
        ...
    </Found>
</Router>

Program В файле зарегистрируйте каскадные службы проверки подлинности:

builder.Services.AddCascadingAuthenticationState();

Настройте каскадный Task<> AuthenticationStateпараметр с помощью AuthorizeRouteView компонентов и CascadingAuthenticationState компонентов.

При создании Blazor приложения из одного из Blazor шаблонов проектов с включенной проверкой подлинности приложение включает AuthorizeRouteView и CascadingAuthenticationState компоненты, показанные в следующем примере. Клиентское Blazor приложение также включает необходимые регистрации служб. Дополнительные сведения представлены в разделе "Настройка несанкционированного содержимого Router " в разделе компонента .

<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView RouteData="routeData" 
                DefaultLayout="typeof(MainLayout)" />
            ...
        </Found>
    </Router>
</CascadingAuthenticationState>

Примечание.

В выпуске ASP.NET Core 5.0.1 и дальнейших выпусках 5.x компонент Router содержит параметр PreferExactMatches со значением @true. Дополнительные сведения см. в статье Миграция с ASP.NET Core 3.1 на 5.0.

В клиентском Blazor приложении добавьте службы авторизации в Program файл:

builder.Services.AddAuthorizationCore();

В клиентском Blazor приложении добавьте параметры и службы авторизации в Program файл:

builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();

В серверном Blazor приложении службы для параметров и авторизации уже присутствуют, поэтому дальнейшие действия не требуются.

Авторизация

После аутентификации пользователя применяются правила авторизации, которые определяют доступные этому пользователю действия.

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

  • выполнена ли аутентификация (выполнен ли вход);
  • есть ли у пользователя определенная роль;
  • есть ли у пользователя определенное утверждение;
  • выполняются ли требования политики.

Каждый из этих аспектов применяется здесь так же, как в приложениях ASP.NET Core MVC или Razor Pages. Дополнительные сведения о безопасности в ASP.NET Core вы найдете в статьях о безопасности и Identity в ASP.NET Core.

Компонент AuthorizeView

Компонент AuthorizeView избирательно демонстрирует содержимое пользовательского интерфейса в зависимости от того, авторизован ли пользователь. Этот подход полезен, если необходимо отображать данные только для пользователя и не нужно использовать его identity в процедурной логике.

Компонент предоставляет context переменную типа AuthenticationState (@context в Razor синтаксисе), которую можно использовать для доступа к сведениям о входе пользователя:

<AuthorizeView>
    <p>Hello, @context.User.Identity?.Name!</p>
</AuthorizeView>

Кроме того, можно указать другое содержимое для отображения, если пользователь не авторизован с помощью сочетания Authorized параметров и NotAuthorized параметров:

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
        <p><button @onclick="HandleClick">Authorized Only Button</button></p>
    </Authorized>
    <NotAuthorized>
        <p>You're not authorized.</p>
    </NotAuthorized>
</AuthorizeView>

@code {
    private void HandleClick() { ... }
}

AuthorizeView Хотя компонент управляет видимостью элементов на основе состояния авторизации пользователя, он не обеспечивает безопасность самого обработчика событий. В предыдущем примере HandleClick метод связан только с кнопкой, видимой авторизованным пользователям, но не запрещает вызывать этот метод из других мест. Чтобы обеспечить безопасность на уровне метода, реализуйте дополнительную логику авторизации в самом обработчике или в соответствующем API.

Razor компоненты содержимого Blazor Web Appникогда не отображаются <NotAuthorized> при сбое авторизации на стороне сервера во время отрисовки на стороне статического сервера (статический SSR). Серверный конвейер ASP.NET Core обрабатывает авторизацию на сервере. Используйте методы на стороне сервера для обработки несанкционированных запросов. Дополнительные сведения см. в режимах отрисовки ASP.NET CoreBlazor.

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

Разметка на стороне клиента и методы, связанные с нимAuthorizeView, защищены только от просмотра и выполнения в отрисованном пользовательском интерфейсе в клиентских Blazor приложениях. Чтобы защитить авторизованное содержимое и безопасные методы на стороне Blazorклиента, содержимое обычно предоставляется безопасным, авторизованным вызовом веб-API к API сервера и никогда не хранится в приложении. Дополнительные сведения см. в статье "Вызов веб-API" из приложения ASP.NET Core Blazor и дополнительных сценариев безопасности ASP.NET CoreBlazor WebAssembly.

Содержимое Authorized и NotAuthorized может включать произвольные элементы, например другие интерактивные компоненты.

Условия авторизации, такие как роли или правила для выбора вариантов пользовательского интерфейса и доступа к ним, описаны в разделе об авторизации.

Если условия авторизации не указаны, AuthorizeView использует политику по умолчанию:

  • Пользователи, прошедшие проверку подлинности (вошедшего в систему), авторизованы.
  • Пользователи, не прошедшие проверку подлинности (вошедшего в систему), не несанкционированны.

Компонент AuthorizeView можно использовать в компоненте NavMenu (Shared/NavMenu.razor) для отображения компонента NavLink (NavLink), но следует учитывать, что при использовании этого подхода удаляется только элемент списка из отображаемых выходных данных. Пользователь по-прежнему может переходить к компоненту. Реализуйте авторизацию отдельно в целевом компоненте.

Авторизация на основе ролей и политик

Компонент AuthorizeView поддерживает авторизацию на основе ролей или политик.

Для авторизации на основе ролей используйте Roles параметр. В следующем примере пользователь должен иметь утверждение роли для Admin ролей или Superuser ролей:

<AuthorizeView Roles="Admin, Superuser">
    <p>You have an 'Admin' or 'Superuser' role claim.</p>
</AuthorizeView>

Чтобы требовать, чтобы у пользователя были Admin утверждения ролей и Superuser роли, вложенные AuthorizeView компоненты:

<AuthorizeView Roles="Admin">
    <p>User: @context.User</p>
    <p>You have the 'Admin' role claim.</p>
    <AuthorizeView Roles="Superuser" Context="innerContext">
        <p>User: @innerContext.User</p>
        <p>You have both 'Admin' and 'Superuser' role claims.</p>
    </AuthorizeView>
</AuthorizeView>

Предыдущий код устанавливает Context для внутреннего AuthorizeView компонента, чтобы предотвратить конфликт контекста AuthenticationState . Контекст AuthenticationState осуществляется во внешнем AuthorizeView с помощью стандартного подхода для доступа к контексту (@context.User). Доступ к контексту осуществляется внутри AuthorizeView с именованным innerContext контекстом (@innerContext.User).

Дополнительные сведения, включая инструкции по настройке, см. в статье Авторизация на основе ролей в ASP.NET Core.

Для авторизации на основе политик используйте Policy параметр с одним именем политики:

<AuthorizeView Policy="Over21">
    <p>You satisfy the 'Over21' policy.</p>
</AuthorizeView>

Чтобы справиться с ситуацией, когда пользователь должен удовлетворить одну из нескольких политик, создайте политику, которая подтверждает, что пользователь удовлетворяет другим политикам.

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

  • Создайте политику для AuthorizeView подтверждения того, что пользователь удовлетворяет нескольким другим политикам.

  • Вложение политик в несколько AuthorizeView компонентов:

    <AuthorizeView Policy="Over21">
        <AuthorizeView Policy="LivesInCalifornia">
            <p>You satisfy the 'Over21' and 'LivesInCalifornia' policies.</p>
        </AuthorizeView>
    </AuthorizeView>
    

Авторизация на основе утверждений считается особым случаем авторизации на основе политик. Например, вы можете определить политику, которая требует наличия определенного утверждения у пользователя. Дополнительные сведения см. в статье Авторизация на основе политик в ASP.NET Core.

Если ни Policy не Roles указано, AuthorizeView используется политика по умолчанию:

  • Пользователи, прошедшие проверку подлинности (вошедшего в систему), авторизованы.
  • Пользователи, не прошедшие проверку подлинности (вошедшего в систему), не несанкционированны.

Так как сравнения строк .NET чувствительны к регистру, соответствующие имена ролей и политик также учитывает регистр. Например, (верхний регистрA) не рассматривается как та же роль, Admin что admin и (строчная).a

Регистр Pascal обычно используется для имен ролей и политик (например, BillingAdministrator), но использование регистра Pascal не является строгим требованием. Разрешены различные схемы регистра, такие как верблюдьи случаи, кебаб и змеиный случай. Использование пробелов в именах ролей и политик является необычным, но разрешено платформой. Например, billing administrator это необычный формат имени роли или политики в приложениях .NET, но это допустимая роль или имя политики.

Содержимое, отображаемое при асинхронной аутентификации

Blazor позволяет асинхронно определять состояние проверки подлинности. Основной сценарий этого подхода — в клиентских Blazor приложениях, которые запрашивают внешнюю конечную точку для проверки подлинности.

При выполнении AuthorizeView проверки подлинности не отображается содержимое. Чтобы отобразить содержимое во время проверки подлинности, назначьте содержимое параметру Authorizing :

<AuthorizeView>
    <Authorized>
        <p>Hello, @context.User.Identity?.Name!</p>
    </Authorized>
    <Authorizing>
        <p>You can only see this content while authentication is in progress.</p>
    </Authorizing>
</AuthorizeView>

Этот подход обычно не применяется к приложениям на стороне Blazor сервера. Серверные Blazor приложения знают состояние проверки подлинности сразу после установки состояния. Authorizing содержимое может быть предоставлено в компоненте приложения AuthorizeView , но содержимое никогда не отображается.

Атрибут [Authorize]

Атрибут [Authorize] доступен в Razor компонентах:

@page "/"
@attribute [Authorize]

You can only see this if you're signed in.

Внимание

Используется [Authorize] только для @page компонентов, достигнутых через Blazor маршрутизатор. Авторизация выполняется только как аспект маршрутизации и не для дочерних компонентов, которые отображаются на странице. Чтобы разрешить отображение конкретных частей на странице, используйте вместо этого AuthorizeView.

Атрибут [Authorize] также поддерживает авторизацию на основе ролей или политик. Для авторизации на основе ролей примените параметр Roles:

@page "/"
@attribute [Authorize(Roles = "Admin, Superuser")]

<p>You can only see this if you're in the 'Admin' or 'Superuser' role.</p>

Для авторизации на основе политик примените параметр Policy:

@page "/"
@attribute [Authorize(Policy = "Over21")]

<p>You can only see this if you satisfy the 'Over21' policy.</p>

Если ни Policy не Roles указано, [Authorize] используется политика по умолчанию:

  • Пользователи, прошедшие проверку подлинности (вошедшего в систему), авторизованы.
  • Пользователи, не прошедшие проверку подлинности (вошедшего в систему), не несанкционированны.

Если пользователь не авторизован и если приложение не настраивает несанкционированное содержимое с Router помощью компонента, платформа автоматически отображает следующее резервное сообщение:

Not authorized.

Авторизация ресурсов

Чтобы авторизовать пользователей для доступа к ресурсам, передайте данные маршрута запроса в параметр Resource в AuthorizeRouteView.

В содержимом Router.Found запрошенного маршрута:

<AuthorizeRouteView Resource="routeData" RouteData="routeData" 
    DefaultLayout="typeof(MainLayout)" />

Дополнительные сведения о том, как данные состояния авторизации передаются и используются в процедурной логике, см. в статье Предоставление состояния аутентификации в качестве каскадного параметра.

Когда объект AuthorizeRouteView получает данные маршрута для ресурса, политики авторизации получают доступ к RouteData.PageType и RouteData.RouteValues, в результате чего разрешается использовать настраиваемую логику для принятия решений об авторизации.

В следующем примере в AuthorizationOptions создается политика EditUser для конфигурации службы авторизации приложения (AddAuthorizationCore) с помощью следующей логики:

  • Определение того, существует ли значение маршрута с ключом id. Если ключ существует, значение маршрута сохраняется в value.
  • В переменной с именем id сохраните value в виде строки или задайте пустое строковое значение (string.Empty).
  • Если id не является пустой строкой, следует подтвердить, что условия политики соблюдены (возвращается true), если значение строки начинается с EMP. В противном случае следует подтвердить, что политика завершается ошибкой (возвращается false).

В файле Program:

  • Добавьте пространства имен для Microsoft.AspNetCore.Components и System.Linq:

    using Microsoft.AspNetCore.Components;
    using System.Linq;
    
  • Добавьте политику:

    options.AddPolicy("EditUser", policy =>
        policy.RequireAssertion(context =>
        {
            if (context.Resource is RouteData rd)
            {
                var routeValue = rd.RouteValues.TryGetValue("id", out var value);
                var id = Convert.ToString(value, 
                    System.Globalization.CultureInfo.InvariantCulture) ?? string.Empty;
    
                if (!string.IsNullOrEmpty(id))
                {
                    return id.StartsWith("EMP", StringComparison.InvariantCulture);
                }
            }
    
            return false;
        })
    );
    

Предыдущий пример — это упрощенная политика авторизации, используемая исключительно для демонстрации концепции с рабочим примером. Дополнительные сведения о создании и настройке политик авторизации см. в статье Авторизация на основе политик в ASP.NET Core.

В следующем компоненте EditUser ресурс в /users/{id}/edit имеет параметр маршрута для идентификатора пользователя ({id}). Компонент использует предыдущую политику авторизации EditUser, чтобы определить, будет ли значение маршрута id начинаться с EMP. Если id начинается с EMP, политика будет успешно применена, и доступ к компоненту будет разрешен. Если id начинается со значения, отличного от EMP, или если id является пустой строкой, то политика завершается ошибкой и компонент не загружается.

EditUser.razor:

@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

@code {
    [Parameter]
    public string? Id { get; set; }
}
@page "/users/{id}/edit"
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Policy = "EditUser")]

<h1>Edit User</h1>

<p>The "EditUser" policy is satisfied! <code>Id</code> starts with 'EMP'.</p>

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

Настройка несанкционированного содержимого Router с помощью компонента

Компонент Router вместе с компонентом AuthorizeRouteView позволяет приложению указать пользовательское содержимое для следующих ситуаций:

  • пользователь не удовлетворяет условию [Authorize], которое применено к компоненту Отображается разметка для элемента <NotAuthorized>. (атрибут [Authorize] описан в разделе Атрибут [Authorize]);
  • Выполняется асинхронная авторизация. Как правило, это означает, что выполняется проверка подлинности пользователя. Отображается разметка для элемента <Authorizing>.

Внимание

Blazor функции маршрутизатора, которые отображаются <NotAuthorized> и <NotFound> содержимое не работают во время отрисовки на стороне статического сервера (статический SSR), так как обработка запросов на ASP.NET Core по промежуточному по промежуточному слоям не обрабатывается, а Razor компоненты не отображаются вообще для несанкционированных или плохих запросов. Используйте методы на стороне сервера для обработки несанкционированных и плохих запросов во время статического SSR. Дополнительные сведения см. в режимах отрисовки ASP.NET CoreBlazor.

<Router ...>
    <Found ...>
        <AuthorizeRouteView ...>
            <NotAuthorized>
                ...
            </NotAuthorized>
            <Authorizing>
                ...
            </Authorizing>
        </AuthorizeRouteView>
    </Found>
</Router>

Содержимое Authorized и NotAuthorized может включать произвольные элементы, например другие интерактивные компоненты.

Примечание.

Для предыдущей процедуры требуется каскадная регистрация государственных служб проверки подлинности в файле приложения Program :

builder.Services.AddCascadingAuthenticationState();
<CascadingAuthenticationState>
    <Router ...>
        <Found ...>
            <AuthorizeRouteView ...>
                <NotAuthorized>
                    ...
                </NotAuthorized>
                <Authorizing>
                    ...
                </Authorizing>
            </AuthorizeRouteView>
        </Found>
    </Router>
</CascadingAuthenticationState>

Содержимое NotFound, Authorized и NotAuthorized может включать произвольные элементы, например другие интерактивные компоненты.

Если NotAuthorized содержимое не указано, AuthorizeRouteView используется следующее резервное сообщение:

Not authorized.

Приложение, созданное Blazor WebAssembly из шаблона проекта с включенной проверкой RedirectToLogin подлинности, включает компонент, расположенный в <NotAuthorized> содержимом Router компонента. Если пользователь не прошел проверку подлинности (context.User.Identity?.IsAuthenticated != true), RedirectToLogin компонент перенаправляет браузер в конечную точку authentication/login для проверки подлинности. Пользователь возвращается на запрошенный URL-адрес после проверки подлинности с identity помощью поставщика.

Процедурная логика

Если приложению нужно проверять правила авторизации в составе процедурной логики, используйте каскадный параметр с типом Task<AuthenticationState>, чтобы получить ClaimsPrincipal пользователя. Task<AuthenticationState> можно комбинировать для оценки политик с другими службами, например IAuthorizationService.

В следующем примере :

  • Выполняет user.Identity.IsAuthenticated код для пользователей, прошедших проверку подлинности (вошедшего в систему).
  • Выполняет user.IsInRole("admin") код для пользователей в роли "Администратор".
  • Выполняет (await AuthorizationService.AuthorizeAsync(user, "content-editor")).Succeeded код для пользователей, удовлетворяющих политике content-editor.

Серверное Blazor приложение включает соответствующие пространства имен при создании из шаблона проекта. В клиентском Blazor приложении подтвердите наличие Microsoft.AspNetCore.Authorization Microsoft.AspNetCore.Components.Authorization пространств имен в компоненте или в файле приложения _Imports.razor :

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization

ProceduralLogic.razor:

@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}
@page "/procedural-logic"
@inject IAuthorizationService AuthorizationService

<h1>Procedural Logic Example</h1>

<button @onclick="@DoSomething">Do something important</button>

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

    private async Task DoSomething()
    {
        if (authenticationState is not null)
        {
            var authState = await authenticationState;
            var user = authState?.User;

            if (user is not null)
            {
                if (user.Identity is not null && user.Identity.IsAuthenticated)
                {
                    // ...
                }

                if (user.IsInRole("Admin"))
                {
                    // ...
                }

                if ((await AuthorizationService.AuthorizeAsync(user, "content-editor"))
                    .Succeeded)
                {
                    // ...
                }
            }
        }
    }
}

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

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

  • Для авторизации требуется каскадный параметр с типом Task<AuthenticationState>. Чтобы предоставить его, попробуйте использовать CascadingAuthenticationState.

  • Для authenticationStateTask возвращается значение null

Скорее всего, проект не был создан с помощью шаблона на стороне Blazor сервера с включенной проверкой подлинности.

В .NET 7 или более ранних версиях обтекайте <CascadingAuthenticationState> часть дерева пользовательского интерфейса, например вокруг маршрутизатора Blazor :

<CascadingAuthenticationState>
    <Router ...>
        ...
    </Router>
</CascadingAuthenticationState>

В .NET 8 или более поздней версии не используйте CascadingAuthenticationState компонент:

- <CascadingAuthenticationState>
      <Router ...>
          ...
      </Router>
- </CascadingAuthenticationState>

Вместо этого добавьте каскадные службы состояния проверки подлинности в коллекцию служб в Program файле:

builder.Services.AddCascadingAuthenticationState();

Компонент CascadingAuthenticationState (.NET 7 или более ранний) или службы, предоставляемые AddCascadingAuthenticationState (.NET 8 или более поздней версии), предоставляют Task<AuthenticationState> каскадный параметр, который, в свою очередь, получает от базовой AuthenticationStateProvider службы внедрения зависимостей.

личные сведения (PII).

Корпорация Майкрософт использует определение GDPR для персональных данных (GDPR 4.1) при обсуждении персональных данных (PII).

PiI ссылается на любую информацию, связанную с идентифицированным или идентифицируемым физическим лицом. Идентифицируемый физический человек — это тот, кто может быть идентифицирован, прямо или косвенно, с любым из следующих элементов:

  • Имя.
  • Идентификационный номер
  • Координаты расположения
  • Идентификатор в Сети
  • Другие конкретные факторы
    • Физически
    • Физиологический
    • Генетический
    • Психический (психологический)
    • Экономический
    • Культура
    • Общественный identity

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