Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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
- Architektura bezpieczeństwa typu Backend for Frontend (BFF)
- Zaawansowane funkcje, standardy, rozszerzanie klienta OpenID Connect
Aby uzyskać alternatywne doświadczenie korzystania z biblioteki Microsoft Authentication Library dla platformy .NET, Microsoft Identity Web i Microsoft Entra ID, zobacz przewodnik Szybki Start: logowanie użytkowników i wywoływanie interfejsu API programu Microsoft Graph z aplikacji internetowej ASP.NET Core (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 z wykorzystaniem procesu przepływu kodu. Zaleca się użycie klucza dowodowego do wymiany kodu przez klientów publicznych OAuth (PKCE) w tej implementacji. Zarówno klient aplikacji, jak i użytkownik aplikacji są uwierzytelniani w poufnym przepływie. Klient aplikacji używa tajemnicy klienta lub uwierzytelnienia 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. Potwierdzeń klienta można używać zamiast tajemnic 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
Od .NET 9 domyślnie używany jest protokół OAuth 2.0 Pushed Authorization Requests (PAR) RFC 9126, 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 OpenID 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;
Skonfiguruj właściwości
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. Tajne dane powinny być przechowywane w bezpiecznej lokalizacji, takiej jak Azure Key Vault w środowiskach produkcyjnych lub tajemnice użytkowników w środowisku deweloperskim. Aby uzyskać więcej informacji, zobacz Bezpieczne przechowywanie tajnych informacji aplikacji 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
Korzystając z Microsoft Entra ID, ustaw ścieżkę w konfiguracji platformy dla wpisów identyfikatora URI przekierowania w portalu Entra lub Azure. 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ą UseRouting
należy zaimplementować metodę UseAuthorization
.
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);
Zrezygnuj z autoryzacji na publicznych punktach końcowych, stosując atrybut [AllowAnonymous]
. Aby zapoznać się z przykładami, zobacz sekcje Dodawanie nowych Logout.cshtml
stron i SignedOut.cshtml
Razor do projektu i Implementowanie Login
strony .
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 wykorzystania 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
- Identyfikator zewnętrzny 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 wraz z dodatkami 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. To może również zostać użyte do pomocy 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).