Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Это не последняя версия этой статьи. См. текущий выпуск в версии .NET 10 этой статьи.
Warning
Эта версия ASP.NET Core больше не поддерживается. Для получения дополнительной информации см. Политику поддержки .NET и .NET Core. См. текущий выпуск в версии .NET 10 этой статьи.
В этой статье описывается, как 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, см. раздел Scaffold ASP.NET Core Identity в серверном приложении Blazor.
Note
Примеры кода, приведенные в этой статье, используют nullable типы ссылок (NRTs) и компиляторский статический анализ состояния null в .NET, которые поддерживаются в ASP.NET Core в .NET 6 и более поздних версиях. При использовании .NET 5 или более старых версий удалите обозначение типа null (?) из примеров в этой статье.
Безопасное обслуживание конфиденциальных данных и учетных данных
Не сохраняйте секреты приложений, строки подключения, учетные данные, пароли, личные идентификационные номера (ПИН-коды), частный код .NET/C# или закрытые ключи или токены в клиентском коде, который является always insecure. Клиентский 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). Дополнительные сведения см. в разделе ASP.NET Core Blazor forms overview.
Служба AntiforgeryStateProvider предоставляет доступ к маркеру антифальсификации, связанному с текущим сеансом. Подключите службу и вызовите её метод GetAntiforgeryToken(), чтобы получить текущий AntiforgeryRequestToken. Дополнительные сведения см. в разделе Вызов веб-API из приложения ASP.NET Core Blazor.
Blazor сохраняет токены запросов в состоянии компонента, что гарантирует доступность токенов антивзлома для интерактивных компонентов, даже если у них нет доступа к запросу.
Note
Меры против подделки требуется только при отправке данных формы на сервер, закодированных как application/x-www-form-urlencoded, multipart/form-data, или text/plain, так как эти являются единственными допустимыми типами кодировки формы.
Дополнительные сведения см. на следующих ресурсах:
- Предотвращение атак Cross-Site Request Forgery (XSRF/CSRF) в ASP.NET Core: эта статья является основной статьёй ASP.NET Core по теме. Его содержание относится к серверной Blazor Server, серверному проекту Blazor Web App, а также интеграции Blazor с MVC/Razor Pages.
- Обзор форм Blazor ASP.NET Core: Раздел поддержки Antiforgery в статье относится к защите от подделки форм.
Проверка подлинности на стороне Blazor сервера
Серверные приложения Blazor настроены для обеспечения безопасности так же, как и ASP.NET Core приложения. Дополнительные сведения см. в статьях по темам безопасности ASP.NET Core.
Контекст проверки подлинности устанавливается только при запуске приложения, то есть когда приложение сначала подключается к WebSocket через SignalR подключение к клиенту. Аутентификация может быть основана на маркере cookie или другом маркере носителя, но аутентификация осуществляется через SignalR концентратор и полностью в рамках цепи. Контекст проверки подлинности сохраняется в течение всего времени существования подключения и оценивается повторно при повторном подключении.
Если приложению необходимо привлекать пользователей для индивидуальных услуг или реагировать на обновления пользователя, см. раздел ASP.NET Core на стороне сервера и Blazor Web App дополнительные сценарии безопасности.
Blazor отличается от традиционных веб-приложений, отрисуемых сервером, которые делают новые HTTP-запросы с файлами cookie при каждом переходе по страницам. Проверка подлинности выполняется во время событий навигации. Однако файлы cookie не участвуют. Файлы cookie отправляются только при выполнении HTTP-запроса на сервер, что не происходит при переходе пользователя в Blazor приложение. Во время навигации состояние аутентификации пользователя проверяется в Blazor контуре, которое можно обновлять в любое время на сервере с помощью RevalidatingAuthenticationStateProvider абстракции.
Important
Реализация пользовательского элемента NavigationManager для валидации аутентификации во время навигации не рекомендуется. Если приложению нужно выполнить пользовательскую логику состояния проверки подлинности во время навигации, используйте пользовательский компонентAuthenticationStateProvider.
Note
Примеры кода, приведенные в этой статье, принимают нуллируемые ссылочные типы (NRTs) и .NET статический анализ состояния null, которые поддерживаются в ASP.NET Core в .NET 6 или более поздних версий. При использовании целевых платформ .NET 5 и более ранних удалите обозначение типа null (?) из примеров данной статьи.
Встроенная или настраиваемая служба AuthenticationStateProvider получает данные о состоянии проверки подлинности из HttpContext.User ASP.NET Core. Это то, как состояние проверки подлинности интегрируется с существующими механизмами проверки подлинности ASP.NET Core.
Общедоступное состояние
Серверные приложения Blazor работают в памяти сервера, и несколько сеансов приложений размещаются в одном процессе. Для каждого сеанса Blazor приложения запускает схему с собственной областью контейнера внедрения зависимостей, поэтому услуги, зависящие от области действия, оказываются уникальными для каждого Blazor сеанса.
Warning
Мы не рекомендуем приложениям на одном сервере совместно использовать состояние через синглтон-сервисы, если не приняты экстремальные меры предосторожности, так как это может привести к уязвимостям безопасности, например, утечке состояния пользователя между сессиями.
Службы-синглтоны с отслеживанием состояния можно использовать в приложениях Blazor, если они специально предназначены для этого. Например, использование однотонного кэша памяти приемлемо, так как кэш памяти требует ключа для доступа к данной записи. Если у пользователей нет контроля над ключами кэша, которые используются с кэшем, состояние, хранящееся в кэше, не утечет между каналами.
Общие рекомендации по управлению состоянием см. в разделе ASP.NET Core Blazor обзор управления состоянием.
Безопасность конфиденциальных данных и учетных данных на стороне сервера
В тестовых, промежуточных и рабочих средах код на стороне Blazor сервера и веб-API должен использовать безопасные потоки аутентификации, которые избегают хранения учетных данных в коде проекта или конфигурационных файлах. Вне локального тестирования разработки рекомендуется избегать использования переменных среды для хранения конфиденциальных данных, так как переменные среды не являются наиболее безопасным подходом. Для локального тестирования разработки средство Secret Manager рекомендуется для защиты конфиденциальных данных. Дополнительные сведения см. на следующих ресурсах:
- Защищенные потоки проверки подлинности (документация по ASP.NET Core)
- Управляемые удостоверения для служб Microsoft Azure (документация)Blazor
Для локальной разработки и тестирования на стороне клиента и сервера используйте средство Диспетчера секретов для защиты конфиденциальных учетных данных.
шаблон Project
Создайте серверное приложение Blazor, следуя инструкциям в Tooling for ASP.NET Core Blazor.
Выбрав шаблон приложения на стороне сервера и настроив проект, выберите проверку подлинности приложения в разделе "Проверка подлинности".
- Нет (по умолчанию): проверка подлинности отсутствует.
- Individual Accounts: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
- Нет (по умолчанию): проверка подлинности отсутствует.
- Individual Accounts: учетные записи пользователей хранятся в приложении с помощью ASP.NET Core Identity.
- платформа удостоверений Майкрософт. Дополнительные сведения см. в разделе Additional resources.
- 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, находящихся в папке Components/Account серверного проекта шаблона Blazor Web App (репозиторий GitHub dotnet/aspnetcore).
При выборе интерактивного режима WebAssembly или интерактивного режима Auto сервер обрабатывает все запросы на проверку подлинности и авторизацию, а Identity компоненты отображаются статически на сервере в основном проекте Blazor Web App.
Платформа предоставляет настраиваемый AuthenticationStateProvider в проектах сервера и клиента (.Client) для передачи состояния аутентификации пользователя в браузер. Серверный проект вызывает AddAuthenticationStateSerialization, а клиентский проект вызывает AddAuthenticationStateDeserialization. Проверка подлинности на сервере, а не клиент позволяет приложению получать доступ к состоянию проверки подлинности во время предварительной подготовки и до инициализации среды выполнения .NET WebAssembly. Пользовательские AuthenticationStateProvider реализации используют службу состояния постоянного компонента (PersistentComponentState) для сериализации состояния аутентификации в комментарии HTML, а затем считывают это состояние обратно из WebAssembly для создания нового экземпляра AuthenticationState. Дополнительные сведения см. в разделе "Управление состоянием проверки подлинности Blazor Web Apps".
Только для решений Интерактивных Серверов, IdentityRevalidatingAuthenticationStateProvider (Components/Account/IdentityRevalidatingAuthenticationStateProvider.cs) в серверном проекте шаблона проекта Blazor Web App (dotnet/aspnetcore репозиторий GitHub) — это серверная AuthenticationStateProvider, которая перепроверяет метку безопасности для подключенного пользователя каждые 30 минут при подключении интерактивного сеанса.
При выборе интерактивного режима WebAssembly или интерактивного режима Auto сервер обрабатывает все запросы на проверку подлинности и авторизацию, а Identity компоненты отображаются статически на сервере в основном проекте Blazor Web App. Шаблон проекта содержит PersistentAuthenticationStateProvider в проекте для синхронизации состояния аутентификации пользователя между сервером и браузером. Класс представляет собой пользовательскую реализацию AuthenticationStateProvider. Поставщик использует службу состояния постоянного компонента (PersistentComponentState) для предварительного рендеринга состояния аутентификации и его сохранения на странице.
В основном проекте Blazor Web App поставщик состояния аутентификации называется IdentityRevalidatingAuthenticationStateProvider в папке Components/Account серверного проекта по шаблону Blazor Web App проекта (dotnet/aspnetcore GitHub репозиторий) (только для решений взаимодействия с сервером) или PersistingRevalidatingAuthenticationStateProvider (решения WebAssembly или автоматического взаимодействия) в той же папке.
Blazor Identity DbContext зависит от экземпляров, которые не созданы фабрикой. Это сделано намеренно, так как DbContext достаточно для компонентов Identity проекта, чтобы статично отображаться без поддержки интерактивности.
Чтобы узнать, как глобальные режимы интерактивной отрисовки применяются к компонентам без Identity, и как одновременно применяется статический SSR к компонентам Identity, см. в справочной статье ASP.NET Core Blazor режимы отрисовки.
Дополнительные сведения о сохранении предопределенного состояния см. в разделе ASP.NET Core Blazor сохраняемость предопределенного состояния.
Note
Ссылки на справочную документацию .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(репозиторийdotnet/aspnetcoreGitHub): для Blazor Web App, использующих интерактивный рендеринг на стороне сервера (интерактивный SSR) и рендеринг на стороне клиента (CSR). Эта серверная функция AuthenticationStateProvider, которая проверяет заново метку безопасности для подключенного пользователя каждые 30 минут в течение подключения интерактивной цепи. Она также использует службу постоянного состояния компонента для передачи состояния проверки подлинности клиенту, которое затем остается неизменным на протяжении всего времени существования CSR.PersistingServerAuthenticationStateProvider(репозиторийdotnet/aspnetcoreна GitHub): для Blazor Web App, которые используют только CSR. Это серверная составляющая AuthenticationStateProvider, которая использует службу состояния сохраняемого компонента для передачи состояния проверки подлинности клиенту, после чего это состояние остаётся неизменным на протяжении всего срока действия CSR.PersistentAuthenticationStateProvider(репозиторийdotnet/aspnetcoreGitHub): для Blazor Web App, использующих CSR. Это клиентская сторона AuthenticationStateProvider, которая определяет состояние аутентификации пользователя путем поиска данных, сохраненных на странице при генерации на сервере. Это состояние аутентификации фиксировано на все время существования CSR. Если пользователю нужно войти или выйти, требуется полная перезагрузка страницы. Это предоставляет только имя пользователя и электронную почту в целях отображения. Он не включает токены аутентификации для сервера при выполнении последующих запросов, обрабатываемых отдельно, используя cookie, который добавляется кHttpClientзапросам к серверу.
Note
Ссылки на справочную документацию .NET обычно открывают основную ветку репозитория, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в разделе Как выбрать тег версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Каркас Identity
Дополнительные сведения о скэффолдинге Identity на стороне сервера в приложении Blazor см. в разделе Scaffold Identity в проектах ASP.NET Core.
Проектируйте Identity в серверное Blazor приложение:
Дополнительные утверждения и маркеры от внешних поставщиков
Сведения о хранении дополнительных утверждений от внешних поставщиков см. в разделе Сохранение дополнительных утверждений и токенов от внешних поставщиков в ASP.NET Core.
Azure App Service на Linux с сервером Identity
Явно укажите эмитента при развертывании на Azure App Service под управлением Linux с Identity Server. Дополнительные сведения см. в разделе «Использование 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);
}
}
Дополнительные сведения см. в руководстве по OwningComponentBase в ASP.NET Core внедрению зависимостей.
Неразрешённое отображение содержимого при предварительной подготовке с помощью настраиваемого AuthenticationStateProvider
Чтобы избежать отображения несанкционированного содержимого, например содержимого в AuthorizeView компоненте, при предварительном создании с помощью пользовательского AuthenticationStateProvider, следует использовать один из следующих подходов:
Реализуйте IHostEnvironmentAuthenticationStateProvider для пользовательского AuthenticationStateProvider, чтобы поддерживать предварительное рендеринг: пример реализации IHostEnvironmentAuthenticationStateProvider можно найти в разделе о реализации Blazor фреймворка ServerAuthenticationStateProvider в
ServerAuthenticationStateProvider.cs(эталонный источник).Note
Ссылки на справочную документацию .NET обычно открывают основную ветку репозитория, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в разделе Как выбрать тег версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Отключить предварительную отрисовку: укажите режим отрисовки с параметром
prerender, установленным какfalseдля компонента на самом высоком уровне иерархии компонентов приложения, который не является корневым компонентом.Note
Создание интерактивного корневого компонента, например
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 Blazor режимы отрисовки.
Отключить предварительную отрисовку: Откройте файл
_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, что и страницы Razor и приложения MVC. Состояние пользователя, хранящееся для ASP.NET Core Identity, передаётся в Blazor без добавления дополнительного кода в приложение. Следуйте инструкциям в статьях и руководствах ASP.NET Core Identity для функций Identity, которые вступают в силу в Blazor части приложения.
Рекомендации по управлению общими состояниями за пределами ASP.NET Core Identity см. в разделе ASP.NET Core Blazor обзор управления состояниями.
Дополнительные абстракции безопасности
Две дополнительные абстракции участвуют в управлении состоянием аутентификации.
ServerAuthenticationStateProvider (справочный источник): используется AuthenticationStateProvider платформой Blazor для получения состояния проверки подлинности с сервера.
RevalidatingServerAuthenticationStateProvider(ссылочный источник): базовый класс для служб, используемых AuthenticationStateProvider платформой для получения состояния аутентификации из среды узла и его переутверждения через регулярные промежутки времени.
Note
Ссылки на справочную документацию .NET обычно открывают основную ветку репозитория, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного релиза, используйте раскрывающийся список Переключение ветвей или тегов. Дополнительные сведения см. в разделе Как выбрать тег версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
В приложениях, созданных из шаблона проекта Blazor для .NET 8 или более поздней версии, настройте интервал повторного изменения по умолчанию 30 минут в IdentityRevalidatingAuthenticationStateProvider. До версии .NET 8 настройте интервал в RevalidatingIdentityAuthenticationStateProvider. В следующем примере интервал сокращается до 20 минут:
protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(20);
Управление состоянием аутентификации при выходе из системы
Blazor Сервер сохраняет состояние аутентификации пользователя на протяжении всего сеанса, включая на вкладках браузера. Чтобы автоматически завершать сеанс пользователя на всех вкладках браузера при выходе с одной из них, необходимо реализовать RevalidatingServerAuthenticationStateProvider (эталонный источник) с коротким RevalidationInterval.
Note
Ссылки на справочную документацию .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 и собственные приложения для любой операционной системы.
Добавьте следующее.
Ссылка на пакет
Майкрософт.AspNetCore.Components.Authorizationдля NuGet.Note
Рекомендации по добавлению пакетов в приложения .NET см. в статьях, приведенных в разделе Установка и управление пакетами в потоке потребления пакетов (документация по NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Добавить пространство имен Майкрософт.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 или более поздней версии) в репозитории образцов 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 Core Blazor сохраняемость предопределенного состояния.
@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 {
[PersistentState]
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.
Если приложение использует платформа удостоверений Майкрософт с Майкрософт Identity Web пакеты для Microsoft Entra ID (см. Вызов веб-API из приложения ASP.NET Core Blazor), следующий 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. Стратегически применяйте безопасность, чтобы избежать неправильного доступа к данным.
Примеры в репозитории Blazor GitHub (dotnet/blazor-samples) (как скачать), демонстрирующие подход, описанный в этом разделе:
BlazorWebAppOidcBlazorWebAppOidcBffBlazorWebAppEntraBlazorWebAppEntraBff
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, можно перечислить заявления и оценить членство в ролях.
Дополнительные сведения о внедрении зависимостей (DI) и службах см. в статьях ASP.NET Core Blazor внедрение зависимостей и Внедрение зависимостей в ASP.NET Core. Сведения о том, как реализовать настраиваемый AuthenticationStateProvider, можно найти в разделе ASP.NET Core 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>
Note
В выпуске .NET 5.0.1 и для любых дополнительных выпусков 5.x компонент Router включает параметр PreferExactMatches, установленный на @true. Дополнительные сведения см. в разделе Migrate от ASP.NET Core 3.1 до .NET 5.
В клиентском Blazor приложении добавьте службы авторизации в Program файл:
builder.Services.AddAuthorizationCore();
В клиентском Blazor приложении добавьте параметры и службы авторизации в Program файл:
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
В серверном Blazor приложении службы для параметров и авторизации уже присутствуют, поэтому дальнейшие действия не требуются.
Authorization
После аутентификации пользователя применяются правила авторизации, которые определяют доступные этому пользователю действия.
Доступ обычно предоставляется или запрещается в зависимости от следующих аспектов:
- Пользователь аутентифицирован (вошел в систему).
- Пользователь находится в роли.
- У пользователя есть претензия.
- Политика policy удовлетворена.
Каждое из этих понятий совпадает с ASP.NET Core MVC или приложением Razor Pages. Дополнительные сведения о безопасности ASP.NET Core см. в статьях ASP.NET Core Security and 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 на стороне сервера обрабатывает авторизацию. Используйте серверные методы, такие как настройка LoginPath для обработки несанкционированных запросов. Дополнительные сведения см. в разделе ASP.NET Core Blazor режимы отрисовки.
Warning
Разметка на стороне клиента и методы, связанные с элементом AuthorizeView, защищены только от просмотра и выполнения в рендеренном пользовательском интерфейсе в клиентских приложениях Blazor. Чтобы защитить авторизованное содержимое и безопасные методы на стороне Blazorклиента, содержимое обычно предоставляется безопасным, авторизованным вызовом веб-API к API сервера и никогда не хранится в приложении. Дополнительные сведения см. в разделе
Содержимое Authorized и NotAuthorized может включать произвольные элементы, например другие интерактивные компоненты.
Условия авторизации, такие как роли или правила для выбора вариантов пользовательского интерфейса и доступа к ним, описаны в разделе об авторизации.
Если условия авторизации не указаны, AuthorizeView использует политику по умолчанию:
- Пользователи, прошедшие проверку подлинности, авторизованы.
- Неавторизованные (вышедшие из системы) пользователи не имеют разрешения.
Компонент AuthorizeView можно использовать в компоненте NavMenu (Shared/NavMenu.razor) для отображения компонента NavLink (NavLink), но следует учитывать, что при использовании этого подхода удаляется только элемент списка из отображаемых выходных данных. Это не препятствует пользователю переходить к компоненту. Реализуйте авторизацию отдельно в целевом компоненте.
Авторизация на основе ролей и политик
Компонент AuthorizeView поддерживает авторизацию на основе ролей или политик.
Для авторизации на основе ролей используйте 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.
Для авторизации на основе политик используйте AuthorizeView.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). Дополнительные сведения см. в разделе Авторизация на основе заявок в ASP.NET Core. Напротив, в ASP.NET Core поиск имен политики обычно регистронезависимый, поэтому RequireAdministratorRole и requireadministratorrole ссылаются на ту же политику.
Содержимое, отображаемое при асинхронной аутентификации
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.
Important
Используйте [Authorize] только для компонентов @page, доступных через маршрутизатор Blazor. Авторизация выполняется только как аспект маршрутизации и не для дочерних компонентов, которые отображаются на странице. Чтобы разрешить отображение конкретных частей на странице, используйте вместо этого AuthorizeView.
Атрибут [Authorize] также поддерживает авторизацию на основе ролей или политик. Для авторизации на основе ролей примените параметр AuthorizeAttribute.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:
Добавьте пространства имен для Майкрософт.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>.
Important
функции Blazor маршрутизатора, которые отображают <NotAuthorized> и <NotFound> содержимое, не работают во время отрисовки на стороне статического сервера (SSR), так как обработка запросов полностью обрабатывается каналом промежуточного ПО ASP.NET Core, и Razor компоненты не отображаются вообще для несанкционированных или плохих запросов. Используйте методы на стороне сервера для обработки несанкционированных и плохих запросов во время статического SSR. Дополнительные сведения см. в разделе ASP.NET Core Blazor режимы отрисовки.
<Router ...>
<Found ...>
<AuthorizeRouteView ...>
<NotAuthorized>
...
</NotAuthorized>
<Authorizing>
...
</Authorizing>
</AuthorizeRouteView>
</Found>
</Router>
Содержимое Authorized и NotAuthorized может включать произвольные элементы, например другие интерактивные компоненты.
Note
Для предыдущей процедуры требуется каскадная регистрация государственных служб проверки подлинности в файле приложения 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 убедитесь в наличии пространств имен Майкрософт.AspNetCore.Authorization и Майкрософт.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 ссылается на любую информацию, связанную с идентифицированным или идентифицируемым физическим лицом. Идентифицируемый физический человек — это тот, кто может быть идентифицирован, прямо или косвенно, с любым из следующих элементов:
- Name
- Идентификационный номер
- Координаты расположения
- Идентификатор в Сети
- Другие конкретные факторы
- Physical
- Physiological
- Genetic
- Психический (психологический)
- Economic
- Cultural
- Социальная идентичность
Дополнительные ресурсы
- Серверная часть и Blazor Web App ресурсы
- Quickstart: добавьте вход с Майкрософт в веб-приложение ASP.NET Core
- Quickstart: защита веб-API ASP.NET Core с помощью платформа удостоверений Майкрософт
-
Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки. Включает следующие рекомендации.
- Использование промежуточного программного обеспечения для перенаправленных заголовков для сохранения сведений о схеме HTTPS на прокси-серверах и во внутренних сетях.
- Дополнительные сценарии и варианты использования, включая ручную настройку схемы, изменение пути запроса для правильной маршрутизации запроса и перенаправление схемы запроса для обратных прокси-серверов Linux и обратных прокси-серверов, отличных от IIS.
- документация по платформа удостоверений Майкрософт
- темы безопасности ASP.NET Core
- Configure Windows Authentication in ASP.NET Core
- IHttpContextAccessor/HttpContext в приложениях ASP.NET Core Blazor
- Создание пользовательской версии библиотеки Authentication.MSAL для JavaScript
- ЗамечательныеBlazor: примеры ссылок сообщества аутентификации
- Аутентификация и авторизация в ASP.NET CoreBlazor Hybrid
- Серверные Blazor ресурсы
- Quickstart: добавьте вход с Майкрософт в веб-приложение ASP.NET Core
- Quickstart: защита веб-API ASP.NET Core с помощью платформа удостоверений Майкрософт
-
Configure ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки. Включает следующие рекомендации.
- Использование промежуточного программного обеспечения для перенаправленных заголовков для сохранения сведений о схеме HTTPS на прокси-серверах и во внутренних сетях.
- Дополнительные сценарии и варианты использования, включая ручную настройку схемы, изменение пути запроса для правильной маршрутизации запроса и перенаправление схемы запроса для обратных прокси-серверов Linux и обратных прокси-серверов, отличных от IIS.
- документация по платформа удостоверений Майкрософт
- Overview
- OAuth 2.0 и протоколы OpenID Connect на платформе идентификации Microsoft
- Платформа идентификации Microsoft и поток авторизационного кода OAuth 2.0
- токены идентификации платформы Microsoft Identity
- Токены доступа платформа удостоверений Майкрософт
- темы безопасности ASP.NET Core
- IHttpContextAccessor/HttpContext в приложениях ASP.NET Core Blazor
- Configure Windows Authentication in ASP.NET Core
- Создание пользовательской версии библиотеки Authentication.MSAL для JavaScript
- ЗамечательныеBlazor: примеры ссылок сообщества аутентификации
ASP.NET Core