Sdílet prostřednictvím


Konfigurace ověřování OpenID Connect Web (UI) v ASP.NET Core

Autor: Damien Bowden

Zobrazení nebo stažení ukázkového kódu

Tento článek se zabývá následujícími oblastmi:

  • Co je důvěrný interaktivní klient OpenID Connect
  • Vytvoření klienta OpenID Connect v ASP.NET Core
  • Příklady klienta OpenID Connect s fragmenty kódu
  • Použití klientů zprostředkovatele OpenID Connect třetích stran
  • Back-end pro architekturu zabezpečení front-endu (BFF)
  • Pokročilé funkce, standardy a rozšíření klienta OpenID Connect

Alternativní způsob použití Microsoft Authentication Library pro .NET, Microsoft Identity Weba Microsoft Entra IDviz dokumentace k Azure v části Rychlý start: Přihlášení uživatelů a volání rozhraní Microsoft Graph API z webové aplikace ASP.NET Core.

Příklad použití serveru OIDC pro externí ID Microsoft Entra najdete v části Přihlášení uživatelů pro ukázkovou webovou aplikaci ASP.NET Core v externím tenantovi a ASP.NET Core webovou aplikaci, která uživatele ověřuje proti Microsoft Entra External ID za použití serveru Microsoft Identity Web.

Co je důvěrný interaktivní klient OpenID Connect

OpenID Connect se dá použít k implementaci ověřování v aplikacích ASP.NET Core. Doporučeným způsobem je použít důvěrného klienta OpenID Connect pomocí toku kódu. Pro tuto implementaci se doporučuje použití ověřovacího klíče pro výměnu kódu veřejnými klienty OAuth (PKCE ). Klient aplikace i uživatel aplikace se ověřují v rámci důvěrného procesu. Klient aplikace používá k ověření tajný klíč klienta nebo klientský kontrolní výraz.

Veřejné klienty OpenID Connect/OAuth se už pro webové aplikace nedoporučují.

Výchozí tok funguje, jak je znázorněno v následujícím diagramu:

Důvěrný klient OIDC pro výměnu kódů s použitím PKCE

OpenID Connect se dodává v mnoha variantách a všechny implementace serveru mají mírně odlišné parametry a požadavky. Některé servery nepodporují koncový bod informací o uživateli, některé stále nepodporují PKCE a jiné vyžadují v požadavku na token speciální parametry. Klientská tvrzení lze použít místo tajemství klienta. Existují také nové standardy, které přidávají nad OpenID Connect Core další zabezpečení, například FAPI, CIBA nebo DPoP pro podřízená rozhraní API.

Poznámka:

V rozhraní .NET 9 se ve výchozím nastavení používají žádosti o autorizaci OAuth 2.0 (PAR) RFC 9126 , pokud to server OpenID Connect podporuje. Toto je třístupňový tok, nikoli dvoustupňový tok, jak je znázorněno výše. (Žádost o informace o uživateli je volitelný krok.)

Vytvořte klienta pro tok kódu Open ID Connect pomocí Razor Pages

Následující část ukazuje, jak implementovat klienta OpenID Connect v prázdném projektu stránky ASP.NET Core Razor . Stejnou logiku je možné použít u libovolného webového projektu ASP.NET Core pouze s rozdílnou integrací uživatelského rozhraní.

Přidání podpory OpenID Connect

Přidejte balíčky NuGet Microsoft.AspNetCore.Authentication.OpenIdConnect do projektu ASP.NET Core.

Nastavení klienta OpenID Connect

Přidejte ověřování do webové aplikace pomocí builder.Services v souboru Program.cs. Konfigurace závisí na serveru OpenID Connect. Každý server OpenID Connect vyžaduje v nastavení malé rozdíly.

Obslužná rutina OpenID Connect se používá pro výzvy a odhlášení. Slouží cookie ke zpracování relace ve webové aplikaci. Výchozí schémata pro ověřování je možné zadat podle potřeby.

Další informace najdete v pokynech pro ASP.NET Core authentication-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";
});

Podrobnosti o různých možnostech OpenID Connect najdete v části Jak zabezpečit ASP.NET Core pomocí OpenID Connect (OIDC) Blazor Web App.

Různé možnosti mapování deklarací najdete v tématu Mapování, přizpůsobení a transformace deklarací identity v ASP.NET Core.

