Konfigurowanie uwierzytelniania openID Connect Web (UI) w programie ASP.NET Core
Autor: Damien Bowden
Wyświetlanie lub pobieranie przykładowego kodu
W tym artykule opisano następujące obszary:
- Co to jest poufny klient interakcyjny OpenID Connect
- Tworzenie klienta OpenID Connect w programie ASP.NET Core
- Przykłady klienta OpenID Connect z fragmentami kodu
- Korzystanie z klientów dostawcy OpenID Connect innej firmy
- Zaplecze dla architektury zabezpieczeń frontonu (BFF)
- Zaawansowane funkcje, standardy, rozszerzanie klienta OpenID Connect
Aby uzyskać alternatywne środowisko korzystania z biblioteki uwierzytelniania Microsoft dla platformy .NET, Microsoft Identity Webi Microsoft Entra ID, zobacz przewodnik Szybki start : logowanie użytkowników i wywoływanie interfejsu API programu Microsoft Graph z ASP.NETcore aplikacji internetowej (dokumentacja platformy Azure).
Aby zapoznać się z przykładem korzystania z zewnętrznego serwera OIDC identyfikatora firmy Microsoft Entra, zobacz Logowanie użytkowników w przykładowej aplikacji webowej ASP.NET Core w zewnętrznym dzierżawcy oraz Aplikacja webowa ASP.NET Core uwierzytelniająca użytkowników przeciwko Microsoft Entra External ID za pomocą Microsoft Identity Web.
Co to jest poufny klient interakcyjny OpenID Connect
OpenID Connect może służyć do implementowania uwierzytelniania w aplikacjach ASP.NET Core. Zalecanym sposobem jest użycie poufnego klienta OpenID Connect przy użyciu przepływu kodu. W tej implementacji zaleca się użycie klucza dowodowego do wymiany kodu przez klientów publicznych OAuth (PKCE ). Zarówno klient aplikacji, jak i użytkownik aplikacji są uwierzytelniane w przepływie poufnym. Klient aplikacji używa wpisu tajnego klienta lub potwierdzenia klienta do uwierzytelniania.
Klienci public OpenID Connect/OAuth nie są już zalecane w przypadku aplikacji internetowych.
Domyślny przepływ działa, jak pokazano na poniższym diagramie:
Program OpenID Connect jest dostępny w wielu odmianach, a wszystkie implementacje serwera mają nieco inne parametry i wymagania. Niektóre serwery nie obsługują punktu końcowego informacji o użytkowniku, a niektóre nadal nie obsługują PKCE, a inne wymagają specjalnych parametrów w żądaniu tokenu. Asercji klienta można używać zamiast wpisów tajnych klienta. Istnieją również nowe standardy, które dodają dodatkowe zabezpieczenia na podstawie openID Connect Core, na przykład FAPI, CIBA lub DPoP dla podrzędnych interfejsów API.
Uwaga
Z platformy .NET 9 używany jest protokół OAuth 2.0 pushed authorization requests (PAR) RFC 9126 na wartość domyślną, jeśli serwer OpenID Connect obsługuje tę funkcję. Jest to przepływ trzech kroków, a nie przepływ dwuetapowy, jak pokazano powyżej. (Żądanie informacji o użytkowniku jest krokiem opcjonalnym).
Tworzenie klienta przepływu kodu Open ID Connect przy użyciu stron Razor
W poniższej sekcji pokazano, jak zaimplementować klienta OpenID Connect w pustym projekcie strony ASP.NET Core Razor . Tę samą logikę można zastosować do dowolnego projektu internetowego platformy ASP.NET Core, przy czym integracja interfejsu użytkownika jest inna.
Dodawanie obsługi programu OpenID Connect
Dodaj pakiety Microsoft.AspNetCore.Authentication.OpenIdConnect
Nuget do projektu ASP.NET Core.
Konfigurowanie klienta OpenID Connect
Dodaj uwierzytelnianie do aplikacji internetowej, korzystając z builder.Services w pliku Program.cs
. Konfiguracja jest zależna od serwera OpenID Connect. Każdy serwer OpenID Connect wymaga niewielkich różnic w konfiguracji.
Procedura obsługi OpenID Connect jest używana do wyzwań i wylogowyń. Element cookie służy do obsługi sesji w aplikacji internetowej. Schematy domyślne uwierzytelniania można określić zgodnie z wymaganiami.
Aby uzyskać więcej informacji, zobacz wskazówkidotyczące
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";
});
Aby uzyskać szczegółowe informacje na temat różnych opcji programu OpenID Connect, zobacz Secure an ASP.NET Core Blazor Web App with OpenID Connect (OIDC).
Aby zapoznać się z różnymi możliwościami mapowania oświadczeń, zobacz Mapowanie, dostosowywanie i przekształcanie oświadczeń w usłudze ASP.NET Core.
Uwaga
Wymagane są następujące przestrzenie nazw:
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;
Konfigurowanie właściwości konfiguracji
Dodaj ustawienia klienta OpenID Connect do właściwości konfiguracji aplikacji. Ustawienia muszą być zgodne z konfiguracją klienta na serwerze OpenID Connect. W ustawieniach aplikacji nie należy utrwalać żadnych tajemnic, ponieważ mogą zostać tam przypadkowo zapisane. Wpisy tajne powinny być przechowywane w bezpiecznej lokalizacji, takiej jak usługa Azure Key Vault w środowiskach produkcyjnych lub wpisów tajnych użytkownika w środowisku deweloperskim. Aby uzyskać więcej informacji, zobacz Bezpieczne przechowywanie sekretów aplikacji w środowisku developerskim w 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--"
},
Konfiguracja ścieżki wywołania zwrotnego wylogowanego
SignedOutCallbackPath (klucz konfiguracji: "SignedOutCallbackPath
") jest ścieżką żądania w ścieżce podstawowej aplikacji przechwyconą przez program obsługi OpenID Connect, gdzie agent użytkownika jest najpierw przekierowywany po wylogowaniu się z dostawcy usług tożsamości. Przykładowa aplikacja nie ustawia wartości dla ścieżki, ponieważ jest używana domyślna wartość "/signout-callback-oidc
". Po przechwyceniu żądania program obsługi OpenID Connect przekierowuje do SignedOutRedirectUri lub RedirectUri, jeśli jest to określone.
Skonfiguruj ścieżkę wywołania zwrotnego po wylogowaniu w rejestracji dostawcy OIDC aplikacji. W poniższym przykładzie symbol zastępczy {PORT}
jest portem aplikacji:
https://localhost:{PORT}/signout-callback-oidc
Uwaga
W przypadku korzystania z identyfikatora Entra firmy Microsoft ustaw ścieżkę w konfiguracji platformyidentyfikatora URI przekierowania wpisów w witrynie Entra lub Azure Portal. Port nie jest wymagany dla adresów localhost
w przypadku korzystania z usługi Entra. Większość innych dostawców OIDC wymaga poprawnego portu. Jeśli nie dodasz identyfikatora URI ścieżki wywołania zwrotnego wylogowania do rejestracji aplikacji w Entra, Entra odmówi przekierowania użytkownika z powrotem do aplikacji i jedynie poprosi ich o zamknięcie okna przeglądarki.
Zaktualizuj metodę potoku ASP.NET Core w klasie programu.
Przed metodą UseAuthorization
należy zaimplementować metodę UseRouting
.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
// Authorization is applied for middleware after the UseAuthorization method
app.UseAuthorization();
app.MapRazorPages();
Wymuszanie autoryzacji
Dodaj atrybut [Authorize]
do chronionych stron Razor.
[Authorize]
Lepszym podejściem jest wymusić autoryzację dla całej aplikacji i zrezygnować z niezabezpieczonych stron:
var requireAuthPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
builder.Services.AddAuthorizationBuilder()
.SetFallbackPolicy(requireAuthPolicy);
Dodawanie nowych stron Logout.cshtml
i SignedOut.cshtml
Razor do projektu
Konieczne jest wylogowanie zarówno z sesji cookie, jak i sesji OpenID Connect. Cała aplikacja musi zostać przekierowana na serwer OpenID Connect, aby się wylogować. Po pomyślnym wylogowaniu aplikacja otwiera trasę RedirectUri
.
Zaimplementuj domyślną stronę wylogowania i zmień kod Logout
razor na następujący:
[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
wymaga atrybutu [AllowAnonymous]
:
[AllowAnonymous]
public class SignedOutModel : PageModel
{
public void OnGet()
{
}
}
Implementowanie strony Login
Można również zaimplementować stronę Login
Razor w celu wywołania ChallengeAsync
bezpośrednio przy użyciu wymaganego AuthProperties
. Nie jest to wymagane, jeśli aplikacja internetowa wymaga uwierzytelniania i jest używane domyślne wyzwanie.
Strona Login.cshtml
wymaga atrybutu [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 };
}
}
Dodawanie przycisku logowania i wylogowywanie użytkownika
@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>
}
Przykłady z fragmentami kodu
Przykład użycia punktu końcowego informacji o użytkowniku
Opcje openID Connect mogą służyć do mapowania oświadczeń, implementowania procedur obsługi, a nawet zapisywania tokenów w sesji na potrzeby późniejszego użycia.
Opcja Scope
może służyć do żądania różnych roszczeń lub tokenu odświeżania, które są przesyłane jako informacja do serwera OpenID Connect. Żądanie offline_access
nakazuje serwerowi zwrócenie tokenu odwołania, którego można użyć do odświeżenia sesji bez ponownej autoryzacji użytkownika aplikacji.
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";
});
Implementowanie dostawców tożsamości firmy Microsoft
Microsoft posiada wielu dostawców tożsamości i implementacje OpenID Connect. Firma Microsoft ma różne serwery OpenID Connect:
- Microsoft Entra ID
- Zewnętrzny identyfikator Microsoft Entra
- Azure AD B2C
W przypadku uwierzytelniania przy użyciu jednego z dostawców tożsamości firmy Microsoft w programie ASP.NET Core zaleca się użycie pakietów Microsoft.Identity.Web
Nuget.
Pakiety Microsoft.Identity.Web
Nuget to określony klient firmy Microsoft oparty na kliencie ASP.NET Core OpenID Connect z pewnymi zmianami w kliencie domyślnym.
Korzystanie z klientów dostawcy OpenID Connect innej firmy
Wiele implementacji serwera OpenID Connect tworzy pakiety Nuget zoptymalizowane pod kątem tej samej implementacji openID Connect. Te pakiety implementują specyfikę klienta OpenID Connect z dodatkowymi wymaganymi przez określony serwer OpenID Connect.
Microsoft.Identity.Web
jest jednym z przykładów tego.
Jeśli w jednej aplikacji implementuje się wielu klientów OpenID Connect z różnych serwerów OpenID Connect, zwykle lepiej jest wrócić do domyślnej implementacji ASP.NET Core, ponieważ różni klienci zastępują niektóre opcje, co wpływa na innych klientów.
Dostawcy sieci Web OpenIddict to implementacja klienta, która obsługuje wiele różnych implementacji serwera.
IdentityModel
to standardowa biblioteka pomocnika platformy .NET dla tożsamości opartej na oświadczeniach, OAuth 2.0 i OpenID Connect. Może to również pomóc w implementacji klienta.
Zaplecze dla architektury zabezpieczeń frontonu (BFF)
Nie zaleca się już implementowania klientów publicznych openID Connect dla wszystkich aplikacji internetowych.
Aby uzyskać więcej informacji, zobacz projekt OAuth 2.0 dla aplikacji Browser-Based .
W przypadku implementowania aplikacji internetowych
Zaawansowane funkcje, standardy, rozszerzanie klienta OIDC
Rejestrowanie
Debugowanie klientów OpenID Connect może być trudne. Dane osobowe nie są domyślnie rejestrowane. W przypadku debugowania w trybie programowania IdentityModelEventSource.ShowPII
może służyć do rejestrowania poufnych danych osobowych. Nie wdrażaj aplikacji z IdentityModelEventSource.ShowPII
na serwerach produkcyjnych.
//using ...
using Microsoft.IdentityModel.Logging;
var builder = WebApplication.CreateBuilder(args);
//... code
var app = builder.Build();
IdentityModelEventSource.ShowPII = true;
//... code
app.Run();
Aby uzyskać więcej informacji, zobacz Logging.
Uwaga
Możesz chcieć obniżyć skonfigurowany poziom dziennika, aby wyświetlić wszystkie wymagane dzienniki.
Dostosowywanie parametrów OIDC i OAuth
Opcja obsługi uwierzytelniania przez programy OAuth i OIDC (AdditionalAuthorizationParameters) umożliwia dostosowanie parametrów komunikatów autoryzacji, które są zwykle dołączane jako część ciągu zapytania przekierowania.
Mapuj oświadczenia z openID Connect
Aby uzyskać więcej informacji, zobacz Mapowanie, dostosowywanie i przekształcanie oświadczeń w ASP.NET Core.
Blazor OpenID Connect
Aby uzyskać więcej informacji, zobacz Zabezpiecz aplikację ASP.NET Core Blazor Web App z użyciem OpenID Connect (OIDC).