Skydda en ASP.NET Core Blazor Web App med Microsoft Entra ID
I den här artikeln beskrivs hur du skyddar en Blazor Web App med Microsofts identitetsplattform/Microsoft Identity-webbpaket för Microsoft Entra-ID med hjälp av en exempelapp.
Följande specifikation omfattas:
-
Blazor Web App använder automatiskt återgivningsläge med global interaktivitet (
InteractiveAuto
). - Serverprojektet anropar AddAuthenticationStateSerialization för att lägga till en leverantör av autentiseringstillstånd på serversidan som använder sig av PersistentComponentState för att strömma autentiseringstillståndet till klienten. Klienten anropar AddAuthenticationStateDeserialization för att deserialisera och använda autentiseringstillståndet som skickas av servern. Autentiseringstillståndet förblir konstant under hela livslängden för WebAssembly-applikationen.
- Appen använder Microsoft Entra-ID, baserat på Microsoft Identity Web-paket.
- Automatisk uppdatering av icke-interaktiva token hanteras av ramverket.
- Appen använder abstraktioner på serversidan och klientsidan för att visa genererade väderdata:
- När komponenten
Weather
återges på servern för att visa väderdata, använder den komponentenServerWeatherForecaster
på servern för att direkt hämta väderdata (inte genom ett anrop via webb-API). - När komponenten
Weather
renderas på klienten använder komponenten implementeringen avClientWeatherForecaster
-tjänsten, som använder en förkonfigurerad HttpClient (i klientprojektetsProgram
-fil) för att göra ett anrop till serverprojektets minimala API (/weather-forecast
) för att hämta väderdata. Den minimala API-slutpunkten hämtar väderdata från klassenServerWeatherForecaster
och returnerar dem till klienten för återgivning av komponenten.
- När komponenten
Exempelapp
Exempelappen består av två projekt:
-
BlazorWebAppEntra
: Projekt på serversidan för Blazor Web App, som innehåller ett exempel på en Minimal API--endpoint för väderinformation. -
BlazorWebAppEntra.Client
: Projektet på klientsidan för Blazor Web App.
Få åtkomst till exempelappar via den senaste versionsmappen från lagringsplatsens rot med följande länk. Projekten finns i mappen BlazorWebAppEntra
för .NET 9 eller senare.
Visa eller ladda ned exempelkod (hur du laddar ned)
Blazor Web App projekt på serversidan (BlazorWebAppEntra
)
BlazorWebAppEntra
-projektet är projektet på serversidan för Blazor Web App.
Den BlazorWebAppEntra.http
filen kan användas för att testa väderdatabegäran. Observera att BlazorWebAppEntra
projektet måste köras för att testa slutpunkten och att slutpunkten är hårdkodad i filen. Mer information finns i Använda .http-filer i Visual Studio 2022.
Projekt på klientsidan Blazor Web App (BlazorWebAppEntra.Client
)
Det BlazorWebAppEntra.Client
projektet är projektet på klientsidan för Blazor Web App.
Om användaren behöver logga in eller ut vid rendering på klientsidan initieras en fullständig sidinläsning.
Konfiguration
I det här avsnittet beskrivs hur du konfigurerar exempelappen.
AddMicrosoftIdentityWebApp från Microsoft Identity Web (Microsoft.Identity.Web
NuGet-paket, API-dokumentation) konfigureras av AzureAd
-avsnittet i serverprojektets appsettings.json
-fil.
I registreringen av appen i Entra- eller Azure-portalen använder du en Web-plattformskonfiguration med en omdirigerings-URI på https://localhost/signin-oidc
(utan att en port krävs). Bekräfta att ID-token och åtkomsttoken under Implicit beviljande och hybridflöden inte är valda. OpenID Connect-hanteraren begär automatiskt lämpliga token med hjälp av koden som returneras från auktoriseringsslutpunkten.
Konfigurera appen
I serverprojektets appinställningsfil (appsettings.json
) anger du appens AzureAd
avsnittskonfiguration. Hämta program-ID:t (klient-), klientdomänen (utgivaren) och katalog-ID:t (klient) från appens registrering i Entra- eller Azure-portalen:
"AzureAd": {
"CallbackPath": "/signin-oidc",
"ClientId": "{CLIENT ID}",
"Domain": "{DOMAIN}",
"Instance": "https://login.microsoftonline.com/",
"ResponseType": "code",
"TenantId": "{TENANT ID}"
},
Platshållare i föregående exempel:
-
{CLIENT ID}
: Programmets (klient)-ID. -
{DOMAIN}
: Hyresgästdomän (utgivaren). -
{TENANT ID}
: Katalog-ID (hyresgäst).
Exempel:
"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"
},
Återanropssökvägen (CallbackPath
) måste matcha den omdirigerings-URI (sökväg för återanrop för inloggning) som konfigurerades vid registreringen av programmet i Entra- eller Azure-portalen. Sökvägar konfigureras på bladet autentisering i appens registrering. Standardvärdet för CallbackPath
är /signin-oidc
för en registrerad omdirigerings-URI för https://localhost/signin-oidc
(en port krävs inte).
SignedOutCallbackPath (konfigurationsnyckel: "SignedOutCallbackPath
") är sökvägen för begäran i appens bassökväg som fångas upp av OpenID Connect-hanteraren där användaragenten först returneras efter utloggning från Entra. Exempelappen anger inte något värde för sökvägen eftersom standardvärdet "/signout-callback-oidc
" används. Efter att ha avlyssnat begäran omdirigerar OpenID Connect-hanteraren till SignedOutRedirectUri eller RedirectUri, om det är angivet.
Konfigurera den utloggade motringningssökvägen i appens Entra-registrering. I Entra- eller Azure-portalen anger du sökvägen i Web-plattformskonfigurationens omdirigerings-URI poster:
https://localhost/signout-callback-oidc
Obs
En port krävs inte för localhost
adresser när du använder Entra.
Om du inte lägger till URI:n för den utloggade motringningssökvägen i appens registrering i Entra vägrar Entra att omdirigera användaren tillbaka till appen och ber dem bara att stänga webbläsarfönstret.
Not
Entra omdirigerar inte en primär administratörsanvändare (rotkonto) eller extern användare tillbaka till Blazor-programmet. I stället loggar Entra ut användaren från appen och rekommenderar att de stänger alla webbläsarfönster. Mer information finns i postLogoutRedirectUri fungerar inte när utfärdar-URL:en innehåller ett klient-ID (AzureAD/microsoft-authentication-library-for-js
#5783).
Varning
Lagra inte apphemligheter, anslutningssträngar, autentiseringsuppgifter, lösenord, personliga identifieringsnummer (PIN),privat C#/.NET-kod eller privata nycklar/token i kod på klientsidan, vilket är alltid osäker. I test-/mellanlagrings- och produktionsmiljöer bör Blazor kod på serversidan och webb-API:er använda säkra autentiseringsflöden som undviker att underhålla autentiseringsuppgifter i projektkod eller konfigurationsfiler. Förutom testning av lokal utveckling rekommenderar vi att du undviker användning av miljövariabler för att lagra känsliga data, eftersom miljövariabler inte är den säkraste metoden. För testning av lokal utveckling rekommenderas verktyget Secret Manager för att skydda känsliga data. Mer information finns i På ett säkert sätt underhålla känsliga data och autentiseringsuppgifter.
Upprätta klienthemligheten
Skapa en klienthemlighet i appens Entra-ID-registrering i Entra- eller Azure-portalen (Hantera>-certifikat & hemligheter>Ny klienthemlighet). Använd värde för den nya hemligheten i följande vägledning.
Använd någon av eller båda av följande metoder för att tillhandahålla klienthemligheten till appen:
- Secret Manager-verktyget: Secret Manager-verktyget lagrar privata data på den lokala datorn och används endast under lokal utveckling.
- Azure Key Vault-: Du kan lagra klienthemligheten i ett nyckelvalv för användning i alla miljöer, inklusive för utvecklingsmiljön när du arbetar lokalt. Vissa utvecklare föredrar att använda nyckelvalv för mellanlagrings- och produktionsdistributioner och använder verktyget Secret Manager för lokal utveckling.
Vi rekommenderar starkt att du undviker att lagra klienthemligheter i projektkod eller konfigurationsfiler. Använd säkra autentiseringsflöden, till exempel någon av eller båda metoderna i det här avsnittet.
Secret Manager-verktyget
Verktyget Secret Manager kan lagra serverappens klienthemlighet under konfigurationsnyckeln AzureAd:ClientSecret
.
Exempelappen har inte initierats för Secret Manager-verktyget. Använd ett kommandogränssnitt, till exempel PowerShell-kommandogränssnittet Developer i Visual Studio, för att köra följande kommando. Innan du kör kommandot ändrar du katalogen med kommandot cd
till serverprojektets katalog. Kommandot upprättar en identifierare för användarhemligheter (<UserSecretsId>
) i serverappens projektfil, som används internt av verktyget för att spåra hemligheter för appen:
dotnet user-secrets init
Kör följande kommando för att ange klienthemligheten. Platshållaren {SECRET}
är klienthemligheten som hämtas från appens Entra-registrering:
dotnet user-secrets set "AzureAd:ClientSecret" "{SECRET}"
Om du använder Visual Studio kan du bekräfta att hemligheten har angetts genom att högerklicka på serverprojektet i Solution Explorer och välja Hantera användarhemligheter.
Azure Key Vault
Azure Key Vault- är en säker metod för att tillhandahålla appens klienthemlighet till appen.
Information om hur du skapar ett nyckelvalv och anger en klienthemlighet finns i Om Azure Key Vault-hemligheter (Azure-dokumentation), som korslänkar resurser för att komma igång med Azure Key Vault. Om du vill implementera koden i det här avsnittet registrerar du nyckelvalvets URI och det hemliga namnet från Azure när du skapar nyckelvalvet och hemligheten. När du anger åtkomstprincipen för hemligheten i Åtkomstprinciper panelen:
- Endast behörigheten att hämta -hemligheten krävs för.
- Välj programmet som Principal för hemligheten.
Viktig
En nyckelvalvshemlighet skapas med ett förfallodatum. Se till att spåra när en nyckelvalvshemlighet upphör att gälla och skapa en ny hemlighet för appen innan det datumet passerar.
Lägg till följande AzureHelper
-klass i serverprojektet. Metoden GetKeyVaultSecret
hämtar en hemlighet från ett nyckelvalv. Justera namnområdet (BlazorSample.Helpers
) så att det matchar projektets namnområdesschema.
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;
}
}
Om tjänster registreras i serverprojektets Program
-fil hämtar och tillämpar du klienthemligheten med hjälp av följande kod:
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);
});
Om du vill styra miljön där föregående kod fungerar, till exempel för att undvika att köra koden lokalt eftersom du har valt att använda verktyget Secret Manager för lokal utveckling, kan du omsluta koden i en villkorsstyrd instruktion som kontrollerar miljön:
if (!context.HostingEnvironment.IsDevelopment())
{
...
}
I avsnittet AzureAd
i appsettings.json
lägger du till följande VaultUri
och SecretName
konfigurationsnycklar och -värden:
"VaultUri": "{VAULT URI}",
"SecretName": "{SECRET NAME}"
I föregående exempel:
- Platshållaren
{VAULT URI}
är nyckelvalvets URI. Inkludera det avslutande snedstrecket på URI:n. - Platshållaren
{SECRET NAME}
är det hemliga namnet.
Exempel:
"VaultUri": "https://contoso.vault.azure.net/",
"SecretName": "BlazorWebAppEntra"
Konfigurationen används för att underlätta tillhandahållandet av dedikerade nyckelvalv och hemliga namn baserat på appens miljökonfigurationsfiler. Du kan till exempel ange olika konfigurationsvärden för appsettings.Development.json
under utveckling, appsettings.Staging.json
vid mellanlagring och appsettings.Production.json
för produktionsdistributionen. Mer information finns i ASP.NET Core Blazor configuration.
Omdirigera till startsidan vid utloggning
Komponenten LogInOrOut
(Layout/LogInOrOut.razor
) anger ett dolt fält för retur-URL:en (ReturnUrl
) till den aktuella URL:en (currentURL
). När användaren loggar ut från appen returnerar identitetsprovidern användaren till sidan som de loggade ut från. Om användaren loggar ut från en säker sida returneras de till samma säkra sida och skickas tillbaka via autentiseringsprocessen. Det här autentiseringsflödet är rimligt när användarna behöver ändra konton regelbundet.
Du kan också använda följande LogInOrOut
komponent, som inte anger någon retur-URL när du loggar ut.
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>
Felsöka
Skogsavverkning
Serverappen är en standardapp för ASP.NET Core. Se vägledningen för ASP.NET Core-loggning för att aktivera en lägre loggningsnivå i serverappen.
Information om hur du aktiverar felsökning eller spårningsloggning för Blazor WebAssembly autentisering finns i avsnittet autentiseringsloggning på klientsidan i ASP.NET Core Blazor loggning med artikelversionsväljaren inställd på ASP.NET Core 7.0 eller senare.
Vanliga fel
Felkonfiguration av appen eller Identity IP-leverantör
De vanligaste felen orsakas av felaktig konfiguration. Följande är några exempel:
- Beroende på kraven i scenariot förhindrar en saknad eller felaktig utfärdare, instans, klient-ID, klientdomän, klient-ID eller omdirigerings-URI en app från att autentisera klienter.
- Felaktiga omfång för begäran hindrar klienter från att komma åt serverwebb-API-slutpunkter.
- Felaktiga eller saknade server-API-behörigheter hindrar klienter från att komma åt serverwebb-API-slutpunkter.
- Köra appen på en annan port än vad som har konfigurerats i omdirigerings-URI:n för IP-adressens appregistrering. Observera att en port inte krävs för Microsoft Entra-ID och en app som körs på en
localhost
utvecklingstestningsadress, men appens portkonfiguration och porten där appen körs måste matcha för icke-localhost
adresser.
Konfigurationstäckning i den här artikeln visar exempel på rätt konfiguration. Kontrollera noggrant konfigurationen för att leta efter fel i appar och IP-adresser.
Om konfigurationen verkar vara korrekt:
Analysera applikationsloggar.
Granska nätverkstrafiken mellan klientappen och IP- eller serverappen med webbläsarens utvecklarverktyg. Ofta returneras ett exakt felmeddelande eller ett meddelande med en ledtråd till vad som orsakar problemet till klienten av IP- eller serverappen efter en begäran. Vägledning för utvecklarverktyg finns i följande artiklar:
- Google Chrome (Google-dokumentation)
- Microsoft Edge
- Mozilla Firefox (Mozilla-dokumentation)
Dokumentationsteamet svarar på dokumentationsfeedback och buggar i artiklar. Starta ett ärende från Den här sidan feedbacksektionen, men de kan inte tillhandahålla produktsupport. Det finns flera offentliga supportforum som hjälper dig att felsöka en app. Vi rekommenderar följande:
Föregående forum ägs eller kontrolleras inte av Microsoft.
För rapporter om icke-säkerhetsrelaterade, icke-känsliga och icke-konfidentiella reproducerbara ramverksfel, skapa ett ärende med ASP.NET Core-produktenheten. Öppna inte ett ärende med produktgruppen förrän du noggrant har undersökt orsaken till ett problem och inte kan lösa det själv och med hjälp av communityt på ett offentligt support-forum. Produktenheten kan inte felsöka enskilda appar som har brutits på grund av enkel felkonfiguration eller användningsfall som rör tjänster från tredje part. Om en rapport är känslig eller konfidentiell eller beskriver en potentiell säkerhetsbrist i produkten som cyberattacker kan utnyttja kan du läsa Rapportering av säkerhetsproblem och buggar (
dotnet/aspnetcore
GitHub-lagringsplats).Obehörig klient för ME-ID
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Auktoriseringen misslyckades. Dessa krav uppfylldes inte: DenyAnonymousAuthorizationRequirement: Kräver en autentiserad användare.
Återanropsfel vid inloggning från ME-ID:
- Fel:
unauthorized_client
- Beskrivning:
AADB2C90058: The provided application is not configured to allow public clients.
Så här löser du felet:
- Gå till -appens manifest i Azure-portalen.
- Ange attributet
allowPublicClient
tillnull
ellertrue
.
- Fel:
Cookies och webbplatsdata
Cookies och webbplatsdata kan sparas mellan appuppdateringar och störa testning och felsökning. Rensa följande när du gör ändringar i appkoden, ändringar av användarkonton med providern eller konfigurationsändringar för providerappen:
- Cookies för användarinloggning
- App cookies
- Cachelagrade och lagrade platsdata
En metod för att förhindra kvardröjande cookies och webbplatsdata från att störa testning och felsökning är att:
- Konfigurera en webbläsare
- Använd en webbläsare för testning som du kan konfigurera för att ta bort alla cookie och platsdata varje gång webbläsaren stängs.
- Kontrollera att webbläsaren stängs manuellt eller av IDE för ändringar i appen, testanvändaren eller providerkonfigurationen.
- Använd ett anpassat kommando för att öppna en webbläsare i InPrivate- eller Incognito-läge i Visual Studio:
- Öppna dialogrutan Bläddra med från Visual Studio-knappen Kör.
- Välj knappen Lägg till.
- Ange sökvägen till webbläsaren i fältet Program. Följande körbara sökvägar är typiska installationsplatser för Windows 10. Om webbläsaren är installerad på en annan plats eller om du inte använder Windows 10 anger du sökvägen till webbläsarens körbara fil.
- 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
- Microsoft Edge:
- I fältet Argument anger du det kommandoradsalternativ som webbläsaren använder för att öppna i InPrivate- eller Inkognitoläge. Vissa webbläsare kräver appens URL.
- Microsoft Edge: Använd
-inprivate
. - Google Chrome: Använd
--incognito --new-window {URL}
, där platshållaren för{URL}
är url:en som ska öppnas (till exempelhttps://localhost:5001
). - Mozilla Firefox: Använd
-private -url {URL}
, där platshållaren{URL}
är url:en som ska öppnas (till exempelhttps://localhost:5001
).
- Microsoft Edge: Använd
- Ange ett namn i fältet Användarvänligt namn. Till exempel
Firefox Auth Testing
. - Välj knappen OK.
- Om du vill undvika att behöva välja webbläsarprofilen för varje iteration av testning med en app anger du profilen som standard med knappen Ange som standard.
- Kontrollera att webbläsaren är stängd av IDE för alla ändringar i appen, testanvändaren eller providerkonfigurationen.
Appuppgraderingar
En fungerande app kan misslyckas omedelbart efter att ha uppgraderat .NET Core SDK på utvecklingsdatorn eller ändrat paketversioner i appen. I vissa fall kan osammanhängande paket orsaka att en app slutar fungera vid genomförande av större uppgraderingar. De flesta av dessa problem kan åtgärdas genom att följa dessa instruktioner:
- Rensa det lokala systemets NuGet-paketcacheminnen genom att köra
dotnet nuget locals all --clear
från ett kommandogränssnitt. - Ta bort projektets mappar
bin
ochobj
. - Återställa och återskapa projektet.
- Ta bort alla filer i distributionsmappen på servern innan du distribuerar om appen.
Obs
Användning av paketversioner som inte är kompatibla med appens målramverk stöds inte. Information om ett paket finns i NuGet Gallery eller FuGet Package Explorer.
Kör serverappen
När du testar och felsöker Blazor Web Appkontrollerar du att du kör appen från serverprojektet.
Inspektera användaren
Följande UserClaims
komponent kan användas direkt i appar eller fungera som grund för ytterligare anpassning.
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;
}
}
Ytterligare resurser
- dokumentation om Microsofts identitetsplattform
-
AzureAD/microsoft-identity-web
GitHub-lagringsplats: Användbar vägledning för att implementera Microsoft Identity Web for Microsoft Entra ID och Azure Active Directory B2C för ASP.NET Core-appar, inklusive länkar till exempelappar och relaterad Azure-dokumentation. För närvarande hanteras inte Blazor Web Apputtryckligen av Azure-dokumentationen, men konfigurationen av en Blazor Web App för ME-ID och värd i Azure är densamma som för vilken ASP.NET Core-webbapp som helst. -
AuthenticationStateProvider
tjänst - Hantera autentiseringstillstånd i Blazor Web Apps
- Service-abstraktioner i Blazor Web Apps
ASP.NET Core