Sdílet prostřednictvím


Zabezpečení ASP.NET Core Blazor Web App pomocí Microsoft Entra ID

Tento článek popisuje, jak zabezpečit Blazor Web App pomocí Microsoft Identity Platform/webových balíčků Microsoft Identity pro MICROSOFT Entra ID pomocí ukázkové aplikace.

Probírá se následující specifikace:

  • Používá Blazor Web App režim automatického vykreslování s globální interaktivitou (InteractiveAuto).
  • Volání projektu AddAuthenticationStateSerialization serveru pro přidání zprostředkovatele stavu ověřování na straně serveru, který používá PersistentComponentState k toku stav ověřování do klienta. Klient volá AddAuthenticationStateDeserialization deserializaci a používá stav ověřování předaný serverem. Stav ověřování je opraven po celou dobu životnosti aplikace WebAssembly.
  • Aplikace používá ID Microsoft Entra založené na Identity balíčcích Microsoftu.
  • Automatická neinteraktivní aktualizace tokenů je spravovaná architekturou.
  • Aplikace používá abstrakce na straně serveru a služby na straně klienta k zobrazení vygenerovaných dat o počasí:
    • Při vykreslování Weather komponenty na serveru k zobrazení dat o počasí používá ServerWeatherForecaster komponenta na serveru k přímému získání dat o počasí (ne prostřednictvím volání webového rozhraní API).
    • Když se komponenta Weather vykreslí na klientovi, použije ClientWeatherForecaster implementaci služby, která používá předkonfigurované HttpClient (v souboru klientského Program projektu) k volání webového rozhraní API do minimálního rozhraní API serveru (/weather-forecast) pro data o počasí. Koncový bod minimálního rozhraní API získá data o počasí z ServerWeatherForecaster třídy a vrátí je klientovi pro vykreslení komponentou.

Ukázková aplikace

Ukázková aplikace se skládá ze dvou projektů:

  • BlazorWebAppEntra: Projekt Blazor Web Appna straně serveru , který obsahuje příklad minimálního koncového bodu rozhraní API pro data o počasí.
  • BlazorWebAppEntra.Client: Projekt na straně klienta .Blazor Web App

Přístup k ukázkovým aplikacím prostřednictvím složky nejnovější verze z kořenového adresáře úložiště pomocí následujícího odkazu. Projekty jsou ve BlazorWebAppEntra složce pro .NET 9 nebo novější.

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

Projekt na straně Blazor Web App serveru (BlazorWebAppEntra)

Projekt BlazorWebAppEntra je projekt Blazor Web Appna straně serveru .

Soubor BlazorWebAppEntra.http lze použít k testování žádosti o data o počasí. Mějte na paměti, že projekt BlazorWebAppEntra musí být spuštěn pro otestování koncového bodu a koncový bod je pevně zakódovaný do souboru. Další informace naleznete v tématu Použití souborů .http v sadě Visual Studio 2022.

Projekt na straně Blazor Web App klienta (BlazorWebAppEntra.Client)

Projekt BlazorWebAppEntra.Client je projekt Blazor Web Appna straně klienta .

Pokud se uživatel musí při vykreslování na straně klienta přihlásit nebo odhlásit, zahájí se opětovné načtení celé stránky.

Konfigurace

Tato část vysvětluje, jak nakonfigurovat ukázkovou aplikaci.

AddMicrosoftIdentityWebAppz Identity (Microsoft.Identity.Webbalíček NuGet, dokumentace k rozhraní API) je nakonfigurována v AzureAd části souboru projektu appsettings.json serveru.

V registraci aplikace na webu Entra nebo Azure Portal použijte konfiguraci webové platformy s identifikátorem URIhttps://localhost/signin-oidc přesměrování (port se nevyžaduje). Ověřte, že nejsou vybrány tokeny ID a přístupové tokeny v rámci implicitního udělení a hybridních toků. Obslužná rutina OpenID Connect automaticky požaduje příslušné tokeny pomocí kódu vráceného z autorizačního koncového bodu.

Konfigurace aplikace