Poznámka:

Jsou vyžadovány následující obory názvů:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;

Nastavení vlastností konfigurace

Přidejte nastavení klienta OpenID Connect do vlastností konfigurace aplikace. Nastavení musí odpovídat konfiguraci klienta na serveru OpenID Connect. V nastavení aplikace by se neměla ukládat žádná tajemství, kde by mohla být neúmyslně odeslána do verzovacího systému. Tajné kódy by měly být uložené v zabezpečeném umístění, jako je Azure Key Vault, v produkčních prostředích nebo v tajných klíčích uživatelů ve vývojovém prostředí. Další informace najdete v tématu Bezpečné ukládání tajných kódů aplikací při vývoji v 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--"
},

Konfigurace cesty pro zpětné volání po odhlášení

SignedOutCallbackPath (konfigurační klíč: "SignedOutCallbackPath") je cesta požadavku v rámci základní cesty aplikace zachycená obslužnou rutinou OpenID Connect, kde se agent uživatele poprvé vrátí po odhlášení od zprostředkovatele identity. Ukázková aplikace nenastaví pro cestu hodnotu, protože se použije výchozí hodnota/signout-callback-oidc. Po zachycení požadavku se obslužná rutina OpenID Connect v případě zadání přesměruje na SignedOutRedirectUri nebo RedirectUri.

Nakonfigurujte cestu pro zpětné volání po odhlášení v registraci poskytovatele OIDC aplikace. V následujícím příkladu je zástupný symbol {PORT} portem aplikace:

https://localhost:{PORT}/signout-callback-oidc

Poznámka:

Pokud používáte ID Microsoft Entra, nastavte cestu v záznamech identifikátoru URI přesměrování v konfiguraci platformy Web v portálu Entra nebo Azure. Při použití Entra se port nevyžaduje pro adresy localhost. Většina ostatních zprostředkovatelů OIDC vyžaduje správný port. Pokud do registrace aplikace v Entra nepřidáte URI cesty zpětného volání po odhlášení, Entra odmítne přesměrovat uživatele zpět do aplikace a pouze ho požádá, aby zavřel okno prohlížeče.

Aktualizujte metodu pipeline ASP.NET Core ve třídě programu.

Metoda UseRouting musí být implementována před metodou UseAuthorization.

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
// Authorization is applied for middleware after the UseAuthorization method
app.UseAuthorization();
app.MapRazorPages();

Vynucení autorizace

Přidejte atribut [Authorize] na chráněné stránky Razor.

[Authorize]

Lepším přístupem je vynutit autorizaci pro celou aplikaci a vyjádřit výslovný nesouhlas se nezabezpečenými stránkami:

var requireAuthPolicy = new AuthorizationPolicyBuilder()
    .RequireAuthenticatedUser()
    .Build();

builder.Services.AddAuthorizationBuilder()
    .SetFallbackPolicy(requireAuthPolicy);

Odhlaste se od autorizace u veřejných koncových bodů použitím [AllowAnonymous] atributu na veřejné koncové body. Příklady najdete v části Přidání nové Logout.cshtml a SignedOut.cshtmlRazor stránky do projektu a Implementace stránky Login.

Přidání nových Logout.cshtml a SignedOut.cshtmlRazor stránek do projektu

K odhlášení z relace cookie i relace OpenID Connect se vyžaduje odhlášení. Aby se odhlásil, musí se celá aplikace přesměrovat na server OpenID Connect. Po úspěšném odhlášení aplikace nasměruje na trasu RedirectUri.

Implementujte výchozí odhlašovací stránku a změňte kód Razor stránky Logout na následující kód:

[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 vyžaduje atribut [AllowAnonymous]:

[AllowAnonymous]
public class SignedOutModel : PageModel
{
    public void OnGet()
    {
    }
}

Implementujte stránku Login

Login Razor stránka může být také implementována pro přímé volání ChallengeAsync s požadovanými AuthProperties. To se nevyžaduje, pokud webová aplikace vyžaduje ověření a použije se výchozí výzva.

Stránka Login.cshtml vyžaduje atribut [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 };
    }
}

Přidání tlačítka pro přihlášení a odhlášení pro uživatele

@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>
}

Příklady s fragmenty kódu

