Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. Для текущей версии см. версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. Для текущей версии см. версию .NET 9 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Для текущей версии см. версию .NET 9 этой статьи.
В этой статье приводятся сведения о поддержке настройки и администрирования функций безопасности в ASP.NET Core для приложений Blazor.
Blazor использует существующие механизмы проверки подлинности ASP.NET Core для установления удостоверения пользователя. Точный механизм зависит от того, как Blazor размещено приложение, на стороне сервера или на стороне клиента.
Сценарии безопасности различаются между выполнением кода авторизации на стороне сервера и на стороне клиента в Blazor приложениях. Для кода авторизации, выполняемого на сервере, проверки авторизации могут применять правила доступа для областей приложения и компонентов. Так как выполнение кода на стороне клиента может быть изменено, код авторизации, выполняемый на клиенте, не может быть доверенным для абсолютного применения правил доступа или управления отображением содержимого на стороне клиента.
Если принудительное применение правил авторизации должно быть гарантировано, не реализуйте проверки авторизации в клиентском коде. Создайте Blazor Web App, которая опирается исключительно на серверную отрисовку (SSR) для проверок авторизации и принудительного применения правил.
Если принудительное применение правил авторизации и безопасность данных и кода должны быть гарантированы, не разрабатывайте клиентское приложение. Blazor Server Создайте приложение.
Соглашения об авторизации Razor Pages не применяются к маршрутизируемым компонентам Razor. Если немаршрутизируемый компонент Razorвстроен на страницу приложения Razor Pages, соглашения об авторизации страницы косвенно влияют на компонент Razor вместе с остальным содержимым страницы.
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), и статический анализ состояния null компилятора .NET, которые поддерживаются в ASP.NET Core в .NET 6 или более поздней версии. При использовании .NET 5 или более ранней версии удалите атрибут нулевой типа (?
) из примеров в этой статье.
Безопасное обслуживание конфиденциальных данных и учетных данных
Не сохраняйте секреты приложений, строка подключения, учетные данные, пароли, персональные идентификационные номера (ПИН-коды), частный код .NET/C# или закрытые ключи и маркеры в клиентском коде, который всегда небезопасн. Клиентский Blazor код должен получить доступ к защищенным службам и базам данных через защищенный веб-API, который вы управляете.
В тестовых, промежуточных и рабочих средах код на стороне Blazor сервера и веб-API должен использовать безопасные потоки аутентификации, которые избегают хранения учетных данных в коде проекта или конфигурационных файлах. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. на следующих ресурсах:
- Потоки безопасной проверки подлинности (документация по ASP.NET Core)
- Управляемые идентификаторы для служб Microsoft Azure (эта статья)
Для локальной разработки и тестирования на стороне клиента и сервера используйте средство Диспетчера секретов для защиты конфиденциальных учетных данных.
Управляемые идентификаторы для служб Microsoft Azure
Для служб Microsoft Azure рекомендуется использовать управляемые удостоверения. Управляемые удостоверения безопасно проходят проверку подлинности в службах Azure без хранения учетных данных в коде приложения. Дополнительные сведения см. на следующих ресурсах:
- Что такое управляемые идентификационные данные для ресурсов Azure? (Документация по Microsoft Entra)
- Документация по службам Azure
Поддержка защиты от подделок
Шаблон Blazor :
- Автоматически добавляет службы защиты от подделки, когда AddRazorComponents вызывается в файле
Program
. - Добавляет промежуточное ПО для защиты от подделок, вызывая UseAntiforgery в конвейере обработки запросов в файле
Program
и требует защиты конечной точки от подделки для устранения угроз межсайтовой подделки запросов (CSRF/XSRF). UseAntiforgery вызывается после UseHttpsRedirection. Вызов UseAntiforgery должен следовать за вызовами UseAuthentication и UseAuthorization, если они присутствуют.
Компонент AntiforgeryToken отображает токен антифоргерии как скрытое поле, и этот компонент автоматически включается в экземпляры форм (EditForm). Для получения дополнительной информации см. Blazor.
Служба AntiforgeryStateProvider предоставляет доступ к маркеру антифальсификации, связанному с текущим сеансом. Подключите службу и вызовите её метод GetAntiforgeryToken(), чтобы получить текущий AntiforgeryRequestToken. Дополнительные сведения см. в статье Вызов веб-API в приложении ASP.NET Core Blazor.
Blazor сохраняет токены запросов в состоянии компонента, что гарантирует доступность токенов антивзлома для интерактивных компонентов, даже если у них нет доступа к запросу.
Примечание.
Меры против подделки требуется только при отправке данных формы на сервер, закодированных как application/x-www-form-urlencoded
, multipart/form-data
, или text/plain
, так как эти являются единственными допустимыми типами кодировки формы.
Дополнительные сведения см. на следующих ресурсах:
- : эта статья является основной статьей по теме ASP.NET Core, которая применяется к серверной стороне Blazor Server, серверному проекту Blazor Web App и интеграции с MVC/Blazor страницами.
- Обзор форм ASP.NET CoreBlazor: в разделе Поддержка защиты от подделки этой статьи рассматривается поддержка защиты форм от подделки Blazor.
Проверка подлинности на стороне Blazor сервера
Серверные Blazor приложения настраиваются для обеспечения безопасности таким же образом, как и ASP.NET приложения Core. Дополнительные сведения см. в статьях, посвященных обеспечению безопасности в ASP.NET Core.
Контекст проверки подлинности устанавливается только при запуске приложения, то есть когда приложение сначала подключается к WebSocket через SignalR подключение к клиенту. Аутентификация может быть основана на маркере cookie или другом маркере носителя, но аутентификация осуществляется через SignalR концентратор и полностью в рамках цепи. Контекст аутентификации сохраняется в течение всего времени существования цепи. Приложения периодически пересматривают состояние проверки подлинности пользователя каждые 30 минут.
Если приложению необходимо фиксировать пользователей для пользовательских сервисов или реагировать на обновления пользователя, см. Blazor Web App.
Blazor отличается от традиционных веб-приложений, отрисуемых сервером, которые делают новые HTTP-запросы с файлами cookie при каждом переходе по страницам. Проверка подлинности выполняется во время событий навигации. Однако файлы cookie не участвуют. Файлы cookie отправляются только при выполнении HTTP-запроса на сервер, что не происходит при переходе пользователя в Blazor приложение. Во время навигации состояние аутентификации пользователя проверяется в Blazor контуре, которое можно обновлять в любое время на сервере с помощью RevalidatingAuthenticationStateProvider
абстракции.
Внимание
Реализация пользовательского элемента NavigationManager
для валидации аутентификации во время навигации не рекомендуется. Если приложению нужно выполнить пользовательскую логику состояния проверки подлинности во время навигации, используйте пользовательский компонентAuthenticationStateProvider
.
Примечание.
Примеры кода в этой статье используют типы ссылок, допускающие значение null (NRTs), и статический анализ состояния null компилятора .NET, которые поддерживаются в ASP.NET Core в .NET 6 или более поздней версии. При работе с .NET 5 или более ранними версиями удалите обозначение типа null (?
) из примеров, приведенных в этой статье.
Встроенная или настраиваемая AuthenticationStateProvider служба получает данные о состоянии проверки подлинности из ASP.NET Core HttpContext.User. Так состояние проверки подлинности интегрируется с существующими соответствующими механизмами проверки подлинности ASP.NET Core.
Дополнительные сведения о проверке подлинности на стороне сервера см. в разделе ASP.NET Core проверка подлинности и авторизацияBlazor.
Общее состояние
Серверные приложения Blazor работают в памяти сервера, и несколько сеансов приложений размещаются в одном процессе. Для каждого сеанса Blazor приложения запускает схему с собственной областью контейнера внедрения зависимостей, поэтому услуги, зависящие от области действия, оказываются уникальными для каждого Blazor сеанса.
Предупреждение
Мы не рекомендуем приложениям на одном сервере совместно использовать состояние через синглтон-сервисы, если не приняты экстремальные меры предосторожности, так как это может привести к уязвимостям безопасности, например, утечке состояния пользователя между сессиями.
Службы-синглтоны с отслеживанием состояния можно использовать в приложениях Blazor, если они специально предназначены для этого. Например, использование однотонного кэша памяти приемлемо, так как кэш памяти требует ключа для доступа к данной записи. Если у пользователей нет контроля над ключами кэша, которые используются с кэшем, состояние, хранящееся в кэше, не утечет между каналами.
Общие рекомендации по управлению состоянием см. в разделе ASP.NET Core Blazor State Management.
Безопасность конфиденциальных данных и учетных данных на стороне сервера
В тестовых, промежуточных и рабочих средах код на стороне Blazor сервера и веб-API должен использовать безопасные потоки аутентификации, которые избегают хранения учетных данных в коде проекта или конфигурационных файлах. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. на следующих ресурсах:
- Потоки безопасной проверки подлинности (документация по ASP.NET Core)
- Управляемые идентификаторы для служб Microsoft Azure (Blazor документация)
Для локальной разработки и тестирования на стороне клиента и сервера используйте средство Диспетчера секретов для защиты конфиденциальных учетных данных.
шаблон проекта;
Создайте серверное Blazor приложение, следуя инструкциям в статье "Инструментирование для ASP.NET Core Blazor".
Выбрав шаблон приложения на стороне сервера и настроив проект, выберите проверку подлинности приложения в разделе "Проверка подлинности".
- Нет (по умолчанию): проверка подлинности отсутствует.
- Отдельные учетные записи: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
- Нет (по умолчанию): проверка подлинности отсутствует.
- Отдельные учетные записи: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
- платформа идентификации Microsoft: Более подробную информацию см. в ASP.NET Core Blazor проверки подлинности и авторизации.
- Windows: используйте проверку подлинности Windows.
Blazor Identity Пользовательский интерфейс (отдельные учетные записи)
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 (по ссылке).
При выборе интерактивного режима WebAssembly или интерактивного режима Auto сервер обрабатывает все запросы на проверку подлинности и авторизацию, а Identity компоненты отображаются статически на сервере в основном проекте Blazor Web App.
Платформа предоставляет настраиваемый AuthenticationStateProvider в проектах сервера и клиента (.Client
) для передачи состояния аутентификации пользователя в браузер. Серверный проект вызывает AddAuthenticationStateSerialization, а клиентский проект вызывает AddAuthenticationStateDeserialization. Проверка подлинности на сервере, а не клиент позволяет приложению получать доступ к состоянию проверки подлинности во время предварительной подготовки и до инициализации среды выполнения .NET WebAssembly. Пользовательские AuthenticationStateProvider реализации используют службу состояния постоянного компонента (PersistentComponentState) для сериализации состояния аутентификации в комментарии HTML, а затем считывают это состояние обратно из WebAssembly для создания нового экземпляра AuthenticationState. Дополнительные сведения см. в разделе "Управление состоянием проверки подлинности Blazor Web Apps".
Только для решений Интерактивного Сервера, IdentityRevalidatingAuthenticationStateProvider
(эталонный источник) — это серверная компонентa AuthenticationStateProvider, которая обновляет метку безопасности для подключенного пользователя каждые 30 минут, пока подключена интерактивная цепь.
При выборе интерактивного режима WebAssembly или интерактивного режима Auto сервер обрабатывает все запросы на проверку подлинности и авторизацию, а Identity компоненты отображаются статически на сервере в основном проекте Blazor Web App. Шаблон проекта содержит PersistentAuthenticationStateProvider
в проекте для синхронизации состояния аутентификации пользователя между сервером и браузером. Класс представляет собой пользовательскую реализацию AuthenticationStateProvider. Поставщик использует службу состояния постоянного компонента (PersistentComponentState) для предварительного рендеринга состояния аутентификации и его сохранения на странице.
В основном проекте Blazor Web App поставщик состояния проверки подлинности называется либо IdentityRevalidatingAuthenticationStateProvider
(эталонный источник) (только решения для взаимодействия сервера), либо PersistingRevalidatingAuthenticationStateProvider
(эталонный источник) (WebAssembly или автоматизированные интерактивные решения).
Blazor Identity DbContext зависит от экземпляров, которые не созданы фабрикой. Это сделано намеренно, так как DbContext достаточно для компонентов Identity проекта, чтобы статично отображаться без поддержки интерактивности.
Описание того, как глобальные режимы интерактивной отрисовки применяются к компонентам, отличным от Identity, одновременно обеспечивая статический SSR для Identity компонентов, см. в разделе ASP.NET Core Blazor режимы отрисовки.
Для получения дополнительной информации о сохранении предварительно отрендеренного состояния см. в разделе
Примечание.
Ссылки в документации на справочные материалы .NET обычно ведут к ветви репозитория по умолчанию, которая отражает текущую разработку для следующего релиза .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода 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 и описаны ниже.
В файле проекта сервера
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization();
API сериализует только серверные данные о именах и ролях для доступа в браузере. Чтобы включить все утверждения, установите SerializeAllClaims на true
в вызове AddAuthenticationStateSerialization на стороне сервера.
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddAuthenticationStateSerialization(
options => options.SerializeAllClaims = true);
В файле проекта клиента (.Client
)Program
вызовите AddAuthenticationStateDeserialization, который добавляет компонент AuthenticationStateProvider, где данные AuthenticationState десериализуются с сервера с помощью службы AuthenticationStateData
сохраняемого состояния компонента ().PersistentComponentState В серверном проекте должно быть соответствующее вызов AddAuthenticationStateSerialization.
builder.Services.AddAuthorizationCore();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddAuthenticationStateDeserialization();
PersistingRevalidatingAuthenticationStateProvider
(справочный источник): для Blazor Web Appустройств, использующих интерактивную отрисовку на стороне сервера (интерактивный SSR) и отрисовку на стороне клиента (CSR). Эта серверная функция AuthenticationStateProvider, которая проверяет заново метку безопасности для подключенного пользователя каждые 30 минут в течение подключения интерактивной цепи. Она также использует службу постоянного состояния компонента для передачи состояния проверки подлинности клиенту, которое затем остается неизменным на протяжении всего времени существования CSR.PersistingServerAuthenticationStateProvider
(ссылочный источник): для Blazor Web App, которые применяют только корпоративную социальную ответственность (CSR). Это серверная составляющая AuthenticationStateProvider, которая использует службу состояния сохраняемого компонента для передачи состояния проверки подлинности клиенту, после чего это состояние остаётся неизменным на протяжении всего срока действия CSR.PersistentAuthenticationStateProvider
(ссылочный источник): для Blazor Web Appов, которые принимают КСО. Это клиентская сторона AuthenticationStateProvider, которая определяет состояние аутентификации пользователя путем поиска данных, сохраненных на странице при генерации на сервере. Это состояние аутентификации фиксировано на все время существования CSR. Если пользователю нужно войти или выйти, требуется полная перезагрузка страницы. Это предоставляет только имя пользователя и электронную почту в целях отображения. Он не включает токены аутентификации для сервера при выполнении последующих запросов, обрабатываемых отдельно, используя cookie, который добавляется кHttpClient
запросам к серверу.
Примечание.
Ссылки в документации на справочные материалы .NET обычно ведут к ветви репозитория по умолчанию, которая отражает текущую разработку для следующего релиза .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Каркас Identity
Дополнительные сведения о внедрении Identity в серверное Blazor приложение см. в разделе Каркас Identity в проектах ASP.NET Core.
Проектируйте Identity в серверное Blazor приложение:
Дополнительные утверждения и маркеры от внешних поставщиков
Для хранения дополнительных утверждений от внешних поставщиков смотрите Сохранение дополнительных утверждений и маркеров от внешних поставщиков в ASP.NET Core.
Служба приложений Azure в Linux с сервером Identity
При развертывании в Azure App Service на Linux с сервером Identity необходимо явно указать издателя. Дополнительные сведения см. в разделе «Использование Identity для защиты серверной части веб-API в SPA.
Внедрите AuthenticationStateProvider
службы, ограниченные областью компонента
Не пытайтесь разрегистрировать AuthenticationStateProvider в рамках пользовательской области, поскольку это приводит к созданию нового экземпляра AuthenticationStateProvider, который инициализируется неправильно.
Чтобы получить доступ к AuthenticationStateProvider в службе, ограниченной компонентом, вставьте AuthenticationStateProvider в компонент и передайте его в службу в качестве параметра. Этот подход обеспечивает использование правильного, инициализированного экземпляра 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);
}
}
Дополнительные сведения см. в руководстве по
Неразрешённое отображение содержимого при предварительной подготовке с помощью настраиваемого AuthenticationStateProvider
Чтобы избежать отображения несанкционированного содержимого, например содержимого в AuthorizeView
компоненте, при предварительном создании с помощью пользовательского AuthenticationStateProvider
, следует использовать один из следующих подходов:
Реализуйте IHostEnvironmentAuthenticationStateProvider для пользовательского AuthenticationStateProvider, чтобы поддерживать предварительное рендеринг: пример реализации IHostEnvironmentAuthenticationStateProvider можно найти в разделе о реализации Blazor фреймворка ServerAuthenticationStateProvider в
ServerAuthenticationStateProvider.cs
(эталонный источник).Примечание.
Ссылки в документации на справочные материалы .NET обычно ведут к ветви репозитория по умолчанию, которая отражает текущую разработку для следующего релиза .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Отключить предварительную отрисовку: укажите режим отрисовки с параметром
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 Core .
Отключить предварительную отрисовку: Откройте файл
_Host.cshtml
, и измените атрибутrender-mode
компонента вспомогательного элемента Component Tag Helper на:<component type="typeof(App)" render-mode="Server" />
- Аутентифицировать пользователя на сервере перед запуском приложения: Чтобы использовать этот подход, приложение должно отвечать на первоначальный запрос пользователя с помощью страницы или формы входа на основе Identity и заблокировать любые запросы к конечным точкам Blazor до того момента, пока пользователь не будет аутентифицирован. Дополнительные сведения см. в разделе "Создание приложения ASP.NET Core с пользовательскими данными, защищенными авторизацией". После проверки подлинности несанкционированное содержимое в предварительно созданных Razor компонентах отображается только в том случае, если пользователь действительно не авторизован для просмотра содержимого.
Управление пользовательским состоянием
Несмотря на слово "состояние" в имени, AuthenticationStateProvider не для хранения общего пользовательского состояния. AuthenticationStateProvider только указывает состояние аутентификации пользователя в приложении, зарегистрированы ли они в приложении и под каким именем.
Проверка подлинности использует ту же ASP.NET Core Identity, что и приложения Pages и MVC. Состояние пользователя, хранящееся для ASP.NET Core Identity, автоматически передается в Blazor без необходимости добавления дополнительного кода в приложение. Следуйте инструкциям в статьях и руководствах по ASP.NET Core Identity, чтобы функции Identity вступить в силу в Blazor частях приложения.
Рекомендации по управлению состоянием за пределами ASP.NET Core
Дополнительные абстракции безопасности
Две дополнительные абстракции участвуют в управлении состоянием аутентификации.
ServerAuthenticationStateProvider (справочный источник): используется AuthenticationStateProvider платформой Blazor для получения состояния проверки подлинности с сервера.
RevalidatingServerAuthenticationStateProvider(ссылочный источник): базовый класс для служб, используемых AuthenticationStateProvider платформой для получения состояния аутентификации из среды узла и его переутверждения через регулярные промежутки времени.
Интервал переутверждения по умолчанию 30 минут можно настроить в
RevalidatingIdentityAuthenticationStateProvider
(источнике справки). В следующем примере интервал сокращается до 20 минут:protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
Примечание.
Ссылки в документации на справочные материалы .NET обычно ведут к ветви репозитория по умолчанию, которая отражает текущую разработку для следующего релиза .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Управление состоянием аутентификации при выходе из системы
Blazor Сервер сохраняет состояние аутентификации пользователя на протяжении всего сеанса, включая на вкладках браузера. Чтобы автоматически завершать сеанс пользователя на всех вкладках браузера при выходе с одной из них, необходимо реализовать RevalidatingServerAuthenticationStateProvider (эталонный источник) с коротким RevalidationInterval.
Примечание.
Ссылки в документации на справочные материалы .NET обычно ведут к ветви репозитория по умолчанию, которая отражает текущую разработку для следующего релиза .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Срок действия URL-адреса временного перенаправления
Этот раздел относится к Blazor Web Apps.
Используйте параметр RazorComponentsServiceOptions.TemporaryRedirectionUrlValidityDuration, чтобы задать или получить срок действия защиты данных ASP.NET Core для URL-адресов временных перенаправлений, создаваемых серверной отрисовкой Blazor. Они используются лишь временно, поэтому срок их действия должен быть достаточно длительным, чтобы клиент успел получить URL-адрес и начать навигацию к нему. Однако оно также должно быть достаточно длинным, чтобы учесть отклонение часов между серверами. Значение по умолчанию — пять минут.
В следующем примере значение распространяется на семь минут:
builder.Services.AddRazorComponents(options =>
options.TemporaryRedirectionUrlValidityDuration =
TimeSpan.FromMinutes(7));
Аутентификация на стороне клиента Blazor
В клиентских приложениях проверки подлинности на стороне Blazor клиента можно обойти, так как все клиентские коды могут быть изменены пользователями. Это верно для всех клиентских технологий приложений, включая платформы SPA JavaScript и собственные приложения для любой операционной системы.
Добавьте следующее.
Ссылка на пакет для пакета NuGet
Microsoft.AspNetCore.Components.Authorization
.Примечание.
Рекомендации по добавлению пакетов в приложения .NET см. в разделе Способы установки пакетов NuGet в статье Рабочий процесс использования пакета (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Пространство имен Microsoft.AspNetCore.Components.Authorization к файлу
_Imports.razor
приложения.
Для обработки аутентификации используйте встроенную или пользовательскую AuthenticationStateProvider службу.
Дополнительные сведения о проверке подлинности на стороне клиента см. в статье Secure ASP.NET Core Blazor WebAssembly.
Защита данных в Blazor Web Appс помощью интерактивной автоматической визуализации
При условии, если Blazor Web App использует серверную отрисовку (SSR) и отрисовку на стороне клиента (CSR) для компонентов или всего приложения, указывающего режим интерактивной отрисовки , авторизация на доступ к компонентам и данным применяется в двух местах . Компонент ограничивает доступ к себе (и ко всем данным, которые он получает) при рендеринге на сервере в соответствии с атрибутом авторизации в файле определения компонента (@attribute [Authorize]
). Когда компонент отображается на клиенте, доступ к данным ограничивается с использованием конечных точек веб-API сервера, которые вызываются с клиента. Будьте внимательны при защите доступа к данным в обоих местах, чтобы предотвратить неправильный доступ к данным.
Рассмотрим следующий сценарий, когда безопасные погодные данные отображаются компонентом. Демонстрации некоторых из следующих подходов можно оценить и протестировать с помощью BlazorWebAppEntra
/BlazorWebAppEntraBff
примеров (.NET 9 или более поздней версии) илиBlazorWebAppOidc
/BlazorWebAppOidcBff
примеров (.NET 8 или более поздней версии) в Blazor репозитории примеров GitHub (dotnet/blazor-samples
как скачать).
Клиентский проект поддерживает класс WeatherForecast
для хранения данных о погоде:
public sealed class WeatherForecast(DateOnly date, int temperatureC, string summary)
{
public DateOnly Date { get; set; } = date;
public int TemperatureC { get; set; } = temperatureC;
public string? Summary { get; set; } = summary;
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Интерфейс IWeatherForecaster
клиентского проекта определяет метод GetWeatherForecastAsync
для получения данных о погоде:
public interface IWeatherForecaster
{
Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync();
}
Служба ClientWeatherForecaster
в клиентском проекте реализует IWeatherForecaster
. Метод GetWeatherForecastAsync
вызывает веб-API в проекте сервера в конечной точке /weather-forecast
для погодных данных:
internal sealed class ClientWeatherForecaster(HttpClient httpClient)
: IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync() =>
await httpClient.GetFromJsonAsync<WeatherForecast[]>("/weather-forecast") ??
throw new IOException("No weather forecast!");
}
Клиентский проект поддерживает компонент Weather
, который:
- Применяет авторизацию с помощью атрибута
[Authorize]
. - Использует службу постоянного состояния компонента (PersistentComponentState) для сохранения данных прогноза погоды при переходе компонента со статического на интерактивный SSR на сервере. Дополнительные сведения см. в разделе Предварительный рендеринг компонентов ASP.NET CoreRazor.
@page "/weather"
@using Microsoft.AspNetCore.Authorization
@using BlazorWebAppEntra.Client.Weather
@attribute [Authorize]
@inject IWeatherForecaster WeatherForecaster
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (Forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th aria-label="Temperature in Celsius">Temp. (C)</th>
<th aria-label="Temperature in Fahrenheit">Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in Forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
[SupplyParameterFromPersistentComponentState]
public IEnumerable<WeatherForecast>? Forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
Forecasts ??= await WeatherForecaster.GetWeatherForecastAsync();
}
}
@page "/weather"
@using Microsoft.AspNetCore.Authorization
@using BlazorWebAppEntra.Client.Weather
@attribute [Authorize]
@implements IDisposable
@inject PersistentComponentState ApplicationState
@inject IWeatherForecaster WeatherForecaster
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th aria-label="Temperature in Celsius">Temp. (C)</th>
<th aria-label="Temperature in Fahrenheit">Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private IEnumerable<WeatherForecast>? forecasts;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<IEnumerable<WeatherForecast>>(
nameof(forecasts), out var restoredData))
{
forecasts = await WeatherForecaster.GetWeatherForecastAsync();
}
else
{
forecasts = restoredData!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose() => persistingSubscription.Dispose();
}
Серверный проект внедряет IWeatherForecaster
как ServerWeatherForecaster
, что генерирует и возвращает данные о погоде методом GetWeatherForecastAsync
.
internal sealed class ServerWeatherForecaster() : IWeatherForecaster
{
public readonly string[] summaries =
[
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot",
"Sweltering", "Scorching"
];
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
// Simulate asynchronous loading to demonstrate streaming rendering
await Task.Delay(500);
return Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
}
}
Если приложение должно вызвать внешний веб-API для получения данных о погоде, можно внедрить HTTP-клиент (HttpClient
) для запроса данных:
internal sealed class ServerWeatherForecaster(HttpClient httpClient,
IHttpContextAccessor httpContextAccessor) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
var httpContext = httpContextAccessor.HttpContext ??
throw new InvalidOperationException("No HttpContext!");
var accessToken = await httpContext.GetTokenAsync("access_token") ??
throw new InvalidOperationException("No access_token was saved");
using var request =
new HttpRequestMessage(HttpMethod.Get, "/weather-forecast");
request.Headers.Authorization = new("Bearer", accessToken);
using var response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
В еще одном подходе можно внедрить фабрику HTTP-клиентов (IHttpClientFactory
) в ServerWeatherForecaster
, чтобы вызвать внешний веб-API с помощью именованного HTTP-клиента с обработчиком токенов. Дополнительные сведения см. в статье Вызов веб-API в приложении ASP.NET Core Blazor.
Если приложение использует платформу удостоверений Майкрософт с веб-пакетами Microsoft для IdentityMicrosoft Entra ID (см. вызов веб-API из приложения ASP.NET CoreBlazor), следующее ServerWeatherForecaster
демонстрирует внешний вызов веб-API. Маркер доступа автоматически присоединяется к запросу.
internal sealed class ServerWeatherForecaster(IDownstreamApi downstreamApi) : IWeatherForecaster
{
public async Task<IEnumerable<WeatherForecast>> GetWeatherForecastAsync()
{
using var response = await downstreamApi.CallApiForUserAsync("DownstreamApi",
options =>
{
options.RelativePath = "/weather-forecast";
});
return await response.Content.ReadFromJsonAsync<WeatherForecast[]>() ??
throw new IOException("No weather forecast!");
}
}
Независимо от подхода, принятого ServerWeatherForecaster
для получения данных, проект сервера поддерживает безопасную конечную точку веб-API для вызовов данных погоды клиента. Эта конечная точка приводит к вызову ServerWeatherForecaster.GetWeatherForecastAsync
на сервере:
app.MapGet("/weather-forecast", (
[FromServices] IWeatherForecaster WeatherForecaster) =>
{
return WeatherForecaster.GetWeatherForecastAsync();
}).RequireAuthorization();
Используя предыдущий подход, существует две системы для предоставления безопасных данных о погоде пользователю:
- Когда компонент
Weather
отображается на сервере, методServerWeatherForecaster
службыGetWeatherForecastAsync
используется непосредственно для получения данных о погоде. Безопасность данных обеспечивается атрибутом[Authorize]
компонента. В итоге безопасность погодных данных обеспечивается компонентом. - Когда компонент
Weather
отображается на клиентском, службаClientWeatherForecaster
используется для вызова веб-API к защищенной конечной точке/weather-forecast
, которая применяет метод расширения RequireAuthorization. Если у пользователя есть право доступа к данным о погоде, конечная точка использует службуServerWeatherForecaster
для вызоваGetWeatherForecastAsync
. Данные возвращаются клиенту. В конечном счёте безопасность данных о погоде обеспечивается конечной точкой веб-API серверного приложения.
Предыдущий подход хорошо подходит, если требования к безопасности веб-API соответствуют требованиям безопасности компонента. Например, ту же политику авторизации можно применить как к конечной точке веб-API, так и к компоненту.
Сложные сценарии требуют дополнительного планирования и реализации. Например, веб-API сервера с несколькими вызывающими клиентами с разными разрешениями доступа требует более сложной политики авторизации, одной или нескольких дополнительных политик или дополнительных конечных точек с различными требованиями к доступу.
При создании безопасности в приложениях, использующих интерактивную автоматическую отрисовку, учитывайте, что безопасность, реализованная для конечных точек веб-API сервера, не защищает реализацию службы сервера, которая используется при отрисовке компонента на сервере и обращается к данным через службу. Тщательно взвешивайте разницу между доступом к данным на сервере во время SSR и доступом к данным в запросе клиентского веб-API во время CSR. Стратегически применяйте безопасность, чтобы избежать неправильного доступа к данным.
Примеры в репозитории GitHub Blazor (dotnet/blazor-samples
) (как скачать), демонстрирующие подход, описанный в этом разделе:
BlazorWebAppOidc
BlazorWebAppOidcBff
BlazorWebAppEntra
BlazorWebAppEntraBff
AuthenticationStateProvider
служба
AuthenticationStateProvider — это базовая служба, используемая компонентом AuthorizeView и каскадными службами проверки подлинности для получения состояния проверки подлинности для пользователя.
AuthenticationStateProvider — это базовая служба, используемая компонентом AuthorizeView и CascadingAuthenticationState компонентом для получения состояния проверки подлинности для пользователя.
Обычно вы не используете AuthenticationStateProvider напрямую. Используйте компонент AuthorizeView
или подход Task<AuthenticationState>
, как описано далее в этой статье. Основной недостаток при использовании AuthenticationStateProvider напрямую заключается в том, что компонент не получает автоматического уведомления при изменении базовых данных о состоянии аутентификации.
Сведения о реализации пользовательского AuthenticationStateProvider, см. в разделе ASP.NET Core Blazor состояние аутентификации, включающем рекомендации по реализации уведомлений об изменении состояния аутентификации пользователей.
Получение основных пользовательских данных (утверждений)
Служба 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, см. в разделе Blazor.
Представьте состояние аутентификации в качестве каскадного параметра
Если данные о состоянии проверки подлинности необходимы для процедурной логики, например при выполнении действия, активированного пользователем, получите данные о состоянии проверки подлинности, определив каскадный параметр типа 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>
Примечание.
В релизе .NET 5.0.1, и для любых дополнительных релизов 5.x, компонент включает набор параметров Router
, установленный на PreferExactMatches
. Дополнительные сведения см. в разделе "Миграция с ASP.NET Core 3.1 на .NET 5".
В клиентском Blazor приложении добавьте службы авторизации в Program
файл:
builder.Services.AddAuthorizationCore();
В клиентском Blazor приложении добавьте параметры и службы авторизации в Program
файл:
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
В серверном Blazor приложении службы для параметров и авторизации уже присутствуют, поэтому дальнейшие действия не требуются.
Авторизация
После аутентификации пользователя применяются правила авторизации, которые определяют доступные этому пользователю действия.
Доступ обычно предоставляется или запрещается в зависимости от следующих аспектов:
- Пользователь аутентифицирован (вошел в систему).
- Пользователь находится в роли.
- У пользователя есть претензия.
- Политика policy удовлетворена.
Каждый из этих аспектов применяется здесь так же, как в приложениях ASP.NET Core MVC или Razor Pages. Дополнительные сведения о безопасности ASP.NET Core вы найдете в статьях раздела Безопасность ASP.NET Core и Identity.
Компонент AuthorizeView
Компонент AuthorizeView избирательно демонстрирует содержимое пользовательского интерфейса в зависимости от того, авторизован ли пользователь. Этот подход полезен, когда нужно только отображать данные для пользователя и не нужно использовать идентификацию пользователя в процедурной логике.
Компонент предоставляет 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 CoreBlazor и Дополнительные сценарии безопасности в 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.
Если заданы и Roles, и Policy, авторизация выполняется только в случае выполнения обоих условий. То есть пользователь должен принадлежать по крайней мере одной из указанных ролей и соответствовать требованиям, определенным политикой.
Если ни Roles, ни Policy не указаны, AuthorizeView используется стандартная политика:
- Пользователи, прошедшие проверку подлинности, авторизованы.
- Неавторизованные (вышедшие из системы) пользователи не имеют разрешения.
Так как сравнения строк .NET чувствительны к регистру, имена ролей и политик также чувствительны к регистру. Например, Admin
(в верхнем регистре A
) не рассматривается в качестве той же роли, как admin
(в нижнем регистре a
).
Регистр Pascal обычно используется для имен ролей и политик (например, BillingAdministrator
), но использование регистра Pascal не является строгим требованием. Разрешены различные стили написания, такие как CamelCase, kebab-case и snake_case. Использование пробелов в именах ролей и политик является необычным, но разрешено фреймворком. Например, 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>
Если ни Roles, ни Policy не указаны, [Authorize]
используется стандартная политика:
- Пользователи, прошедшие проверку подлинности, авторизованы.
- Неавторизованные (вышедшие из системы) пользователи не имеют разрешения.
Если пользователь не авторизован и если приложение не настраивает несанкционированное содержимое с Router
помощью компонента, фреймворк автоматически отображает следующее резервное сообщение:
Not authorized.
Авторизация ресурсов
Чтобы авторизовать пользователей для доступа к ресурсам, передайте данные маршрута запроса в параметр Resource в AuthorizeRouteView.
В содержимом Router.Found маршрута запроса:
<AuthorizeRouteView Resource="routeData" RouteData="routeData"
DefaultLayout="typeof(MainLayout)" />
Дополнительные сведения о том, как данные состояния авторизации передаются и используются в процедурной логике, см. в статье Предоставление состояния аутентификации в качестве каскадного параметра.
Когда объект AuthorizeRouteView получает данные маршрута для ресурса, политики авторизации получают доступ к RouteData.PageType и RouteData.RouteValues, в результате чего разрешается использовать настраиваемую логику для принятия решений об авторизации.
В следующем примере в EditUser
создается политика AuthorizationOptions для конфигурации службы авторизации приложения (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-адрес после аутентификации через поставщика удостоверений личности.
Процедурная логика
Если приложению нужно проверять правила авторизации в составе процедурной логики, используйте каскадный параметр с типом 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
для этого.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 ссылается на любую информацию, связанную с идентифицированным или идентифицируемым физическим лицом. Идентифицируемый физический человек — это тот, кто может быть идентифицирован, прямо или косвенно, с любым из следующих элементов:
- Имя.
- Идентификационный номер
- Координаты расположения
- Идентификатор в Сети
- Другие конкретные факторы
- Физический
- физиологический
- Генетический
- Психический (психологический)
- Экономический
- Культура
- Социальная идентичность
Дополнительные ресурсы
- Серверная часть и Blazor Web App ресурсы
- Краткое руководство: Добавление входа с помощью Microsoft в веб-приложение ASP.NET Core
- Быстрый старт: Защита веб-API ASP.NET Core с помощью платформы удостоверений Microsoft
-
Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки. Содержит рекомендации по следующим вопросам:
- Использование промежуточного программного обеспечения для перенаправленных заголовков для сохранения сведений о схеме HTTPS на прокси-серверах и во внутренних сетях.
- Дополнительные сценарии и варианты использования, включая ручную настройку схемы, изменение пути запроса для правильной маршрутизации запроса и перенаправление схемы запроса для обратных прокси-серверов Linux и обратных прокси-серверов, отличных от IIS.
- Документация по платформе идентификации Microsoft
- Материалы по безопасности в ASP.NET Core
- Настройка аутентификации Windows в ASP.NET Core
- Использование IHttpContextAccessor/HttpContext в приложениях Blazor ASP.NET Core
- Создание пользовательской версии библиотеки Authentication.MSAL для JavaScript
- ЗамечательныеBlazor: примеры ссылок сообщества аутентификации
- Проверка подлинности и авторизация в Blazor Hybrid ASP.NET Core
- Серверные Blazor ресурсы
- Краткое руководство: Добавление входа с помощью Microsoft в веб-приложение ASP.NET Core
- Быстрый старт: Защита веб-API ASP.NET Core с помощью платформы удостоверений Microsoft
-
Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки. Содержит рекомендации по следующим вопросам:
- Использование промежуточного программного обеспечения для перенаправленных заголовков для сохранения сведений о схеме HTTPS на прокси-серверах и во внутренних сетях.
- Дополнительные сценарии и варианты использования, включая ручную настройку схемы, изменение пути запроса для правильной маршрутизации запроса и перенаправление схемы запроса для обратных прокси-серверов Linux и обратных прокси-серверов, отличных от IIS.
- Документация по платформе идентификации Microsoft
- Материалы по безопасности в ASP.NET Core
- Использование IHttpContextAccessor/HttpContext в приложениях Blazor ASP.NET Core
- Настройка аутентификации Windows в ASP.NET Core
- Создание пользовательской версии библиотеки Authentication.MSAL для JavaScript
- ЗамечательныеBlazor: примеры ссылок сообщества аутентификации
ASP.NET Core