V souboru nastavení aplikace serveru (appsettings.json) zadejte konfiguraci oddílu AzureAd aplikace. Získejte ID aplikace (klienta), doménu tenanta (vydavatele) a ID adresáře (tenanta) z registrace aplikace na webu Entra nebo Azure Portal:

"AzureAd": {
  "CallbackPath": "/signin-oidc",
  "ClientId": "{CLIENT ID}",
  "Domain": "{DOMAIN}",
  "Instance": "https://login.microsoftonline.com/",
  "ResponseType": "code",
  "TenantId": "{TENANT ID}"
},

Zástupné symboly v předchozím příkladu:

  • {CLIENT ID}: ID aplikace (klienta).
  • {DOMAIN}: Doména tenanta (vydavatele).
  • {TENANT ID}: ID adresáře (tenanta).

Příklad:

"AzureAd": {
  "CallbackPath": "/signin-oidc",
  "ClientId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "Domain": "contoso.onmicrosoft.com",
  "Instance": "https://login.microsoftonline.com/",
  "ResponseType": "code",
  "TenantId": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
},

Cesta zpětného volání (CallbackPath) se musí shodovat s identifikátorem URI přesměrování (cesta zpětného volání přihlášení) nakonfigurovanou při registraci aplikace na webu Entra nebo Azure Portal. Cesty se konfigurují v okně Ověřování registrace aplikace. Výchozí hodnota CallbackPath je /signin-oidc pro zaregistrovaný identifikátor URI https://localhost/signin-oidc přesměrování (port se nevyžaduje).

SignedOutCallbackPath (konfigurační klíč: "SignedOutCallbackPath") je cesta požadavku v základní cestě aplikace zachycená obslužnou rutinou OpenID Connect, kde se uživatelský agent poprvé vrátí po odhlášení z Entra. 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 zpětného volání po odhlášení v registraci aplikace Entra. Na webu Entra nebo Azure Portal nastavte cestu v konfiguraci platformy web identifikátor URI přesměrování položky:

https://localhost/signout-callback-oidc

Poznámka:

Port se při použití Entra nevyžaduje pro localhost adresy.

Pokud do registrace aplikace v Entra nepřidáte URI cesty pro zpětné volání po odhlášení, Entra uživatele zpět do aplikace nepřesměruje a místo toho ho požádá, aby zavřel okno prohlížeče.

Poznámka:

Entra nepřesměruje uživatele primárního správce (kořenový účet) ani externího uživatele zpět do Blazor aplikace. Místo toho Entra odhlásí uživatele z aplikace a doporučí, aby zavřel všechna okna prohlížeče. Další informace najdete v tématu postLogoutRedirectUri nefunguje, pokud adresa URL autority obsahuje ID tenanta (AzureAD/microsoft-authentication-library-for-js #5783).

Upozorňující

Neukládejte tajné kódy aplikací, připojovací řetězec, přihlašovací údaje, hesla, osobní identifikační čísla (PIN), privátní kód C#/.NET nebo privátní klíče/tokeny v kódu na straně klienta, což je vždy nezabezpečené. V testovacích a pracovních a produkčních prostředích by kód na straně Blazor serveru a webová rozhraní API měly používat toky zabezpečeného ověřování, které se vyhýbají údržbě přihlašovacích údajů v kódu projektu nebo konfiguračních souborech. Mimo místní testování vývoje doporučujeme vyhnout se použití proměnných prostředí k ukládání citlivých dat, protože proměnné prostředí nejsou nejbezpečnějším přístupem. Pro místní testování vývoje se pro zabezpečení citlivých dat doporučuje nástroj Secret Manager. Další informace najdete v tématu Bezpečné udržování citlivých dat a přihlašovacích údajů.

Vytvoření tajného klíče klienta

Vytvořte tajný klíč klienta v registraci ID Entra aplikace na webu Entra nebo Azure Portal (>Nový tajný klíč klienta). Hodnotu nového tajného kódu použijte v následujících doprovodných materiálech.

K poskytnutí tajného klíče klienta do aplikace použijte jeden nebo oba následující přístupy:

  • Nástroj Secret Manager: Nástroj Secret Manager ukládá soukromá data na místním počítači a používá se pouze při místním vývoji.
  • Azure Key Vault: Tajný klíč klienta můžete uložit do trezoru klíčů pro použití v libovolném prostředí, včetně vývojového prostředí při práci místně. Někteří vývojáři raději používají trezory klíčů pro přípravné a produkční nasazení a používají nástroj Secret Manager pro místní vývoj.

Důrazně doporučujeme vyhnout se ukládání tajných kódů klienta do kódu projektu nebo konfiguračních souborů. Používejte zabezpečené ověřovací toky, jako jsou oba přístupy v této části.

Nástroj Secret Manager

Nástroj Secret Manager může uložit tajný klíč klienta serverové aplikace pod konfigurační klíč AzureAd:ClientSecret.

Ukázková aplikace nebyla inicializována pro nástroj Secret Manager. K provedení následujícího příkazu použijte příkazové prostředí, například příkazové prostředí Developer PowerShell v sadě Visual Studio. Před provedením příkazu změňte adresář příkazem cd na adresář projektu serveru. Příkaz vytvoří identifikátor tajných kódů uživatele (<UserSecretsId>) v souboru projektu serverové aplikace, který je interně používán nástroji ke sledování tajných kódů pro aplikaci:

dotnet user-secrets init

Spuštěním následujícího příkazu nastavte tajný klíč klienta. Zástupný {SECRET} symbol je tajný klíč klienta získaný z registrace Entra aplikace:

dotnet user-secrets set "AzureAd:ClientSecret" "{SECRET}"

Pokud používáte Visual Studio, můžete ověřit, že je tajný kód nastavený tak, že v Průzkumník řešení kliknete pravým tlačítkem na projekt serveru a vyberete Spravovat tajné kódy uživatelů.

Azure Key Vault

Azure Key Vault poskytuje bezpečný přístup pro poskytnutí tajného klíče klienta aplikace pro aplikaci.

Pokud chcete vytvořit trezor klíčů a nastavit tajný klíč klienta, přečtěte si informace o tajných klíčích služby Azure Key Vault (dokumentace k Azure), které křížově propojí prostředky, které vám pomůžou začít se službou Azure Key Vault. Pokud chcete implementovat kód v této části, poznamenejte si identifikátor URI trezoru klíčů a název tajného kódu z Azure při vytváření trezoru klíčů a tajného klíče. Když nastavíte zásady přístupu pro tajný kód na panelu Zásad přístupu:

  • Vyžaduje se pouze oprávnění Získat tajný kód.
  • Jako objekt zabezpečení pro tajný klíč vyberte aplikaci.

Důležité

Vytvoří se tajný klíč trezoru klíčů s datem vypršení platnosti. Nezapomeňte sledovat, kdy vyprší platnost tajného klíče trezoru klíčů, a před předáním tohoto data vytvořte pro aplikaci nový tajný klíč.

Do projektu serveru přidejte následující třídu AzureHelper. Metoda GetKeyVaultSecret načte tajný kód z trezoru klíčů. Upravte obor názvů (BlazorSample.Helpers) tak, aby odpovídal schématu oboru názvů projektu.

Helpers/AzureHelper.cs:

using Azure;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;

namespace BlazorSample.Helpers;

public static class AzureHelper
{
    public static string GetKeyVaultSecret(string tenantId, string vaultUri, string secretName)
    {
        DefaultAzureCredentialOptions options = new()
        {
            // Specify the tenant ID to use the dev credentials when running the app locally
            // in Visual Studio.
            VisualStudioTenantId = tenantId,
            SharedTokenCacheTenantId = tenantId
        };

        var client = new SecretClient(new Uri(vaultUri), new DefaultAzureCredential(options));
        var secret = client.GetSecretAsync(secretName).Result;

        return secret.Value.Value;
    }
}

Pokud jsou služby zaregistrované v souboru projektu Program serveru, získejte a použijte tajný kód klienta pomocí následujícího kódu:

var tenantId = builder.Configuration.GetValue<string>("AzureAd:TenantId")!;
var vaultUri = builder.Configuration.GetValue<string>("AzureAd:VaultUri")!;
var secretName = builder.Configuration.GetValue<string>("AzureAd:SecretName")!;

builder.Services.Configure<MicrosoftIdentityOptions>(
    OpenIdConnectDefaults.AuthenticationScheme,
    options =>
    {
        options.ClientSecret = 
            AzureHelper.GetKeyVaultSecret(tenantId, vaultUri, secretName);
    });

Pokud chcete řídit prostředí, ve kterém funguje předchozí kód, například abyste se vyhnuli místnímu spuštění kódu, protože jste se rozhodli použít nástroj Secret Manager pro místní vývoj, můžete předchozí kód zabalit do podmíněného příkazu, který kontroluje prostředí:

if (!context.HostingEnvironment.IsDevelopment())
{
    ...
}

AzureAd V části appsettings.jsonpřidejte následující VaultUri a SecretName konfigurační klíče a hodnoty:

"VaultUri": "{VAULT URI}",
"SecretName": "{SECRET NAME}"

V předchozím příkladu:

  • Zástupný {VAULT URI} symbol je identifikátor URI trezoru klíčů. Zahrňte koncové lomítko na identifikátoru URI.
  • Zástupný {SECRET NAME} symbol je název tajného kódu.

Příklad:

"VaultUri": "https://contoso.vault.azure.net/",
"SecretName": "BlazorWebAppEntra"

Konfigurace se používá k usnadnění poskytování vyhrazených trezorů klíčů a názvů tajných kódů na základě konfiguračních souborů prostředí aplikace. Můžete například zadat různé hodnoty konfigurace pro appsettings.Development.json vývoj, appsettings.Staging.json při přípravě a appsettings.Production.json pro produkční nasazení. Další informace najdete v tématu Blazor jádra.

Přesměrování na domovskou stránku při odhlášení

Komponenta LogInOrOut (Layout/LogInOrOut.razor) nastaví skryté pole pro zpáteční adresu URL (ReturnUrl) na aktuální adresu URL (currentURL). Když se uživatel z aplikace odhlásí, zprostředkovatel identity vrátí uživatele na stránku, ze které se odhlásil. Pokud se uživatel odhlásí ze zabezpečené stránky, vrátí se na stejnou zabezpečenou stránku a odešle se zpět prostřednictvím procesu ověřování. Tento tok ověřování je přiměřený, když uživatelé potřebují pravidelně měnit účty.

Případně použijte následující LogInOrOut komponentu, která při odhlášení nezadává zpáteční adresu URL.

Layout/LogInOrOut.razor:

<div class="nav-item px-3">
    <AuthorizeView>
        <Authorized>
            <form action="authentication/logout" method="post">
                <AntiforgeryToken />
                <button type="submit" class="nav-link">
                    <span class="bi bi-arrow-bar-left-nav-menu" aria-hidden="true">
                    </span> Logout @context.User.Identity?.Name
                </button>
            </form>
        </Authorized>
        <NotAuthorized>
            <a class="nav-link" href="authentication/login">
                <span class="bi bi-person-badge-nav-menu" aria-hidden="true"></span> 
                Login
            </a>
        </NotAuthorized>
    </AuthorizeView>
</div>

Odstraňování potíží

Protokolování

Serverová aplikace je standardní aplikace ASP.NET Core. Informace o povolení nižší úrovně protokolování v serverové aplikaci najdete v pokynech k protokolování ASP.NET Core.

Pokud chcete povolit protokolování ladění nebo trasování pro Blazor WebAssembly ověřování, přečtěte si Core Blazor pomocí selektoru verze článku nastaveného na ASP.NET Core 7.0 nebo novější.

Běžné chyby

  • Chybná konfigurace aplikace nebo Identity poskytovatele (IP)

    Nejčastější chyby jsou způsobené nesprávnou konfigurací. Tady je několik příkladů:

    • V závislosti na požadavcích scénáře brání chybějící nebo nesprávné autoritě, instanci, ID tenanta, doméně tenanta, ID klienta nebo identifikátoru URI přesměrování, aby aplikace ověřoval klienty.
    • Nesprávné obory požadavků brání klientům v přístupu ke koncovým bodům webového rozhraní API serveru.
    • Nesprávná nebo chybějící oprávnění rozhraní API serveru brání klientům v přístupu ke koncovým bodům webového rozhraní API serveru.
    • Spuštění aplikace na jiném portu, než je nakonfigurované v identifikátoru URI přesměrování registrace aplikace IP adresy. Všimněte si, že port není nutný pro MICROSOFT Entra ID a aplikaci spuštěnou localhost na adrese pro testování vývoje, ale konfigurace portu aplikace a port, na kterém je aplikace spuštěná, se musí shodovat s neadresoulocalhost .

    Pokrytí konfigurace v tomto článku ukazuje příklady správné konfigurace. Pečlivě zkontrolujte konfiguraci, která hledá aplikaci a nesprávnou konfiguraci IP adres.

    Pokud se konfigurace zobrazí správně:

    • Analyzujte protokoly aplikace.

    • Prozkoumejte síťový provoz mezi klientskou aplikací a IP nebo serverovou aplikací pomocí vývojářských nástrojů prohlížeče. Často je přesná chybová zpráva nebo zpráva s povědomím o příčině problému vrácena klientovi ip adresou nebo serverovou aplikací po provedení požadavku. Vývojářské nástroje pokyny najdete v následujících článcích:

    Tým dokumentace reaguje na zpětnou vazbu a chyby v článcích (otevřete problém z oddílu Pro zpětnou vazbu na této stránce ), ale nemůže poskytnout podporu k produktům. K dispozici je několik veřejných fór podpory, která vám pomůžou s řešením potíží s aplikací. Doporučujeme následující:

    Předchozí fóra nejsou vlastněna ani řízena Společností Microsoft.

    V případě zpráv o chybách rozhraní bez zabezpečení, nerozlišujících a nedůvěryhodných reprodukovatelných chyb otevřete problém s produktovou jednotkou ASP.NET Core. Neotevírejte problém s produktovou jednotkou, dokud důkladně neprošetříte příčinu problému a nemůžete ho vyřešit sami a s pomocí komunity na veřejném fóru podpory. Produktová jednotka nedokáže řešit potíže s jednotlivými aplikacemi, které jsou poškozené kvůli jednoduché chybné konfiguraci nebo případům použití zahrnujícím služby třetích stran. Pokud je sestava citlivá nebo důvěrná v povaze nebo popisuje potenciální chybu zabezpečení v produktu, který může cyberattackers zneužít, přečtěte si téma Hlášení problémů se zabezpečením a chyb (dotnet/aspnetcore úložiště GitHub).

  • Neautorizovaný klient pro ME-ID

    info: Autorizace Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] selhala. Tyto požadavky nebyly splněny: DenyAnonymousAuthorizationRequirement: Vyžaduje ověřeného uživatele.

    Chyba zpětného volání přihlášení z ME-ID:

    • Chyba: unauthorized_client
    • Popis: AADB2C90058: The provided application is not configured to allow public clients.

    Řešení chyby:

    1. Na webu Azure Portal přejděte k manifestu aplikace.
    2. allowPublicClient Nastavte atribut na null nebo true.

