Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento průvodce ukazuje, jak zabezpečit distribuovanou aplikaci .NET Aspire pomocí ověřování a autorizace Microsoft Entra ID. Zahrnuje:
-
Front-end Blazor Serveru (
MyService.Web): Přihlášení uživatele pomocí OpenID Connect a získání tokenu -
Protected API back-end (
MyService.ApiService): Ověřování JWT pomocí Microsoft. Identity.Web - Kompletní tok: Blazor získává přístupové tokeny a volá chráněné rozhraní API pomocí zjišťování služby Aspire.
V této příručce se předpokládá, že jste začali s projektem Aspire vytvořeným pomocí následujícího příkazu:
aspire new aspire-starter --name MyService
Předpoklady
- .NET 9 SDK nebo novější
- .NET Aspire CLI – viz Instalace rozhraní příkazového řádku Aspire
- Microsoft Entra tenant – Informace o nastavení najdete v tématu Register apps in Microsoft Entra ID
Návod
Začínáte s Aspire? Viz přehled .NET Aspire.
Vysvětlení dvoufázového pracovního postupu
Tento průvodce se řídí dvoufázovým přístupem:
| Fáze | Co se stane | Výsledek |
|---|---|---|
| Fáze 1 | Přidání ověřovacího kódu se zástupnými hodnotami | Aplikace se sestaví, ale nespustí se |
| Fáze 2 | Zřízení registrací aplikací Microsoft Entra | Aplikace běží se skutečným ověřováním. |
Registrace aplikací v Microsoft Entra ID
Než bude vaše aplikace moct ověřovat uživatele, budete potřebovat dvě registrace aplikací v Microsoft Entra:
| Registrace aplikace | Purpose | Konfigurace klíče |
|---|---|---|
API (MyService.ApiService) |
Ověřuje příchozí tokeny. | URI ID aplikace, access_as_user obor |
Webová aplikace (MyService.Web) |
Přihlášení uživatelů, získání tokenů | URI přesměrování, tajný klíč klienta, oprávnění API |
Pokud už máte nakonfigurované registrace aplikací, potřebujete pro svoji appsettings.jsonaplikaci tyto hodnoty:
- TenantId – ID vašeho tenanta Microsoft Entra
- API ClientId – ID aplikace (klienta) registrace vaší aplikace API
-
Identifikátor URI ID aplikace API – obvykle
api://<api-client-id>(používá se vAudiencesaScopes) - ID klienta webové aplikace – ID aplikace (klienta) registrace webové aplikace
- Tajný klíč klienta (nebo certifikát) – přihlašovací údaje pro webovou aplikaci (ukládání do tajných kódů uživatelů, nikoli appsettings.json)
-
Scopes – Rozsahy oprávnění, které vaše webová aplikace vyžaduje, například
api://<api-client-id>/.defaultneboapi://<api-client-id>/access_as_user
Krok 1: Registrace rozhraní API
- Přejděte na Centrum pro správu Microsoft Entra>Identity>Applications>Registrace aplikací.
- Vyberte Nová registrace.
-
Jméno:
MyService.ApiService - Podporované typy účtů: Účty pouze v tomto organizačním adresáři (jeden tenant)
- Vyberte Zaregistrovat.
-
Jméno:
- Přejděte na Zveřejnit rozhraní API>Přidat vedle identifikátoru URI ID aplikace.
- Přijměte výchozí (
api://<client-id>) nebo ho přizpůsobte. - Vyberte Přidat obor:
-
Název oboru:
access_as_user - Kdo může souhlasit: Správci a uživatelé
- Zobrazovaný název souhlasu správce: Přístup k rozhraní MyService API
- Popis souhlasu správce: Umožňuje aplikaci přístup k rozhraní MYService API jménem přihlášeného uživatele.
- Vyberte Přidat rozsah.
-
Název oboru:
- Přijměte výchozí (
- Zkopírujte ID aplikace (klienta) – budete ho potřebovat pro oba
appsettings.jsonsoubory.
Další informace najdete v tématu Rychlý start: Konfigurace aplikace pro zveřejnění webového rozhraní API.
Krok 2: Registrace webové aplikace
- Přejděte na Registrace aplikací>Nová registrace.
-
Jméno:
MyService.Web - Podporované typy účtů: Účty pouze v tomto organizačním adresáři
-
Identifikátor URI přesměrování: Vyberte Web a zadejte adresu URL aplikace +
/signin-oidc- Pro místní vývoj:
https://localhost:7001/signin-oidc(zkontrolujte svůjlaunchSettings.jsonpro skutečný port)
- Pro místní vývoj:
- Vyberte Zaregistrovat.
-
Jméno:
- Přejděte na Ověřování>Přidat URI a přidejte všechny své vývojové adresy URL (z
launchSettings.json). - Přejděte na Certifikáty a tajné>kódy> klientaNové tajné klíče klienta.
- Přidejte popis a vypršení platnosti.
- Zkopírujte hodnotu tajného kódu okamžitě – znovu se nezobrazí.
- Přejděte na oprávnění >– Přidejte oprávnění>Moje rozhraní API.
- Vyberte možnost
MyService.ApiService. - Vyberte
access_as_user>Přidat oprávnění. - Vyberte Udělit souhlas správce pro [tenanta] (nebo se uživatelům zobrazí výzva k prvnímu použití).
- Vyberte možnost
- Zkopírujte ID aplikace (klienta) pro webovou aplikaci
appsettings.json.
Poznámka:
Některé organizace nepovolují tajné kódy klientů. Alternativy najdete v tématu Přihlašovací údaje certifikátu nebo ověřování bez certifikátů.
Další informace najdete v tématu Rychlý start: Registrace aplikace.
Krok 3: Aktualizace konfigurace
Po vytvoření registrací aplikací aktualizujte soubory appsettings.json :
Rozhraní API (MyService.ApiService/appsettings.json):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "YOUR_TENANT_ID",
"ClientId": "YOUR_API_CLIENT_ID",
"Audiences": ["api://YOUR_API_CLIENT_ID"]
}
}
Webová aplikace (MyService.Web/appsettings.json):
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "YOUR_TENANT_ID",
"ClientId": "YOUR_WEB_CLIENT_ID",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [
{ "SourceType": "ClientSecret" }
]
},
"WeatherApi": {
"Scopes": ["api://YOUR_API_CLIENT_ID/.default"]
}
}
Bezpečně uložte tajný kód:
cd MyService.Web
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "YOUR_SECRET_VALUE"
| Hodnota | Kde najít |
|---|---|
TenantId |
Microsoft Entra Administrační centrum > – Přehled > ID tenanta |
API ClientId |
Registrace aplikací > MyService.ApiService > ID aplikace (klienta) |
Web ClientId |
Registrace aplikací > MyService.Web > ID aplikace (klienta) |
Client Secret |
Vytvořeno v kroku 2 (kopírování okamžitě po vytvoření) |
Poznámka:
Úvodní šablona Aspire automaticky vytvoří WeatherApiClient třídu v MyService.Web projektu. Tento typ HttpClient se používá v tomto průvodci k předvedení volání chráněného rozhraní API. Tuto třídu nemusíte vytvářet sami – je součástí šablony.
Začněte rychle
Tato část poskytuje zhuštěný přehled pro přidání autentizace. Podrobné návody najdete v části 1 a 2.
ROZHRANÍ API (MyService.ApiService)
Nainstalujte balíček NuGet Microsoft.Identity.Web:
dotnet add package Microsoft.Identity.Web
Přidejte konfiguraci Microsoft Entra do appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id>",
"ClientId": "<api-client-id>",
"Audiences": ["api://<api-client-id>"]
}
}
Registrujte ověřování a autorizaci v Program.cs:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddAuthorization();
// ...
app.UseAuthentication();
app.UseAuthorization();
// ...
app.MapGet("/weatherforecast", () => { /* ... */ }).RequireAuthorization();
Webová aplikace (MyService.Web)
Nainstalujte balíček NuGet Microsoft.Identity.Web.
dotnet add package Microsoft.Identity.Web
Přidejte konfiguraci Microsoft Entra do appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-id>",
"ClientId": "<web-client-id>",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [{ "SourceType": "ClientSecret" }]
},
"WeatherApi": { "Scopes": ["api://<api-client-id>/.default"] }
}
Konfigurace ověřování, získání tokenu a podběžného klienta rozhraní API v Program.cs:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<BlazorAuthenticationChallengeHandler>();
builder.Services.AddHttpClient<WeatherApiClient>(client =>
client.BaseAddress = new("https+http://apiservice"))
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
// ...
app.UseAuthentication();
app.UseAuthorization();
app.MapGroup("/authentication").MapLoginAndLogout();
Automaticky MicrosoftIdentityMessageHandler získá a připojí tokeny a BlazorAuthenticationChallengeHandler zpracuje problémy se souhlasem a podmíněným přístupem.
Důležité
Nezapomeňte vytvořit UserInfo.razor tlačítko pro přihlášení. Podrobnosti najdete v tématu Přidání komponent uživatelského rozhraní Blazor .
Poznámka:
BlazorAuthenticationChallengeHandler a LoginLogoutEndpointRouteBuilderExtensions jsou dodávány v Microsoft.Identity.Web (v3.3.0+). Není vyžadováno kopírování souborů.
Identifikace souborů k úpravě
Následující tabulka uvádí soubory, které změníte v jednotlivých projektech:
| Projekt | Soubor | Changes |
|---|---|---|
| ApiService | Program.cs |
JWT Bearer auth, autorizační middleware |
appsettings.json |
konfigurace Microsoft Entra | |
.csproj |
Přidejte Microsoft.Identity.Web |
|
| Web | Program.cs |
Ověřování OIDC, získání tokenu, BlazorAuthenticationChallengeHandler |
appsettings.json |
konfigurace Microsoft Entra, rozsahy podřízených rozhraní API | |
.csproj |
Přidejte Microsoft.Identity.Web (v3.3.0+) |
|
Components/UserInfo.razor |
Uživatelské rozhraní přihlašovacího tlačítka (nový soubor) | |
Components/Layout/MainLayout.razor |
Zahrnout součást UserInfo | |
Components/Routes.razor |
AuthorizeRouteView pro chráněné stránky | |
| Stránky volající rozhraní API | Vyzkoušení nebo zachycení pomocí challengehandleru |
Vysvětlení toku ověřování
Následující diagram znázorňuje interakci front-endu Blazoru, Microsoft Entra a chráněného rozhraní API:
flowchart LR
A[User Browser] -->|1 Login OIDC| B[Blazor Server<br/>MyService.Web]
B -->|2 Redirect| C[Microsoft Entra ID]
C -->|3 auth code| B
B -->|4 exchange auth code| C
C -->|5 tokens| B
B -->|6 cookie + session| A
B -->|7 HTTP + Bearer token| D[ASP.NET API<br/>MyService.ApiService<br/>Microsoft.Identity.Web]
D -->|8 Validate JWT| C
D -->|9 Weather data| B
- Uživatel navštíví aplikaci Blazor → Neověřené → zobrazí tlačítko Přihlásit se.
-
Uživatel vybere přihlášení → Přesměrování na
/authentication/login→ výzva OIDC → Microsoft Entra. -
Uživatel se přihlásí → Microsoft Entra přesměruje na
/signin-oidc→ soubor cookie vytvořený. -
Uživatel přejde na stránku Počasí → volání
WeatherApiClient.GetAsync()Blazoru . -
MicrosoftIdentityMessageHandlerzachytí požadavek, získá token z mezipaměti (nebo tiše obnoví) a připojí hlavičkuAuthorization: Bearer <token>. - API obdrží požadavek → Microsoft.Identity.Web ověřuje JWT → vrací data.
- Blazor vykreslí data o počasí.
Kontrola struktury řešení
Úvodní šablona Aspire vytvoří následující rozložení projektu:
MyService/
├── MyService.AppHost/ # Aspire orchestration
├── MyService.ApiService/ # Protected API (Microsoft.Identity.Web)
├── MyService.Web/ # Blazor Server (Microsoft.Identity.Web)
├── MyService.ServiceDefaults/ # Shared defaults
└── MyService.Tests/ # Tests
Část 1: Zabezpečení back-endu rozhraní API pomocí Microsoft Identity.Web
Tato část nakonfiguruje projekt rozhraní API tak, aby ověřil tokeny JWT Bearer vydané Microsoft Entra.
Přidejte balíček Microsoft.Identity.Web
Spusťte následující příkaz pro instalaci balíčku NuGet Microsoft.Identity.Web:
cd MyService.ApiService
dotnet add package Microsoft.Identity.Web
Konfigurace nastavení Microsoft Entra
Přidejte konfiguraci Microsoft Entra do MyService.ApiService/appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<your-tenant-id>",
"ClientId": "<your-api-client-id>",
"Audiences": [
"api://<your-api-client-id>"
]
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Vlastnosti klíče:
-
ClientId: ID registrace aplikace API Microsoft Entra -
TenantId: ID tenanta Microsoft Entra nebo"organizations"pro více tenantů nebo"common"pro libovolný Microsoft účet -
Audiences: Platné cílové skupiny tokenů (obvykle identifikátor URI ID vaší aplikace)
Aktualizace rozhraní API v Program.cs
Nahraďte obsah MyService.ApiService/Program.cs následujícím kódem pro přidání ověřování pomocí nosiče JWT a ochrany koncových bodů.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Add Microsoft.Identity.Web JWT Bearer authentication
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddProblemDetails();
builder.Services.AddOpenApi();
builder.Services.AddAuthorization();
var app = builder.Build();
app.UseExceptionHandler();
app.UseAuthentication();
app.UseAuthorization();
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
string[] summaries = ["Freezing", "Bracing", "Chilly", "Cool", "Mild",
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"];
app.MapGet("/", () =>
"API service is running. Navigate to /weatherforecast to see sample data.");
app.MapGet("/weatherforecast", () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast")
.RequireAuthorization();
app.MapDefaultEndpoints();
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
Klíčové změny:
- Registrace autentizace typu JWT Bearer pomocí
AddMicrosoftIdentityWebApi - Přidejte
app.UseAuthentication()aapp.UseAuthorization()middleware - Použít
.RequireAuthorization()na chráněné koncové body
Testování chráněného rozhraní API
Ověřte, že rozhraní API odmítne neověřené požadavky a přijímá platné tokeny.
Odeslání požadavku bez tokenu:
curl https://localhost:<PORT>/weatherforecast
# Expected: 401 Unauthorized
Odeslání požadavku s platným tokenem:
curl -H "Authorization: Bearer <TOKEN>" https://localhost:<PORT>/weatherforecast
# Expected: 200 OK with weather data
Část 2: Konfigurace front-endu Blazor pro ověřování
Aplikace Blazor Server používá Microsoft. Identity.Web do:
- Přihlášení uživatelů pomocí OIDC
- Získání přístupových tokenů pro volání rozhraní API
- Připojení tokenů k odchozím požadavkům HTTP
Přidejte balíček Microsoft.Identity.Web
Spuštěním následujícího příkazu nainstalujte balíček NuGet Microsoft.Identity.Web:
cd MyService.Web
dotnet add package Microsoft.Identity.Web
Konfigurace nastavení Microsoft Entra
Přidejte rozsahy konfigurace Microsoft Entra a podřízeného rozhraní API do MyService.Web/appsettings.json:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<your-tenant>.onmicrosoft.com",
"TenantId": "<tenant-guid>",
"ClientId": "<web-app-client-id>",
"CallbackPath": "/signin-oidc",
"ClientCredentials": [
{
"SourceType": "ClientSecret",
"ClientSecret": "<your-client-secret>"
}
]
},
"WeatherApi": {
"Scopes": [ "api://<api-client-id>/.default" ]
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Podrobnosti o konfiguraci:
-
ClientId: ID registrace webové aplikace (ne ID rozhraní API) -
ClientCredentials: Přihlašovací údaje pro webovou aplikaci k získání tokenů. Podporuje více typů přihlašovacích údajů. Viz Přehled přihlašovacích údajů pro možnosti připravené pro produkční prostředí. -
Scopes: Musí odpovídat URI ID aplikace rozhraní API s/.defaultpříponou.
Výstraha
V produkčním prostředí místo tajných klíčů klienta používejte certifikáty nebo spravovanou identitu. Doporučený přístup najdete v tématu Ověřování bez certifikátů .
Aktualizace Program.cs webové aplikace
Nahraďte obsah MyService.Web/Program.cs následujícím kódem pro konfiguraci ověřování OIDC, získání tokenu a podřízeného klienta rozhraní API:
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Abstractions;
using Microsoft.Identity.Web;
using MyService.Web;
using MyService.Web.Components;
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
// Authentication + Microsoft Identity Web
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddCascadingAuthenticationState();
// Blazor components
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
// Blazor authentication challenge handler for incremental consent and Conditional Access
builder.Services.AddScoped<BlazorAuthenticationChallengeHandler>();
builder.Services.AddOutputCache();
// Downstream API client with MicrosoftIdentityMessageHandler
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
// Aspire service discovery: resolves "apiservice" at runtime
client.BaseAddress = new("https+http://apiservice");
})
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.UseAntiforgery();
app.UseOutputCache();
app.MapStaticAssets();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
// Login/Logout endpoints with incremental consent support
app.MapGroup("/authentication").MapLoginAndLogout();
app.MapDefaultEndpoints();
app.Run();
klíčové body:
-
AddMicrosoftIdentityWebApp: Konfiguruje ověřování OIDC. -
EnableTokenAcquisitionToCallDownstreamApi: Povolí získání tokenu pro podřízená rozhraní API. -
AddScoped<BlazorAuthenticationChallengeHandler>: Zpracovává přírůstkový souhlas a podmíněný přístup na Blazor Serveru. -
AddMicrosoftIdentityMessageHandler: Automaticky připojí nosné tokeny k žádostem HttpClient. -
https+http://apiservice: Zjišťování služby Aspire převede tuto hodnotu na skutečnou adresu URL rozhraní API. -
Pořadí middlewaru:
UseAuthentication()→UseAuthorization()→ koncové body
Rozšíření AddMicrosoftIdentityMessageHandler podporuje více vzorů konfigurace:
Možnost 1: Konfigurace z appsettings.json (viz předchozí)
.AddMicrosoftIdentityMessageHandler(builder.Configuration.GetSection("WeatherApi"));
Možnost 2: Inline konfigurace s delegátem Action
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
});
Možnost 3: Konfigurace podle požadavku (bez parametrů)
.AddMicrosoftIdentityMessageHandler();
// Then in your service, configure per-request:
var request = new HttpRequestMessage(HttpMethod.Get, "/weatherforecast")
.WithAuthenticationOptions(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
});
var response = await _httpClient.SendAsync(request);
Přidání komponent uživatelského rozhraní Blazor
Důležité
Tento krok je často zapomenutý. Bez komponenty UserInfo nemají uživatelé způsob, jak se přihlásit.
BlazorAuthenticationChallengeHandler a LoginLogoutEndpointRouteBuilderExtensions jsou dodávány v Microsoft.Identity.Web v3.3.0+ Jakmile na balíček odkazujete, jsou automaticky dostupné – nevyžaduje se kopírování souborů.
Vytvořit MyService.Web/Components/UserInfo.razor:
@using Microsoft.AspNetCore.Components.Authorization
<AuthorizeView>
<Authorized>
<span class="nav-item">Hello, @context.User.Identity?.Name</span>
<form action="/authentication/logout" method="post" class="nav-item">
<AntiforgeryToken />
<input type="hidden" name="returnUrl" value="/" />
<button type="submit" class="btn btn-link nav-link">Logout</button>
</form>
</Authorized>
<NotAuthorized>
<a href="/authentication/login?returnUrl=/" class="nav-link">Login</a>
</NotAuthorized>
</AuthorizeView>
Přidat do rozložení: Zahrnout <UserInfo /> do svého MainLayout.razor:
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<UserInfo />
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
Aktualizace Routes.razor pro AuthorizeRouteView
Nahradit RouteView za AuthorizeRouteView v Components/Routes.razor:
@using Microsoft.AspNetCore.Components.Authorization
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
<NotAuthorized>
<p>You are not authorized to view this page.</p>
<a href="/authentication/login">Login</a>
</NotAuthorized>
</AuthorizeRouteView>
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
Zpracování výjimek na stránkách volajících rozhraní API
Blazor Server vyžaduje explicitní zpracování výjimek pro podmíněný přístup a souhlas. Každou stránku, která volá podřízené rozhraní API, musíte zpracovat pomocí MicrosoftIdentityWebChallengeUserException, pokud vaše aplikace není předem autorizována, a vyžádáte si všechny scopy předem v Program.cs.
Následující Weather.razor příklad ukazuje správné zpracování výjimek:
@page "/weather"
@attribute [Authorize]
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Identity.Web
@inject WeatherApiClient WeatherApi
@inject BlazorAuthenticationChallengeHandler ChallengeHandler
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-warning">@errorMessage</div>
}
else if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
private string? errorMessage;
protected override async Task OnInitializedAsync()
{
if (!await ChallengeHandler.IsAuthenticatedAsync())
{
await ChallengeHandler.ChallengeUserWithConfiguredScopesAsync("WeatherApi:Scopes");
return;
}
try
{
forecasts = await WeatherApi.GetWeatherAsync();
}
catch (Exception ex)
{
// Handle incremental consent / Conditional Access
if (!await ChallengeHandler.HandleExceptionAsync(ex))
{
errorMessage = $"Error loading weather data: {ex.Message}";
}
}
}
}
Vzor funguje takto:
-
IsAuthenticatedAsync()zkontroluje, jestli je uživatel přihlášený před voláním rozhraní API. -
HandleExceptionAsync()zachytíMicrosoftIdentityWebChallengeUserException(nebo jako InnerException). - Pokud se jedná o výjimku výzvy, uživatel se přesměruje na opětovné ověření pomocí požadovaných deklarací identity nebo oborů.
- Pokud se nejedná o výjimku výzvy,
HandleExceptionAsyncvrátífalse, abyste mohli chybu zpracovat sami.
Uložení klientského tajemství do uživatelských tajemství
Pomocí .NET Secret Manageru bezpečně uložte tajný klíč klienta během vývoje.
Upozornění
Nikdy neukládejte tajné informace do správy zdrojového kódu.
Inicializace tajných kódů uživatelů a uložení tajného klíče klienta:
cd MyService.Web
dotnet user-secrets init
dotnet user-secrets set "AzureAd:ClientCredentials:0:ClientSecret" "<your-client-secret>"
Potom aktualizujte appsettings.json a odeberte pevně zakódovaný tajný klíč:
{
"AzureAd": {
"ClientCredentials": [
{
"SourceType": "ClientSecret"
}
]
}
}
Microsoft. Identity.Web podporuje více typů přihlašovacích údajů. V produkčním prostředí se podívejte na přehled přihlašovacích údajů.
Ověření implementace
Pomocí tohoto kontrolního seznamu potvrďte, že jste dokončili všechny požadované kroky.
Projekt rozhraní API
- [ ] Přidání balíčku
Microsoft.Identity.Web - [ ] Aktualizováno
appsettings.jsonpřidáním oddíluAzureAd - [ ] Aktualizováno
Program.cspomocíAddMicrosoftIdentityWebApi - [ ] Přidáno
.RequireAuthorization()do chráněných koncových bodů
Projekt Web/Blazor
- [ ] Přidání balíčku
Microsoft.Identity.Web(v3.3.0+) - [ ] Aktualizováno
appsettings.jsono oddílyAzureAdaWeatherApi - [ ] Aktualizováno
Program.css využitím OIDC, získávání tokenů - [ ] Přidáno
AddScoped<BlazorAuthenticationChallengeHandler>() - [ ] Vytvořeno
Components/UserInfo.razor(tlačítko pro přihlášení) - [ ] Aktualizováno
MainLayout.razortak, aby zahrnovalo<UserInfo /> - [ ] Aktualizováno
Routes.razorpomocíAuthorizeRouteView - [ ] Přidáno try/catch s
ChallengeHandlerna každou stránku volající rozhraní API - [ ] Uložený tajný klíč klienta v uživatelských tajných klíčích
Ověření
- [ ]
dotnet builduspěje - [ ] Registrace aplikací vytvořené v Microsoft Entra centru pro správu
- [ ]
appsettings.jsonmá skutečné identifikátory GUID (žádné zástupné symboly)
Test a řešení potíží
Po dokončení implementace spusťte aplikaci a ověřte tok kompletního ověřování.
Spuštění aplikace
Spusťte Aspire AppHost a spusťte jak webové projekty, tak projekty rozhraní API:
# From solution root
dotnet restore
dotnet build
# Launch AppHost (starts both Web and API)
dotnet run --project .\MyService.AppHost\MyService.AppHost.csproj
Otestování toku ověřování
- Otevřete prohlížeč → webové uživatelské rozhraní Blazor (zkontrolujte řídicí panel dashboard Aspire pro adresu URL).
- Vyberte Login → Přihlásit se pomocí Microsoft Entra.
- Přejděte na stránku Počasí .
- Ověřte načtení dat o počasí (z chráněného rozhraní API).
Řešení běžných problémů
Následující tabulka uvádí časté problémy a jejich řešení:
| Problém | Řešení |
|---|---|
| 401 při voláních rozhraní API | Ověřte, že obory ve appsettings.json odpovídají identifikátoru URI ID aplikace rozhraní API. |
| Selhání přesměrování OIDC | Přidejte /signin-oidc k identifikátorům URI přesměrování Microsoft Entra |
| Token není připojený | Ujistěte se, že je AddMicrosoftIdentityMessageHandler voláno na HttpClient |
| Neuspělo zjišťování služeb | Zkontrolujte odkazy na oba projekty, které jsou spuštěny |
| AADSTS65001 | Požadován souhlas správce – udělení souhlasu v Centrum pro správu Microsoft Entra |
| Bez přihlašovacího tlačítka | Ujistěte se, že UserInfo.razor existuje a je součástí MainLayout.razor |
| Smyčka souhlasu | Ujistěte se, že try/catch with HandleExceptionAsync je přítomno na všech stránkách volajících API. |
Povolte protokolování MSAL
Při řešení potíží s ověřováním povolte podrobné protokolování MSAL a zobrazte podrobnosti o získání tokenu. Přidejte následující úrovně protokolu:appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Identity": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Výstraha
Zakažte protokolování ladění v produkčním prostředí, protože může být velmi podrobné.
Kontrola tokenů
Pokud chcete ladit problémy s tokeny, dekódujte JWT na jwt.ms a ověřte:
-
aud(cílová skupina): Odpovídá ID klienta rozhraní API nebo identifikátoru URI ID aplikace. -
iss(vystavitel): Odpovídá vašemu tenantovi (https://login.microsoftonline.com/<tenant-id>/v2.0) -
scp(obory):: Obsahuje požadované obory. -
exp(vypršení platnosti): Platnost tokenu nevypršela
Prozkoumání běžných scénářů
Následující části ukazují, jak rozšířit základní implementaci pro další případy použití.
Ochrana stránek Blazor
[Authorize] Přidejte atribut na stránky, které vyžadují ověření:
@page "/weather"
@attribute [Authorize]
Nebo definujte zásady autorizace v Program.cs:
// Program.cs
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
@attribute [Authorize(Policy = "AdminOnly")]
Ověření oborů v rozhraní API
Ujistěte se, že rozhraní API přijímá pouze tokeny s konkrétními oprávněními řetězením RequireScope:
app.MapGet("/weatherforecast", () =>
{
// ... implementation
})
.RequireAuthorization()
.RequireScope("access_as_user");
Použití tokenů pouze pro aplikace (service-to-service)
V případě scénářů démona nebo volání mezi službami bez kontextu uživatele nastavte RequestAppToken na true:
builder.Services.AddHttpClient<WeatherApiClient>(client =>
{
client.BaseAddress = new("https+http://apiservice");
})
.AddMicrosoftIdentityMessageHandler(options =>
{
options.Scopes.Add("api://<api-client-id>/.default");
options.RequestAppToken = true;
});
Použití přihlašovacích údajů bez certifikátů pro produkční prostředí
Pro produkční nasazení v Azure použijte spravovanou identitu místo tajných klíčů klienta.
ClientCredentials Nakonfigurujte oddíl následujícím způsobem:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "<tenant-guid>",
"ClientId": "<web-app-client-id>",
"ClientCredentials": [
{
"SourceType": "SignedAssertionFromManagedIdentity",
"ManagedIdentityClientId": "<user-assigned-mi-client-id>"
}
]
}
}
Další informace najdete v tématu Ověřování bez certifikátů.
Volání podřízených API z API (on-behalf-of)
Pokud vaše rozhraní API potřebuje za uživatele volat jiné podřízené rozhraní API, povolte získání tokenu jménem uživatele v Program.cs:
// MyService.ApiService/Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
builder.Services.AddDownstreamApi("GraphApi", builder.Configuration.GetSection("GraphApi"));
Přidejte konfiguraci podřízeného rozhraní API do appsettings.json:
{
"GraphApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": [ "User.Read" ]
}
}
Potom volejte podřízené rozhraní API z koncového bodu:
{
var user = await downstreamApi.GetForUserAsync<JsonElement>("GraphApi", "me");
return user;
}).RequireAuthorization();
Další informace naleznete v sekci Volání podřízených rozhraní API.