Příklad použití koncového bodu informace o uživateli

Možnosti OpenID Connect lze použít k mapování deklarací identity, implementaci obslužných rutin nebo dokonce k uložení tokenů v relaci pro pozdější použití.

Možnost Scope lze použít k vyžádání různých deklarací identity nebo obnovovacího tokenu, který se odešle jako informace na server OpenID Connect. Žádost o offline_access žádá server o vrácení referenčního tokenu, který lze použít k aktualizaci relace bez opětovného ověření uživatele aplikace.

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";
});

Implementace zprostředkovatelů identity Microsoftu

Microsoft má několik zprostředkovatelů identity a implementací OpenID Connect. Microsoft má různé servery OpenID Connect:

  • Microsoft Entra ID
  • Microsoft Entra Externí ID
  • Azure AD B2C

Pokud se ověřuje pomocí některého z poskytovatelů identity Microsoftu v ASP.NET Core, doporučujeme použít balíčky NuGet Microsoft.Identity.Web.

Balíčky NuGet Microsoft.Identity.Web jsou specifického klienta Microsoftu postaveného na klientovi ASP.NET Core OpenID Connect s některými změnami výchozího klienta.

Použití klientů zprostředkovatele OpenID Connect třetích stran

Mnoho implementací serveru OpenID Connect vytváří balíčky NuGet optimalizované pro stejnou implementaci OpenID Connect. Tyto balíčky implementují specifika klienta OpenID Connect s dodatečnými informacemi vyžadovanými konkrétním serverem OpenID Connect. Microsoft.Identity.Web je jedním z příkladů.

Pokud v jedné aplikaci implementujte více klientů OpenID Connect z různých serverů OpenID Connect, je obvykle lepší vrátit se k výchozí implementaci ASP.NET Core, protože různí klienti přepíší některé možnosti, které ovlivňují ostatní klienty.

Weboví poskytovatelé OpenIddict jsou klientskou implementací, která podporuje mnoho různých implementací serveru.

IdentityModel je .NET standard pomocná knihovna pro identitu založenou na deklaracích, OAuth 2.0 a OpenID Connect. To se dá použít také k pomoci s implementací klienta.

Back-end pro architekturu zabezpečení front-endu (BFF)

Pro všechny webové aplikace se už nedoporučuje implementovat veřejné klienty OpenID Connect.

Další informace najdete v návrhu OAuth 2.0 pro Browser-Based aplikace.

Pokud implementujeme webové aplikace, které nemají žádný nezávislý back-end, doporučujeme použít architekturu zabezpečení podle vzoru Backend pro Frontend (BFF). Tento model je možné implementovat různými způsoby, ale ověřování se vždy implementuje v back-endu a do webového klienta se neposílají žádná citlivá data pro další autorizaci nebo toky ověřování.

Pokročilé funkce, standardy, rozšíření klienta OIDC

Protokolování

Ladění klientů OpenID Connect může být obtížné. Osobní údaje (PII) se ve výchozím nastavení nezaprotokolují. Při ladění ve vývojovém režimu je možné IdentityModelEventSource.ShowPII použít k protokolování citlivých osobních údajů. Nenasazujte aplikaci s IdentityModelEventSource.ShowPII na produktivní servery.

//using ...

using Microsoft.IdentityModel.Logging;

var builder = WebApplication.CreateBuilder(args);

//... code 

var app = builder.Build();

IdentityModelEventSource.ShowPII = true;

//... code 

app.Run();

Další informace naleznete v tématu Protokoly.

Poznámka:

Možná budete chtít snížit nakonfigurovanou úroveň protokolu, aby se zobrazily všechny požadované protokoly.

Přizpůsobení parametrů OIDC a OAuth

Možnost ověřovacích obslužných rutin OAuth a OIDC (AdditionalAuthorizationParameters) umožňuje přizpůsobení parametrů autorizační zprávy, které jsou zpravidla zahrnuty v řetězci dotazu při přesměrování.

Mapování deklarací identity z OpenID Connect

Další informace najdete v tématu Mapování, přizpůsobení a transformace nároků v ASP.NET Core.

Blazor OpenID Connect

Další informace najdete v tématu Zabezpečení Blazor Web App ASP.NET Core sOpenID Connect (OIDC).

Standardy