Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Просмотреть или скачать образец кода
В этой статье рассматриваются следующие области:
- Что такое конфиденциальный интерактивный клиент OpenID Connect
- Создание клиента OpenID Connect в ASP.NET Core
- Примеры клиента OpenID Connect с фрагментами кода
- Использование сторонних клиентов поставщика OpenID Connect
- Серверная часть для архитектуры безопасности внешнего интерфейса (BFF)
- Расширенные функции, стандарты, расширение клиента OpenID Connect
Для альтернативного опыта использования библиотеки проверки подлинности Майкрософт для .NET, Microsoft Identity Web и Microsoft Entra ID см. в разделе "Краткое руководство: вход пользователей и вызов Microsoft Graph API из веб-приложения ASP.NET Core (документация Azure)."
Пример использования OIDC-сервера Microsoft Entra External ID смотрите в документации: "Вход пользователей для демонстрационного веб-приложения ASP.NET Core во внешнем арендаторе" и "Веб-приложение ASP.NET Core, которое аутентифицирует пользователей через Microsoft Entra External ID с использованием Microsoft Identity Web".
Что такое конфиденциальный интерактивный клиент OpenID Connect
OpenID Connect можно использовать для реализации проверки подлинности в приложениях ASP.NET Core. Рекомендуется использовать конфиденциальный клиент OpenID Connect, используя поток кода. Для этой реализации рекомендуется использовать ключ подтверждения для обмена кодом от общедоступных клиентов OAuth (PKCE). Клиент приложения и пользователь приложения проходят проверку подлинности в конфиденциальном потоке. Клиент приложения использует секрет клиента или утверждение клиента для проверки подлинности.
Общедоступные клиенты OpenID Connect/OAuth больше не рекомендуются для веб-приложений.
Поток по умолчанию работает, как показано на следующей схеме:
OpenID Connect поставляется во многих вариантах, и все реализации сервера имеют немного разные параметры и требования. Некоторые серверы не поддерживают конечную точку пользовательской информации, некоторые по-прежнему не поддерживают PKCE, а другие требуют специальных параметров в запросе токена. Утверждения клиента можно использовать вместо секретов клиента. Новые стандарты также существуют, которые добавляют дополнительную безопасность поверх OpenID Connect Core, например FAPI, CIBA или DPoP для подчиненных API.
Примечание.
Начиная с .NET 9, OAuth 2.0 Pushed Authorization Requests (PAR) RFC 9126 используется по умолчанию, если сервер OpenID Connect поддерживает это. Это три шага, а не два шага, как показано выше. (Запрос сведений о пользователе является необязательным шагом.)
Создание клиента потока кода Open ID Connect с помощью Razor Pages
В следующем разделе показано, как реализовать клиент OpenID Connect в пустом проекте страницы ASP.NET Core Razor . Та же логика может применяться к любому веб-проекту ASP.NET Core, но только интеграция пользовательского интерфейса отличается.
Добавление поддержки OpenID Connect
Microsoft.AspNetCore.Authentication.OpenIdConnect Добавьте пакеты Nuget в проект ASP.NET Core.
Настройка клиента OpenID Connect
Добавьте аутентификацию в веб-приложение, используя builder.Services в файле Program.cs. Конфигурация зависит от сервера OpenID Connect. Каждый сервер OpenID Connect требует небольших различий в настройке.
Обработчик OpenID Connect используется для аутентификационных вызовов и выхода из системы. Используется cookie для обработки сеанса в веб-приложении. Схемы по умолчанию для проверки подлинности можно указать по мере необходимости.
Дополнительные сведения см. в руководстве по ASP.NET Coreauthentication-handler.
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
var oidcConfig = builder.Configuration.GetSection("OpenIDConnectSettings");
options.Authority = oidcConfig["Authority"];
options.ClientId = oidcConfig["ClientId"];
options.ClientSecret = oidcConfig["ClientSecret"];
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.ResponseType = OpenIdConnectResponseType.Code;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.MapInboundClaims = false;
options.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
options.TokenValidationParameters.RoleClaimType = "roles";
});
Дополнительные сведения о различных параметрах OpenID Connect см. в статье "Защита ASP.NET Core Blazor Web App с помощью OpenID Connect (OIDC)".
Сведения о различных возможностях сопоставления утверждений см. в разделе "Сопоставление", "Настройка" и преобразование утверждений в ASP.NET Core.
Примечание.
Требуются следующие пространства имен:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
Настройка свойств конфигурации
Добавьте параметры клиента OpenID Connect в свойства конфигурации приложения. Параметры должны соответствовать конфигурации клиента на сервере OpenID Connect. Секреты не должны сохраняться в параметрах приложения, где они могут быть случайно возвращены. Секреты должны храниться в безопасном расположении, например Azure Key Vault в рабочих средах или в секретах пользователей в среде разработки. Дополнительные сведения см. в статье Надежное хранение секретов приложений при разработке в ASP.NET Core.
"OpenIDConnectSettings": {
// OpenID Connect URL. (The base URL for the /.well-known/openid-configuration)
"Authority": "<Authority>",
// client ID from the OpenID Connect server
"ClientId": "<Client ID>",
//"ClientSecret": "--stored-in-user-secrets-or-key-vault--"
},
Конфигурация пути обратного вызова после выхода из системы
Запрос "SignedOutCallbackPath" (ключ конфигурации: "SignedOutCallbackPath") - это путь в базовом пути приложения, который перехватывается обработчиком OpenID Connect. Здесь агент пользователя сначала возвращается после выхода из системы поставщика удостоверений. Пример приложения не задает значение для пути, так как используется значение по умолчанию "/signout-callback-oidc". После перехвата запроса обработчик OpenID Connect перенаправляет на SignedOutRedirectUri или RedirectUri, если задано.
Настройте путь обратного вызова для выхода из системы в настройках провайдера OIDC приложения. В следующем примере заполнитель {PORT} является портом приложения:
https://localhost:{PORT}/signout-callback-oidc
Примечание.
При использовании Microsoft Entra ID укажите путь в конфигурации платформы для записей URI перенаправления на портале Entra или Azure. Порт не требуется для адресов localhost при использовании Entra. Большинству других поставщиков OIDC требуется правильный порт. Если вы не добавите URI пути обратного вызова после выхода из системы в регистрацию приложения в Entra, Entra откажется перенаправить пользователя обратно в приложение и просто попросит его закрыть окно браузера.
Обновите метод конвейера ASP.NET Core в классе программы.
Метод UseRouting должен быть реализован перед методом UseAuthorization.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
// Authorization is applied for middleware after the UseAuthorization method
app.UseAuthorization();
app.MapRazorPages();
Принудительная авторизация
Добавьте атрибут [Authorize] к защищённым Razor страницам:
[Authorize]
Лучший подход заключается в принудительном авторизации для всего приложения и отказе от небезопасных страниц:
var requireAuthPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
builder.Services.AddAuthorizationBuilder()
.SetFallbackPolicy(requireAuthPolicy);
Отказ от авторизации на общедоступных конечных точках путем применения атрибута[AllowAnonymous] к общедоступным конечным точкам. Примеры см. в разделах "Добавить новую Logout.cshtml и SignedOut.cshtmlRazor страницы к проекту" и "Реализация Login страницы".
Добавьте новые страницы Logout.cshtml и SignedOut.cshtmlRazor в проект
Для выхода из сеанса cookie и сеанса OpenID Connect требуется выход. Для выхода из системы все приложение должно быть перенаправлено на сервер OpenID Connect. После успешного выхода приложение открывает маршрут RedirectUri.
Реализуйте страницу выхода по умолчанию и измените Logout код страницы razor следующим образом:
[Authorize]
public class LogoutModel : PageModel
{
public IActionResult OnGetAsync()
{
return SignOut(new AuthenticationProperties
{
RedirectUri = "/SignedOut"
},
// Clear auth cookie
CookieAuthenticationDefaults.AuthenticationScheme,
// Redirect to OIDC provider signout endpoint
OpenIdConnectDefaults.AuthenticationScheme);
}
}
Требуется атрибут SignedOut.cshtml для [AllowAnonymous].
[AllowAnonymous]
public class SignedOutModel : PageModel
{
public void OnGet()
{
}
}
Реализовать Login страницу
Также LoginRazor можно реализовать страницу для вызова ChallengeAsync непосредственно с обязательным AuthProperties. Это не обязательно, если веб-приложение требует проверки подлинности и используется проблема по умолчанию.
Для Login.cshtml страницы требуется [AllowAnonymous] атрибут:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace RazorPageOidc.Pages;
[AllowAnonymous]
public class LoginModel : PageModel
{
[BindProperty(SupportsGet = true)]
public string? ReturnUrl { get; set; }
public async Task OnGetAsync()
{
var properties = GetAuthProperties(ReturnUrl);
await HttpContext.ChallengeAsync(properties);
}
private static AuthenticationProperties GetAuthProperties(string? returnUrl)
{
const string pathBase = "/";
// Prevent open redirects.
if (string.IsNullOrEmpty(returnUrl))
{
returnUrl = pathBase;
}
else if (!Uri.IsWellFormedUriString(returnUrl, UriKind.Relative))
{
returnUrl = new Uri(returnUrl, UriKind.Absolute).PathAndQuery;
}
else if (returnUrl[0] != '/')
{
returnUrl = $"{pathBase}{returnUrl}";
}
return new AuthenticationProperties { RedirectUri = returnUrl };
}
}
Добавление кнопки входа и выхода для пользователя
@if (Context.User.Identity!.IsAuthenticated)
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Logout">Logout</a>
</li>
<span class="nav-link text-dark">Hi @Context.User.Identity.Name</span>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Login</a>
</li>
}
Примеры с фрагментами кода
Пример использования конечной точки информации о пользователе
Параметры OpenID Connect можно использовать для отображения утверждений, реализации обработчиков или даже сохранения токенов в сессии для их последующего использования.
Этот Scope параметр можно использовать для запроса различных утверждений или маркера обновления, который отправляется в качестве сведений на сервер OpenID Connect. Запрос offline_access просит сервер вернуть ссылочный токен, который можно использовать для обновления сеанса без повторной проверки подлинности пользователя приложения снова.
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
var oidcConfig = builder.Configuration.GetSection("OpenIDConnectSettings");
options.Authority = oidcConfig["IdentityProviderUrl"];
options.ClientSecret = oidcConfig["ClientSecret"];
options.ClientId = oidcConfig["Audience"];
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.Scope.Add("offline_access");
options.ClaimActions.Remove("amr");
options.ClaimActions.MapUniqueJsonKey("website", "website");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
// .NET 9 feature
options.PushedAuthorizationBehavior = PushedAuthorizationBehavior.Require;
options.TokenValidationParameters.NameClaimType = "name";
options.TokenValidationParameters.RoleClaimType = "role";
});
Внедрение поставщиков удостоверений Microsoft
Корпорация Майкрософт имеет несколько поставщиков удостоверений и реализации OpenID Connect. Корпорация Майкрософт имеет разные серверы OpenID Connect:
- Microsoft Entra ID
- Внешний идентификатор Microsoft Entra
- Azure AD B2C
При проверке подлинности с использованием одного из поставщиков удостоверений Microsoft в ASP.NET Core рекомендуется использовать пакеты NuGet Microsoft.Identity.Web.
Пакеты Microsoft.Identity.Web Nuget — это конкретный клиент Майкрософт, созданный на основе клиента ASP.NET Core OpenID Connect с некоторыми изменениями в клиенте по умолчанию.
Использование сторонних клиентов поставщика OpenID Connect
Многие реализации сервера OpenID Connect создают пакеты Nuget, оптимизированные для той же реализации OpenID Connect. Эти пакеты реализуют особенности клиента OpenID Connect с дополнительными компонентами, необходимыми для конкретного сервера OpenID Connect.
Microsoft.Identity.Web является одним из примеров этого.
При реализации нескольких клиентов OpenID Connect из разных серверов OpenID Connect в одном приложении обычно лучше вернуться к реализации по умолчанию ASP.NET Core, так как разные клиенты перезаписывают некоторые параметры, влияющие на другие клиенты.
Веб-поставщики OpenIddict — это клиентская реализация, которая поддерживает множество различных реализаций сервера.
IdentityModel — вспомогательная библиотека .NET стандарт для идентификации на основе утверждений, OAuth 2.0, OpenID Connect. Это также можно использовать для поддержки реализации клиента.
Серверная часть для архитектуры безопасности внешнего интерфейса (BFF)
Для любых веб-приложений больше не рекомендуется реализовать общедоступные клиенты OpenID Connect.
Подробности см. в черновике OAuth 2.0 для приложений Browser-Based.
При реализации веб-приложений, которые не имеют независимой серверной части, рекомендуется использовать архитектуру безопасности шаблонов серверной части (BFF). Этот шаблон можно реализовать разными способами, но проверка подлинности всегда реализуется в серверной части, и конфиденциальные данные не отправляются веб-клиенту для дальнейшего авторизации или проверки подлинности.
Расширенные функции, стандарты, расширение клиента OIDC
Логирование
Отладка клиентов OpenID Connect может быть сложной. Персональные данные (PII) по умолчанию не регистрируются. При отладке в режиме разработки IdentityModelEventSource.ShowPII можно использовать для логирования конфиденциальных персональных данных. Не развертывайте приложение IdentityModelEventSource.ShowPII на продуктивных серверах.
//using ...
using Microsoft.IdentityModel.Logging;
var builder = WebApplication.CreateBuilder(args);
//... code
var app = builder.Build();
IdentityModelEventSource.ShowPII = true;
//... code
app.Run();
Более подробную информацию см. в разделе Ведение журналов.
Примечание.
Возможно, потребуется снизить настроенный уровень журнала, чтобы просмотреть все необходимые журналы.
Настройка OIDC и параметра OAuth
Опция обработчиков проверки подлинности OAuth и OIDC (AdditionalAuthorizationParameters) позволяет настраивать параметры сообщения авторизации, которые обычно включаются в запрос перенаправления.
Карта утверждений из OpenID Connect
Дополнительные сведения см. в разделе "Сопоставление", "Настройка" и преобразование утверждений в ASP.NET Core.
Blazor OpenID Connect
Дополнительные сведения см. в статье "Защита ASP.NET Core Blazor Web App с помощью OpenID Connect (OIDC)".