Soubory cookie a data webu

Soubory cookie a data webu se můžou uchovávat v aktualizacích aplikací a kolidovat s testováním a odstraňováním potíží. Při provádění změn kódu aplikace, změn uživatelského účtu u poskytovatele nebo změn konfigurace aplikace poskytovatele zrušte následující:

  • Soubory cookie přihlašování uživatelů
  • Soubory cookie aplikace
  • Uložená a uložená data lokality v mezipaměti

Jedním z přístupů k tomu, aby se zabránilo zasahování souborů cookie a dat webu do testování a řešení potíží, je:

  • Konfigurace prohlížeče
    • K testování můžete použít prohlížeč, který můžete nakonfigurovat tak, aby při každém zavření prohlížeče odstranil všechna cookie data a data webu.
    • Ujistěte se, že je prohlížeč zavřený ručně nebo integrované vývojové prostředí (IDE) pro všechny změny aplikace, testovacího uživatele nebo konfigurace poskytovatele.
  • Pomocí vlastního příkazu otevřete prohlížeč v režimu InPrivate nebo Incognito v sadě Visual Studio:
    • V dialogovém okně Spustit v sadě Visual Studio otevřete dialogové okno Procházet.
    • Vyberte tlačítko Přidat.
    • Do pole Program zadejte cestu k prohlížeči. Následující spustitelné cesty jsou typická umístění instalace pro Windows 10. Pokud je váš prohlížeč nainstalovaný v jiném umístění nebo nepoužíváte Windows 10, zadejte cestu ke spustitelnému souboru prohlížeče.
      • Microsoft Edge: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
      • Google Chrome: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
      • Mozilla Firefox: C:\Program Files\Mozilla Firefox\firefox.exe
    • V poli Argumenty zadejte možnost příkazového řádku, kterou prohlížeč používá k otevření v režimu InPrivate nebo Anonymní režim. Některé prohlížeče vyžadují adresu URL aplikace.
      • Microsoft Edge: Použijte -inprivate.
      • Google Chrome: Použijte --incognito --new-window {URL}, kde {URL} zástupný symbol je adresa URL k otevření (například https://localhost:5001).
      • Mozilla Firefox: Použijte -private -url {URL}, kde {URL} zástupný symbol je adresa URL k otevření (například https://localhost:5001).
    • Do pole Popisný název zadejte název. Například Firefox Auth Testing.
    • Vyberte tlačítko OK.
    • Pokud se chcete vyhnout výběru profilu prohlížeče pro každou iteraci testování pomocí aplikace, nastavte profil jako výchozí tlačítkem Nastavit jako výchozí .
    • Ujistěte se, že integrované vývojové prostředí (IDE) zavřel prohlížeč pro všechny změny aplikace, testovacího uživatele nebo konfigurace poskytovatele.

Upgrady aplikací

Funkční aplikace může selhat okamžitě po upgradu sady .NET Core SDK na vývojovém počítači nebo změně verzí balíčků v aplikaci. V některých případech můžou inkoherentní balíčky přerušit aplikaci při provádění hlavních upgradů. Většinu těchto problémů je možné vyřešit pomocí těchto pokynů:

  1. Vymažte mezipaměti balíčků NuGet místního systému spuštěním dotnet nuget locals all --clear z příkazového prostředí.
  2. Odstraňte složky a bin složky projektuobj.
  3. Obnovte a znovu sestavte projekt.
  4. Před opětovným nasazením aplikace odstraňte všechny soubory ve složce nasazení na serveru.

Poznámka:

Použití verzí balíčků nekompatibilních s cílovou architekturou aplikace se nepodporuje. Informace o balíčku potřebujete pomocí galerie NuGet nebo Průzkumníka balíčků FuGet.

Spuštění serverové aplikace

Při testování a řešení potíží Blazor Web Appse ujistěte, že aplikaci spouštíte ze serverového projektu.

Kontrola uživatele

Následující UserClaims komponentu lze použít přímo v aplikacích nebo sloužit jako základ pro další přizpůsobení.

UserClaims.razor:

@page "/user-claims"
@using System.Security.Claims
@using Microsoft.AspNetCore.Authorization
@attribute [Authorize]

<PageTitle>User Claims</PageTitle>

<h1>User Claims</h1>

@if (claims.Any())
{
    <ul>
        @foreach (var claim in claims)
        {
            <li><b>@claim.Type:</b> @claim.Value</li>
        }
    </ul>
}

@code {
    private IEnumerable<Claim> claims = Enumerable.Empty<Claim>();

    [CascadingParameter]
    private Task<AuthenticationState>? AuthState { get; set; }

    protected override async Task OnInitializedAsync()
    {
        if (AuthState == null)
        {
            return;
        }

        var authState = await AuthState;
        claims = authState.User.Claims;
    }
}

Další materiály