Zabezpieczanie hostowanej aplikacji ASP.NET Core Blazor WebAssembly za pomocą Identity serwera
Ważne
Szablon projektu Hostowany Blazor WebAssembly został usunięty ze struktury z wydaniem programu .NET 8 (listopad 2023 r.). Wskazówki zawarte w tym artykule są obsługiwane tylko dla platformy .NET 7 lub starszej wersji. Hostowane aplikacje Blazor WebAssembly, które są uaktualniane w każdej wersji, nadal otrzymują pomoc techniczną dotyczącą produktów. Możesz też przekształcić aplikację w autonomiczną aplikację Blazor WebAssembly lub Blazor Web App.
W tym artykule wyjaśniono, jak utworzyć hostowane rozwiązanieBlazor WebAssembly, które używa serwera DuendeIdentity do uwierzytelniania użytkowników i wywołań interfejsu API.
Ważne
Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.
Uwaga
Aby skonfigurować autonomiczną lub hostowaną Blazor WebAssembly aplikację do korzystania z istniejącego, zewnętrznego wystąpienia serwera Identity, postępuj zgodnie ze wskazówkami w temacie Zabezpieczanie autonomicznej aplikacji ASP.NET Core Blazor WebAssembly za pomocą biblioteki Uwierzytelniania.
Aby uzyskać dodatkowe informacje na temat scenariuszy zabezpieczeń po przeczytaniu tego artykułu, zobacz
Przewodnik
Podsekcje przewodnika wyjaśniają, jak:
- Utwórz aplikację Blazor
- Uruchom aplikację
Tworzenie Blazor aplikacji
Aby utworzyć nowy Blazor WebAssembly projekt z mechanizmem uwierzytelniania:
Tworzenie nowego projektu.
Blazor WebAssembly Wybierz szablon Aplikacja. Wybierz Dalej.
Podaj nazwę projektu bez użycia kreski. Upewnij się, że lokalizacja jest poprawna. Wybierz Dalej.
Unikaj używania łączników (
-
) w nazwie projektu, które przerywają tworzenie identyfikatora aplikacji OIDC. Logika w szablonie Blazor WebAssembly projektu używa nazwy projektu jako identyfikatora aplikacji OIDC w konfiguracji rozwiązania, a kreski nie są dopuszczalne w identyfikatorze aplikacji OIDC. Przypadek Pascal (BlazorSample
) lub podkreślenia (Blazor_Sample
) są akceptowalnymi alternatywami.W oknie dialogowym Dodatkowe informacje wybierz pozycję Indywidualne konta jako typ uwierzytelniania, aby przechowywać użytkowników w aplikacji przy użyciu systemu ASP.NET CoreIdentity.
Zaznacz pole wyboru ASP.NET Core Hosted.
Wybierz przycisk Utwórz, aby utworzyć aplikację.
Uruchom aplikację
Uruchom aplikację z Server
projektu. W przypadku korzystania z programu Visual Studio, można:
Wybierz strzałkę listy rozwijanej obok przycisku Uruchom. Otwórz pozycję Konfiguruj projekty startowe z listy rozwijanej. Wybierz opcję Pojedynczy projekt startowy. Potwierdź lub zmień projekt projektu startowego na
Server
projekt.Upewnij się, że
Server
projekt został podświetlony w Eksploratorze rozwiązań przed uruchomieniem aplikacji przy użyciu dowolnego z następujących podejść:- Wybierz przycisk Run (Uruchom).
- Użyj polecenia Debuguj>Rozpocznij debugowanie z menu.
- Naciśnij klawisz F5.
W powłoce wiersza polecenia przejdź do folderu projektu
Server
rozwiązania.dotnet watch
Wykonaj polecenie (lubdotnet run
).
Części rozwiązania
W tej sekcji opisano części wygenerowanego rozwiązania z szablonu projektu Blazor WebAssembly oraz sposób konfigurowania projektów Client i Server do celów odwołań. Nie ma konkretnych wskazówek, które należy wykonać w tej sekcji dla podstawowej aplikacji roboczej, jeśli aplikacja została utworzona przy użyciu wskazówek w sekcji Przewodnik . Wskazówki zawarte w tej sekcji są przydatne podczas aktualizowania aplikacji w celu uwierzytelniania i autoryzowania użytkowników. Jednak alternatywnym podejściem do aktualizowania aplikacji jest utworzenie nowej aplikacji na podstawie wskazówek w sekcji Przewodnik i przeniesienie składników, klas i zasobów aplikacji do nowej aplikacji.
Server usługi aplikacyjne
Ta sekcja dotyczy aplikacji rozwiązania Server .
Zarejestrowane są następujące usługi.
W pliku
Program
:Entity Framework Core i ASP.NET Core Identity:
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite( ... )); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
Identity Serwer z dodatkową AddApiAuthorization metodą pomocnika, która konfiguruje domyślne konwencje ASP.NET Core na serwerze Identity :
builder.Services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Uwierzytelnianie za pomocą dodatkowej AddIdentityServerJwt metody pomocniczej, która konfiguruje aplikację do weryfikowania tokenów JWT utworzonych przez Identity serwer:
builder.Services.AddAuthentication() .AddIdentityServerJwt();
W
Startup.ConfigureServices
pliku:Startup.cs
Entity Framework Core i ASP.NET Core Identity:
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();
Ostrzeżenie
Nie przechowuj sekretów aplikacji, ciągów połączeń, poświadczeń, haseł, osobistych numerów identyfikacyjnych (PIN), prywatnego kodu C#/.NET ani kluczy prywatnych/tokenów w kodzie po stronie klienta, który jest zawsze niepewne. W środowiskach testowych/przejściowych i produkcyjnych kod po stronie Blazor serwera i internetowe interfejsy API powinny używać bezpiecznych przepływów uwierzytelniania, które unikają utrzymywania poświadczeń w kodzie projektu lub plikach konfiguracji. Poza lokalnymi testami programistycznymi zalecamy unikanie używania zmiennych środowiskowych do przechowywania poufnych danych, ponieważ zmienne środowiskowe nie są najbezpieczniejszym podejściem. W przypadku lokalnego testowania programistycznego narzędzie Secret Manager jest zalecane do zabezpieczania poufnych danych. Aby uzyskać więcej informacji, zobacz Bezpieczne utrzymywanie poufnych danych i poświadczeń.
Identity Serwer z dodatkową AddApiAuthorization metodą pomocnika, która konfiguruje domyślne konwencje ASP.NET Core na serwerze Identity :
services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
Uwierzytelnianie za pomocą dodatkowej AddIdentityServerJwt metody pomocniczej, która konfiguruje aplikację do weryfikowania tokenów JWT utworzonych przez Identity serwer:
services.AddAuthentication() .AddIdentityServerJwt();
Uwaga
Po zarejestrowaniu jednego schematu uwierzytelniania schemat ten jest automatycznie używany jako domyślny schemat aplikacji i nie jest konieczne podanie go do AddAuthentication ani przez AuthenticationOptions. Aby uzyskać więcej informacji, zobacz Przegląd uwierzytelniania ASP.NET Core i Ogłoszenie ASP.NET Core (aspnet/Announcements #490).
- W pliku
Program
:
- W
Startup.Configure
pliku:Startup.cs
Middleware Identity serwera udostępnia punkty końcowe OpenID Connect (OIDC):
app.UseIdentityServer();
Oprogramowanie pośredniczące uwierzytelniania jest odpowiedzialne za weryfikowanie poświadczeń żądania i ustawianie użytkownika w kontekście żądania:
app.UseAuthentication();
Oprogramowanie pośredniczące autoryzacji umożliwia autoryzację:
app.UseAuthorization();
Autoryzacja interfejsu API
Ta sekcja dotyczy aplikacji rozwiązania Server .
Metoda AddApiAuthorization pomocnika konfiguruje Identity serwer dla scenariuszy ASP.NET Core. Identity Serwer to zaawansowana i rozszerzalna struktura do obsługi problemów z zabezpieczeniami aplikacji. Identity Serwer uwidacznia niepotrzebną złożoność w przypadku najbardziej typowych scenariuszy. W związku z tym zapewnia się zestaw konwencji i opcji konfiguracji, które uważamy za dobry punkt wyjścia. Po zmianie potrzeb związanych z uwierzytelnianiem pełna moc serwera Identity jest dostępna w celu dostosowania uwierzytelniania zgodnie z wymaganiami aplikacji.
Dodaj procedurę obsługi uwierzytelniania dla interfejsu API, który współistnieje z Identity serwerem
Ta sekcja dotyczy aplikacji rozwiązania Server .
Metoda AddIdentityServerJwt pomocnika konfiguruje schemat zasad dla aplikacji jako domyślną procedurę obsługi uwierzytelniania. Polityka jest skonfigurowana tak, aby umożliwić Identity obsługę wszystkich żądań kierowanych do dowolnej ścieżki podrzędnej w przestrzeni URL Identity pod /Identity
. Usługa JwtBearerHandler obsługuje wszystkie inne żądania. Ponadto ta metoda:
- Rejestruje zasób interfejsu API za pomocą Identity serwera z domyślnym zakresem
{PROJECT NAME}API
, gdzie{PROJECT NAME}
symbol zastępczy jest nazwą projektu podczas tworzenia aplikacji. - Konfiguruje pośredniczące oprogramowanie JWT Bearer Token do weryfikacji tokenów wystawionych przez Identity Server dla aplikacji.
Kontroler prognozy pogody
Ta sekcja dotyczy aplikacji rozwiązania Server .
W elemencie WeatherForecastController
(Controllers/WeatherForecastController.cs
) [Authorize]
atrybut zastosowano do klasy. Atrybut wskazuje, że użytkownik musi być autoryzowany na podstawie domyślnych zasad dostępu do zasobu. Domyślne zasady autoryzacji są skonfigurowane, aby używać domyślnego schematu uwierzytelniania, ustawionego przez AddIdentityServerJwt. Metoda pomocnika konfiguruje JwtBearerHandler jako domyślną obsługę żądań do aplikacji.
Kontekst bazy danych aplikacji
Ta sekcja dotyczy aplikacji rozwiązania Server .
W ApplicationDbContext
(Data/ApplicationDbContext.cs
), DbContext rozszerza ApiAuthorizationDbContext<TUser>, aby uwzględnić schemat dla serwera Identity.
ApiAuthorizationDbContext<TUser> pochodzi z IdentityDbContext.
Aby uzyskać pełną kontrolę nad schematem bazy danych, dziedzicz z jednej z dostępnych IdentityDbContext klas i skonfiguruj kontekst, aby uwzględnić schemat Identity przez wywołanie builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value)
w metodzie OnModelCreating.
Kontroler konfiguracji OIDC
Ta sekcja dotyczy aplikacji rozwiązania Server .
W OidcConfigurationController
(Controllers/OidcConfigurationController.cs
) punkt końcowy klienta jest konfigurowany do obsługi parametrów OIDC.
Ustawienia aplikacji
Ta sekcja dotyczy aplikacji rozwiązania Server .
W pliku ustawień aplikacji (appsettings.json
) w głównym katalogu projektu, sekcja IdentityServer
opisuje listę skonfigurowanych klientów. W poniższym przykładzie istnieje jeden klient. Nazwa klienta odpowiada Client nazwie zestawu aplikacji i jest mapowana zgodnie z konwencją do parametru OAuth ClientId
. Profil wskazuje skonfigurowany typ aplikacji. Profil jest używany wewnętrznie do określania konwencji, które upraszczają proces konfiguracji serwera.
"IdentityServer": {
"Clients": {
"{ASSEMBLY NAME}": {
"Profile": "IdentityServerSPA"
}
}
}
Symbol zastępczy {ASSEMBLY NAME}
jest nazwą zestawu aplikacji Client (na przykład BlazorSample.Client
).
Pakiet uwierzytelniania
Ta sekcja dotyczy aplikacji rozwiązania Client .
Po utworzeniu aplikacji do korzystania z indywidualnych kont użytkowników (Individual
) aplikacja automatycznie otrzymuje odwołanie do Microsoft.AspNetCore.Components.WebAssembly.Authentication
pakietu. Pakiet zawiera zestaw elementów pierwotnych, które ułatwiają aplikacji uwierzytelnianie użytkowników i uzyskiwanie tokenów w celu wywoływania chronionych interfejsów API.
W przypadku dodawania uwierzytelniania do aplikacji ręcznie dodaj Microsoft.AspNetCore.Components.WebAssembly.Authentication
pakiet do aplikacji.
Uwaga
Aby uzyskać instrukcje dodawania pakietów do aplikacji .NET, zobacz artykuły w sekcji Instalowanie pakietów i zarządzanie nimi w temacie Przepływ pracy użycia pakietów (dokumentacja programu NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.
HttpClient
konfiguracja
Ta sekcja dotyczy aplikacji rozwiązania Client .
W pliku Program
skonfigurowano element nazwany HttpClient, który dostarcza wystąpienia HttpClient zawierające tokeny dostępu podczas wysyłania żądań do interfejsu API serwera. W momencie tworzenia rozwiązania, nazwa HttpClient to {PROJECT NAME}.ServerAPI
, gdzie symbol zastępczy {PROJECT NAME}
oznacza nazwę projektu.
builder.Services.AddHttpClient("{PROJECT NAME}.ServerAPI",
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("{PROJECT NAME}.ServerAPI"));
Symbol {PROJECT NAME}
zastępczy to nazwa projektu podczas tworzenia rozwiązania. Na przykład podanie nazwy BlazorSample
projektu powoduje utworzenie nazwy HttpClientBlazorSample.ServerAPI
.
Uwaga
Jeśli konfigurujesz aplikację Blazor WebAssembly tak, aby korzystała z istniejącego wystąpienia serwera Identity, która nie jest częścią hostowanego rozwiązania Blazor, zmień rejestrację podstawowego adresu HttpClient z IWebAssemblyHostEnvironment.BaseAddress (builder.HostEnvironment.BaseAddress
) na adres URL punktu końcowego autoryzacji API serwera.
Obsługa autoryzacji interfejsu API
Ta sekcja dotyczy aplikacji rozwiązania Client .
Obsługa uwierzytelniania użytkowników jest podłączana do kontenera usług za pomocą metody rozszerzającej podaną wewnątrz pakietu Microsoft.AspNetCore.Components.WebAssembly.Authentication
. Ta metoda konfiguruje usługi wymagane przez aplikację do interakcji z istniejącym systemem autoryzacji.
builder.Services.AddApiAuthorization();
Konfiguracja aplikacji jest ładowana zgodnie z konwencją z _configuration/{client-id}
. Zgodnie z konwencją identyfikator klienta jest ustawiony na nazwę zestawu aplikacji. Ten adres URL można zmienić tak, aby wskazywał oddzielny punkt końcowy, wywołując przeciążenie za pomocą opcji.
Plik Imports
Ta sekcja dotyczy aplikacji rozwiązania Client .
Microsoft.AspNetCore.Components.Authorization Przestrzeń nazw jest udostępniana za pośrednictwem pliku _Imports.razor
w całej aplikacji.
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using {APPLICATION ASSEMBLY}
@using {APPLICATION ASSEMBLY}.Shared
Index
strona
Ta sekcja dotyczy aplikacji rozwiązania Client .
Strona Indeks (wwwroot/index.html
) zawiera skrypt, który definiuje element AuthenticationService
w języku JavaScript.
AuthenticationService
obsługuje szczegóły niskiego poziomu protokołu OIDC. Aplikacja wewnętrznie wywołuje metody zdefiniowane w skry skryptie w celu wykonania operacji uwierzytelniania.
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
App
komponent
Ta sekcja dotyczy aplikacji rozwiązania Client .
Składnik App
(App.razor
) jest podobny do składnika App
obecnego w Blazor Server aplikacjach.
- Składnik CascadingAuthenticationState odpowiada za udostępnianie AuthenticationState reszcie aplikacji.
- Składnik AuthorizeRouteView zapewnia, że bieżący użytkownik ma autoryzację dostępu do danej strony lub w inny sposób renderuje
RedirectToLogin
składnik. - Składnik
RedirectToLogin
zarządza przekierowywaniem nieautoryzowanych użytkowników do strony logowania.
Ze względu na zmiany w platformie pomiędzy wersjami ASP.NET Core, znaczniki dla składnika App
(App.razor
) nie są wyświetlane w tej sekcji. Aby sprawdzić znaczniki składnika dla danej wersji, użyj jednej z następujących metod:
Utwórz aplikację aprowizowaną do uwierzytelniania na podstawie domyślnego Blazor WebAssembly szablonu projektu dla wersji ASP.NET Core, która ma być używana.
App
Sprawdź składnik (App.razor
) w wygenerowanej aplikacji.App
Sprawdź składnik (App.razor
) w źródle referencyjnym. Wybierz wersję z selektora gałęzi i wyszukaj składnik wProjectTemplates
folderze repozytorium, ponieważApp
lokalizacja składnika zmieniła się na przestrzeni lat.Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
RedirectToLogin
komponent
Ta sekcja dotyczy aplikacji rozwiązania Client .
Składnik RedirectToLogin
(RedirectToLogin.razor
):
- Zarządza przekierowywaniem nieautoryzowanych użytkowników do strony logowania.
- Bieżący adres URL, do którego użytkownik próbuje uzyskać dostęp, jest zapisywany, aby możliwe było jego zwrócenie do tej strony po pomyślnym uwierzytelnieniu, używając:
- Stan historii nawigacji w programie ASP.NET Core na platformie .NET 7 lub nowszym.
- Ciąg zapytania w programie ASP.NET Core na platformie .NET 6 lub starszej wersji.
RedirectToLogin
Sprawdź składnik w źródle referencyjnym. Lokalizacja składnika zmieniła się wraz z upływem czasu, dlatego użyj narzędzi wyszukiwania GitHub, aby zlokalizować składnik.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
LoginDisplay
komponent
Ta sekcja dotyczy aplikacji rozwiązania Client .
Składnik LoginDisplay
(LoginDisplay.razor
) jest renderowany w składniku MainLayout
(MainLayout.razor
) i zarządza następującymi zachowaniami:
- W przypadku uwierzytelnionych użytkowników:
- Wyświetla bieżącą nazwę użytkownika.
- Oferuje link do strony profilu użytkownika w programie ASP.NET Core Identity.
- Oferuje przycisk wylogowania się z aplikacji.
- W przypadku użytkowników anonimowych:
- Oferuje opcję rejestracji.
- Oferuje opcję logowania.
Ze względu na zmiany w strukturze w wersjach ASP.NET Core, znaczniki dla komponentu LoginDisplay
nie są wyświetlane w tej sekcji. Aby sprawdzić znaczniki składnika dla danej wersji, użyj jednej z następujących metod:
Utwórz aplikację aprowizowaną do uwierzytelniania na podstawie domyślnego Blazor WebAssembly szablonu projektu dla wersji ASP.NET Core, która ma być używana. Sprawdź komponent
LoginDisplay
w wygenerowanej aplikacji.LoginDisplay
Sprawdź składnik w źródle referencyjnym. Lokalizacja składnika zmieniła się wraz z upływem czasu, dlatego użyj narzędzi wyszukiwania GitHub, aby zlokalizować składnik. Użyto szablonowej zawartości dlaHosted
, równejtrue
.Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Authentication
komponent
Ta sekcja dotyczy aplikacji rozwiązania Client .
Strona utworzona przez składnik Authentication
(Pages/Authentication.razor
) definiuje trasy wymagane do obsługi różnych etapów uwierzytelniania.
Składnik RemoteAuthenticatorView :
- Jest dostarczany przez
Microsoft.AspNetCore.Components.WebAssembly.Authentication
pakiet. - Zarządza wykonywaniem odpowiednich akcji na każdym etapie uwierzytelniania.
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action" />
@code {
[Parameter]
public string? Action { get; set; }
}
Uwaga
Typy referencyjne dopuszczające null (NRT) i statyczna analiza stanu zerowego kompilatora platformy .NET są obsługiwane w ASP.NET Core na platformie .NET 6 lub nowszej. Przed wydaniem ASP.NET Core na platformie .NET 6 typ string
pojawi się bez oznaczenia typu null (?
).
FetchData
komponent
Ta sekcja dotyczy aplikacji rozwiązania Client .
Składnik FetchData
pokazuje, jak:
- Aprowizuj token dostępu.
- Użyj tokenu dostępu, aby wywołać chroniony interfejs API zasobów w aplikacji Serwera .
Dyrektywa @attribute [Authorize]
wskazuje na Blazor WebAssembly system autoryzacji, że użytkownik musi być autoryzowany, aby uzyskać dostęp do tego składnika. Obecność atrybutu w Client
aplikacji nie uniemożliwia wywoływanie interfejsu API na serwerze bez odpowiednich poświadczeń. Aplikacja Server
musi również używać [Authorize]
w odpowiednich punktach końcowych, aby je prawidłowo chronić.
IAccessTokenProvider.RequestAccessToken Zajmuje się żądaniem tokenu dostępu, który można dodać do żądania w celu wywołania interfejsu API. Jeśli token jest buforowany lub usługa może aprowizować nowy token dostępu bez interakcji użytkownika, żądanie tokenu zakończy się pomyślnie. W przeciwnym razie żądanie tokenu kończy się niepowodzeniem, którego przyczyną jest element AccessTokenNotAvailableException, a zostaje on przechwycony w instrukcji try-catch
.
Aby uzyskać rzeczywisty token do uwzględnienia w żądaniu, aplikacja musi sprawdzić, czy żądanie zakończyło się pomyślnie, wywołując metodę tokenResult.TryGetToken(out var token)
.
Jeśli żądanie zakończyło się pomyślnie, zmienna tokenu zostanie wypełniona tokenem dostępu.
AccessToken.Value Właściwość tokenu udostępnia ciąg znaków do uwzględnienia w nagłówku żądania Authorization
.
Jeśli nie można aprowizować tokenu bez interakcji z użytkownikiem, co spowoduje niepowodzenie żądania:
- ASP.NET Core na platformie .NET 7 lub nowszym: aplikacja nawiguję do
AccessTokenResult.InteractiveRequestUrl
przy użyciu podanegoAccessTokenResult.InteractionOptions
, aby umożliwić odświeżenie tokenu dostępu. - ASP.NET Core na platformie .NET 6 lub starszej wersji: wynik tokenu zawiera adres URL przekierowania. Przejście do tego adresu URL powoduje przejście użytkownika do strony logowania i powrót do bieżącej strony po pomyślnym uwierzytelnieniu.
@page "/fetchdata"
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using {APP NAMESPACE}.Shared
@attribute [Authorize]
@inject HttpClient Http
...
@code {
private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
try
{
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("WeatherForecast");
}
catch (AccessTokenNotAvailableException exception)
{
exception.Redirect();
}
}
}
Usługa Azure App Service na Linuxie
Określ wystawcę jawnie podczas wdrażania w usłudze Azure App Service na systemie Linux. Aby uzyskać więcej informacji, zobacz Użyj Identity, aby zabezpieczyć zaplecze Web API dla SPA.
Nazwa i żądanie roli z autoryzacją API
Niestandardowa fabryka użytkowników
Client W aplikacji utwórz niestandardową fabrykę użytkowników.
Identity Serwer wysyła wiele ról jako tablicę JSON w jednym role
żądaniu. Pojedyncza rola jest wysyłana jako wartość string w żądaniu. Fabryka tworzy osobne role
roszczenie dla każdej z ról użytkownika.
CustomUserFactory.cs
:
using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal;
public class CustomUserFactory(IAccessTokenProviderAccessor accessor)
: AccountClaimsPrincipalFactory<RemoteUserAccount>(accessor)
{
public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
RemoteUserAccount account,
RemoteAuthenticationUserOptions options)
{
var user = await base.CreateUserAsync(account, options);
if (user.Identity is not null && user.Identity.IsAuthenticated)
{
var identity = (ClaimsIdentity)user.Identity;
var roleClaims = identity.FindAll(identity.RoleClaimType).ToArray();
if (roleClaims.Any())
{
foreach (var existingClaim in roleClaims)
{
identity.RemoveClaim(existingClaim);
}
var rolesElem =
account.AdditionalProperties[identity.RoleClaimType];
if (options.RoleClaim is not null && rolesElem is JsonElement roles)
{
if (roles.ValueKind == JsonValueKind.Array)
{
foreach (var role in roles.EnumerateArray())
{
var roleValue = role.GetString();
if (!string.IsNullOrEmpty(roleValue))
{
identity.AddClaim(
new Claim(options.RoleClaim, roleValue));
}
}
}
else
{
var roleValue = roles.GetString();
if (!string.IsNullOrEmpty(roleValue))
{
identity.AddClaim(
new Claim(options.RoleClaim, roleValue));
}
}
}
}
}
return user;
}
}
Client W aplikacji zarejestruj fabrykę w Program
pliku:
builder.Services.AddApiAuthorization()
.AddAccountClaimsPrincipalFactory<CustomUserFactory>();
W aplikacji wywołaj ServerAddRolesIdentity konstruktora, który dodaje usługi związane z rolami.
W pliku Program
:
using Microsoft.AspNetCore.Identity;
...
builder.Services.AddDefaultIdentity<ApplicationUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
W pliku Startup.cs
:
using Microsoft.AspNetCore.Identity;
...
services.AddDefaultIdentity<ApplicationUser>(options =>
options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Konfigurowanie Identity serwera
Użyj jednego z następujących podejść:
Opcje autoryzacji interfejsu API
Server W aplikacji:
- Skonfiguruj Identity serwer, aby umieścić
name
oświadczenia irole
w tokenie identyfikatora i tokenu dostępu. - Zapobiegaj domyślnemu mapowaniu ról w procedurze obsługi tokenów JWT.
W pliku Program
:
using System.IdentityModel.Tokens.Jwt;
...
builder.Services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
W pliku Startup.cs
:
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
...
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
Usługa profilu
Server W aplikacji utwórz implementacjęProfileService
.
ProfileService.cs
:
using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
public class ProfileService : IProfileService
{
public ProfileService()
{
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
context.IssuedClaims.AddRange(nameClaim);
var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
context.IssuedClaims.AddRange(roleClaims);
await Task.CompletedTask;
}
public async Task IsActiveAsync(IsActiveContext context)
{
await Task.CompletedTask;
}
}
W aplikacji Server zarejestruj Usługę Profili w pliku Program
.
using Duende.IdentityServer.Services;
...
builder.Services.AddTransient<IProfileService, ProfileService>();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
Server W aplikacji zarejestruj usługę profilu w Startup.ConfigureServices
pliku Startup.cs
:
using IdentityServer4.Services;
...
services.AddTransient<IProfileService, ProfileService>();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
Korzystanie z mechanizmów autoryzacji
Client W aplikacji podejścia autoryzacji składników działają w tym momencie. Dowolny z mechanizmów autoryzacji w składnikach może używać roli do autoryzowania użytkownika:
AuthorizeView
komponent (Przykład:<AuthorizeView Roles="Admin">
)[Authorize]
dyrektywa atrybutu (AuthorizeAttribute) (przykład:@attribute [Authorize(Roles = "Admin")]
)Logika proceduralna (przykład:
if (user.IsInRole("Admin")) { ... }
)Obsługiwane są wiele testów ról:
if (user.IsInRole("Admin") && user.IsInRole("Developer")) { ... }
User.Identity.Name
jest wypełniany w Client aplikacji nazwą użytkownika, czyli zazwyczaj adresem e-mail logowania.
UserManager
i SignInManager
Ustaw typ oświadczenia identyfikatora użytkownika, gdy jest to wymagane przez aplikację serwera.
- UserManager<TUser> lub SignInManager<TUser> w punkcie końcowym interfejsu API.
- IdentityUser szczegóły, takie jak nazwa użytkownika, adres e-mail lub godzina zakończenia blokady.
W Program.cs
dla ASP.NET Core w środowisku .NET 6 lub nowszym:
using System.Security.Claims;
...
builder.Services.Configure<IdentityOptions>(options =>
options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
W Startup.ConfigureServices
przypadku wersji ASP.NET Core starszych niż 6.0:
using System.Security.Claims;
...
services.Configure<IdentityOptions>(options =>
options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
Poniższe WeatherForecastController
rejestruje UserName, gdy wywoływana jest metoda Get
.
Uwaga
W poniższym przykładzie użyto:
- Przestrzeń nazw o zakresie plików, która jest cechą C# 10 lub nowszy (.NET 6 lub nowszy).
- Podstawowy konstruktor , który jest funkcją C# 12 lub nowszą (.NET 8 lub nowsza).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using BlazorSample.Server.Models;
using BlazorSample.Shared;
namespace BlazorSample.Server.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController(ILogger<WeatherForecastController> logger,
UserManager<ApplicationUser> userManager) : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm",
"Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet]
public async Task<IEnumerable<WeatherForecast>> Get()
{
var rng = new Random();
var user = await userManager.GetUserAsync(User);
if (user != null)
{
logger.LogInformation("User.Identity.Name: {UserIdentityName}", user.UserName);
}
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
W powyższym przykładzie:
-
Server
Przestrzeń nazw projektu toBlazorSample.Server
. -
Shared
Przestrzeń nazw projektu toBlazorSample.Shared
.
Hostowanie w usłudze Azure App Service z domeną niestandardową i certyfikatem
W poniższych wskazówkach wyjaśniono:
- Jak wdrożyć hostowaną aplikację Blazor WebAssembly z użyciem serwera Identity do usługi Azure App Service z niestandardową domeną.
- Jak utworzyć i używać certyfikatu TLS do komunikacji protokołu HTTPS z przeglądarkami. Chociaż wskazówki koncentrują się na korzystaniu z certyfikatu z domeną niestandardową, wskazówki mają również zastosowanie do używania domyślnej domeny aplikacji systemu Azure, na przykład
contoso.azurewebsites.net
.
W tym scenariuszu hostingu nie używaj tego samego certyfikatu dla klucza podpisującego token serwera Duende i bezpiecznej komunikacji HTTPS witryny z przeglądarkami:
- Używanie różnych certyfikatów dla tych dwóch wymagań jest dobrym rozwiązaniem w zakresie zabezpieczeń, ponieważ izoluje klucze prywatne do każdego celu.
- Certyfikaty TLS do komunikacji z przeglądarkami są zarządzane niezależnie, bez wpływu na podpisywanie tokenów przez serwer Identity.
- Gdy usługa Azure Key Vault dostarcza certyfikat do aplikacji usługi App Service na potrzeby powiązania domeny niestandardowej, Identity serwer nie może uzyskać tego samego certyfikatu z usługi Azure Key Vault na potrzeby podpisywania tokenów. Chociaż skonfigurowanie Identity serwera do używania tego samego certyfikatu TLS ze ścieżki fizycznej jest możliwe, umieszczenie certyfikatów zabezpieczeń w kontroli źródła jest złym rozwiązaniem i należy unikać go w większości scenariuszy.
W poniższych wskazówkach, w ramach Azure Key Vault, tworzony jest certyfikat samopodpisany wyłącznie do podpisywania tokenów serwera Identity. Konfiguracja Identity serwera używa certyfikatu skarbca kluczy za pośrednictwem magazynu certyfikatów aplikacji CurrentUser
>My
. Inne certyfikaty używane do ruchu HTTPS z domenami niestandardowymi są tworzone i konfigurowane oddzielnie od certyfikatu podpisywania Identity serwera.
Aby skonfigurować aplikację, usługę Azure App Service i Azure Key Vault do hostowania przy użyciu domeny niestandardowej i protokołu HTTPS:
Utwórz plan usługi App Service z planem na poziomie
Basic B1
lub wyższym. App Service wymaga warstwy usługiBasic B1
lub wyższej do korzystania z domen niestandardowych.Utwórz certyfikat PFX dla bezpiecznej komunikacji przeglądarki z witryną (protokół HTTPS) z nazwą wspólną pełnej kwalifikowanej nazwy domeny (FQDN), którą kontroluje twoja organizacja (na przykład
www.contoso.com
). Utwórz certyfikat za pomocą:- Kluczowe zastosowania
- Walidacja podpisu cyfrowego (
digitalSignature
) - Szyfrowanie klucza (
keyEncipherment
)
- Walidacja podpisu cyfrowego (
- Rozszerzone/ulepszone zastosowania kluczy
- Uwierzytelnianie klienta (1.3.6.1.5.5.7.3.2)
- Uwierzytelnianie serwera (1.3.6.1.5.5.7.3.1)
Aby utworzyć certyfikat, użyj jednego z następujących metod lub innego odpowiedniego narzędzia lub usługi online:
Zanotuj hasło, które jest później używane do importowania certyfikatu do usługi Azure Key Vault.
Aby uzyskać więcej informacji na temat certyfikatów usługi Azure Key Vault, zobacz Usługa Azure Key Vault: certyfikaty.
- Kluczowe zastosowania
Utwórz nową usługę Azure Key Vault lub użyj istniejącego magazynu kluczy w ramach subskrypcji platformy Azure.
W obszarze Certyfikaty magazynu kluczy, zaimportuj certyfikat witryny PFX. Zarejestruj odcisk palca certyfikatu, który jest używany w konfiguracji aplikacji później.
W usłudze Azure Key Vault wygeneruj nowy certyfikat z podpisem własnym na potrzeby Identity podpisywania tokenu serwera. Nadaj certyfikatowi nazwę certyfikatu i podmiot. Podmiot jest ustawiony jako
CN={COMMON NAME}
, gdzie{COMMON NAME}
symbol zastępczy jest nazwą wspólną certyfikatu. Nazwa pospolita może być dowolnym ciągiem alfanumerycznym. Na przykładCN=IdentityServerSigning
jest prawidłowym podmiotem certyfikatu. W Zasadach Wystawiania>Zaawansowana Konfiguracja Zasad użyj ustawień domyślnych. Zarejestruj odcisk palca certyfikatu, który jest używany w konfiguracji aplikacji później.Przejdź do usługi aplikacja systemu Azure w witrynie Azure Portal i utwórz nową usługę App Service z następującą konfiguracją:
-
Opublikowanie ustawiono na
Code
. - Stos środowiska uruchomieniowego przypisany do środowiska uruchomieniowego aplikacji.
- W przypadku jednostki SKU i rozmiaru upewnij się, że poziom usługi App Service jest
Basic B1
lub wyższy. Usługa App Service wymaga warstwy usługiBasic B1
lub wyższej do korzystania z domen niestandardowych.
-
Opublikowanie ustawiono na
Po utworzeniu usługi App Service przez platformę Azure otwórz konfigurację aplikacji i dodaj nowe ustawienie aplikacji określające zarejestrowane wcześniej odciski palca certyfikatu. Klucz ustawień aplikacji to
WEBSITE_LOAD_CERTIFICATES
. Rozdziel odciski palca certyfikatu w polu ustawień aplikacji przecinkiem, jak pokazano w poniższym przykładzie.- Klucz:
WEBSITE_LOAD_CERTIFICATES
- Wartość:
57443A552A46DB...D55E28D412B943565,29F43A772CB6AF...1D04F0C67F85FB0B1
W portalu Azure zapisywanie ustawień aplikacji jest procesem dwuetapowym: zapisz ustawienie klucz-wartość
WEBSITE_LOAD_CERTIFICATES
, a następnie wybierz przycisk Zapisz w górnej części panelu.- Klucz:
Wybierz ustawienia protokołu TLS/SSL aplikacji. Wybierz pozycję Certyfikaty klucza prywatnego (format .pfx). Użyj procesu Importowanie certyfikatu Key Vault. Użyj procesu dwa razy, aby zaimportować zarówno certyfikat witryny na potrzeby komunikacji HTTPS, jak i certyfikat podpisywania tokenów serwera, wystawiony przez witrynę działającą jako urząd certyfikacji.
Przejdź do strony Domeny niestandardowe. Na stronie internetowej rejestratora domen użyj adresu IP i identyfikatora weryfikacji niestandardowej domeny, aby skonfigurować domenę. Typowa konfiguracja domeny obejmuje:
-
Rekord A z Hostem
@
i wartością adresu IP z portalu Azure. -
Rekord TXT z Hostem jako
asuid
i wartością identyfikatora weryfikacji wygenerowanego przez platformę Azure i udostępnionego przez portal Azure.
Upewnij się, że zmiany są zapisywane poprawnie w witrynie internetowej rejestratora domen. Niektóre witryny rejestratorów wymagają dwuetapowego procesu przy zapisywaniu rekordów domeny: najpierw jeden lub więcej rekordów jest zapisywanych indywidualnie, a następnie rejestracja domeny jest aktualizowana za pomocą oddzielnego przycisku.
-
Rekord A z Hostem
Wróć do panelu Domeny niestandardowe w portalu Azure. Wybierz pozycję Dodaj domenę niestandardową. Wybierz opcję Rekord A. Podaj domenę i wybierz pozycję Weryfikuj. Jeśli rekordy domeny są poprawne i propagowane przez Internet, portal umożliwia wybranie przycisku Dodaj domenę niestandardową.
Propagacja zmian rejestracji domeny na serwerach nazw domen internetowych (DNS) po przetworzeniu ich przez rejestratora domen może potrwać kilka dni. Jeśli rekordy domeny nie są aktualizowane w ciągu trzech dni roboczych, upewnij się, że rekordy są poprawnie ustawione u rejestratora domen i skontaktuj się z pomocą techniczną.
W bloku Domeny niestandardowe stan SSL dla domeny jest oznaczony jako
Not Secure
. Wybierz link Dodaj powiązanie. Wybierz certyfikat HTTPS witryny z magazynu kluczy dla wiązania domeny niestandardowej.W programie Visual Studio otwórz plik ustawień aplikacji projektu Server (
appsettings.json
lubappsettings.Production.json
). Identity W konfiguracji serwera dodaj następującąKey
sekcję. Określ samopodpisany certyfikat Podmiot dlaName
klucza. W poniższym przykładzie nazwa główna certyfikatu przypisana w magazynie kluczy to, co daje podmiot : "IdentityServer": { ... "Key": { "Type": "Store", "StoreName": "My", "StoreLocation": "CurrentUser", "Name": "CN=IdentityServerSigning" } },
W programie Visual Studio utwórz profil publikowania usługi App Service Azure dla projektu Server. Na pasku menu wybierz: Build>Publikuj>Nowa>Azure>Azure App Service (Windows lub Linux). Gdy program Visual Studio jest połączony z subskrypcją platformy Azure, możesz ustawić widok zasobów platformy Azure według typu zasobu. Przejdź do listy Web App, aby znaleźć App Service dla aplikacji i ją wybrać. Wybierz Zakończ.
Gdy program Visual Studio powróci do okna Publikowanie , zostaną automatycznie wykryte zależności magazynu kluczy i usługi bazy danych programu SQL Server.
Dla usługi Key Vault nie są wymagane żadne zmiany konfiguracji ustawień domyślnych.
Do celów testowych lokalną bazę danych SQLite aplikacji, skonfigurowaną przez Blazor szablon, można wdrożyć wraz z aplikacją bez dodatkowej konfiguracji. Konfigurowanie innej bazy danych dla Identity serwera w środowisku produkcyjnym wykracza poza zakres tego artykułu. Aby uzyskać więcej informacji, zobacz zasoby bazy danych w następujących zestawach dokumentacji:
Wybierz link Edytuj poniżej nazwy profilu wdrożenia na górze okna. Zmień docelowy adres URL na adres URL domeny niestandardowej witryny (na przykład
https://www.contoso.com
). Zapisz ustawienia.Opublikuj aplikację. Program Visual Studio otwiera okno przeglądarki i próbuje uzyskać dostęp do witryny na jej niestandardowej domenie.
Dokumentacja platformy Azure zawiera dodatkowe szczegóły dotyczące korzystania z usług platformy Azure i domen niestandardowych z powiązaniem TLS w usłudze App Service, w tym informacje na temat używania rekordów CNAME zamiast rekordów A. Aby uzyskać więcej informacji, zobacz następujące zasoby:
- Dokumentacja usługi App Service
- Poradnik: Jak przypisać istniejącą niestandardową nazwę DNS do usługi Azure App Service
- Zabezpiecz niestandardową nazwę DNS przy użyciu powiązania TLS/SSL w Azure App Service
- Azure Key Vault
Zalecamy użycie nowego okna przeglądarki trybu prywatnego (na przykład trybu InPrivate przeglądarki Microsoft Edge lub trybu Incognito w przeglądarce Google Chrome) dla każdego testu aplikacji po zmianie aplikacji, konfiguracji aplikacji lub usług platformy Azure w witrynie Azure Portal. Utrzymujące się pliki cookie z poprzedniego przebiegu testu mogą spowodować niepowodzenie uwierzytelniania lub autoryzacji podczas testowania witryny nawet wtedy, gdy konfiguracja witryny jest poprawna. Aby uzyskać więcej informacji na temat konfigurowania programu Visual Studio w celu otwarcia nowego okna przeglądarki prywatnej dla każdego przebiegu testu, zobacz sekcję Pliki cookie i dane witryny.
Gdy konfiguracja usługi App Service zostanie zmieniona w witrynie Azure Portal, aktualizacje będą obowiązywać szybko, ale nie są natychmiastowe. Czasami należy poczekać krótki okres na ponowne uruchomienie usługi App Service w celu wprowadzenia zmiany konfiguracji.
Jeśli napotkasz problem z ładowaniem CurrentUser
>My
magazynu certyfikatów. Dane wyjściowe obejmują podmioty certyfikatu i odciski palca przydatne podczas debugowania aplikacji:
Get-ChildItem -path Cert:\CurrentUser\My -Recurse | Format-List DnsNameList, Subject, Thumbprint, EnhancedKeyUsageList
Rozwiązywanie problemów
Rejestrowanie
Aby włączyć rejestrowanie debugowania lub śledzenia uwierzytelniania dla Blazor WebAssembly, zobacz sekcję Rejestrowanie uwierzytelniania po stronie klienta w ASP.NET Core Blazor logging, z selektorem wersji artykułu ustawionym na ASP.NET Core 7.0 lub nowszym.
Typowe błędy
Błędna konfiguracja aplikacji lub Identity dostawcy (IP)
Najczęstsze błędy są spowodowane nieprawidłową konfiguracją. Poniżej przedstawiono kilka przykładów:
- W zależności od wymagań scenariusza brakujący lub niepoprawny organ, instancja, identyfikator dzierżawy, domena dzierżawy, klienta lub identyfikator URI przekierowania uniemożliwia aplikacji uwierzytelnianie klientów.
- Nieprawidłowe zakresy żądań uniemożliwiają klientom uzyskiwanie dostępu do punktów końcowych internetowego interfejsu API serwera.
- Nieprawidłowe lub brakujące uprawnienia interfejsu API serwera uniemożliwiają klientom uzyskiwanie dostępu do punktów końcowych internetowego interfejsu API serwera.
- Uruchamianie aplikacji na innym porcie niż ten skonfigurowany w URI przekierowania podczas rejestracji aplikacji dla adresu IP. Należy pamiętać, że port nie jest wymagany dla identyfikatora Microsoft Entra ID i aplikacji działającej na adresie testowym programowania
localhost
, ale konfiguracja portu aplikacji i port, na którym działa aplikacja, musi być zgodna z adresami innymi niżlocalhost
.
Sekcje konfiguracji tego artykułu zawierają przykłady prawidłowej konfiguracji. Dokładnie sprawdź każdą sekcję artykułu, aby wyszukać błędną konfigurację aplikacji i adresu IP.
Jeśli konfiguracja jest poprawna:
Analizowanie dzienników aplikacji.
Sprawdź ruch sieciowy między aplikacją kliencka a adresem IP lub aplikacją serwera przy użyciu narzędzi deweloperskich przeglądarki. Często dokładny komunikat o błędzie lub komunikat zawierający wskazówki dotyczące przyczyn problemu jest zwracany do klienta przez adres IP lub aplikację serwera po wykonaniu żądania. Wskazówki dotyczące narzędzi programistycznych można znaleźć w następujących artykułach:
- Google Chrome (dokumentacja Google)
- Microsoft Edge
- Mozilla Firefox (dokumentacja Mozilla)
W przypadku wersji Blazor , w których jest używany token internetowy JSON (JWT), zdekoduj zawartość tokenu używanego do uwierzytelniania klienta lub uzyskiwania dostępu do internetowego interfejsu API serwera, w zależności od tego, gdzie występuje problem. Aby uzyskać więcej informacji, zobacz Inspekcja zawartości tokenu internetowego JSON (JWT).
Zespół dokumentacji odpowiada na opinie dotyczące dokumentów i błędy w artykułach (utwórz zgłoszenie z sekcji opinii na tej stronie), ale nie może zapewnić wsparcia technicznego produktów. Dostępnych jest kilka publicznych forów pomocy technicznej, które ułatwiają rozwiązywanie problemów z aplikacją. Zalecamy:
Poprzednie fora nie należą do firmy Microsoft ani nie są kontrolowane przez firmę Microsoft.
W przypadku raportów błędów dotyczących struktury, które nie są związane z bezpieczeństwem, nie są wrażliwe i nie są poufne, zgłoś problem w jednostce produktu ASP.NET Core. Nie otwieraj problemu z jednostką produktu, dopóki nie zbadasz dokładnie przyczyny problemu i nie możesz go rozwiązać samodzielnie i z pomocą społeczności na publicznym forum pomocy technicznej. Jednostka produktu nie może rozwiązywać problemów z poszczególnymi aplikacjami, które są uszkodzone z powodu prostej błędnej konfiguracji lub przypadków użycia obejmujących usługi innych firm. Jeśli raport jest poufny lub poufny lub opisuje potencjalną lukę w zabezpieczeniach produktu, którą mogą wykorzystać cyberataki, zobacz Raportowanie problemów z zabezpieczeniami i usterek (
dotnet/aspnetcore
repozytorium GitHub).Nieautoryzowany klient dla ME-ID
info: Autoryzacja Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] nie powiodła się. Te wymagania nie zostały spełnione: DenyAnonymousAuthorizationRequirement: Wymaga uwierzytelnionego użytkownika.
Błąd wywołania zwrotnego logowania z identyfikatora ME-ID:
- Błąd:
unauthorized_client
- Opis:
AADB2C90058: The provided application is not configured to allow public clients.
Aby naprawić ten błąd:
- W witrynie Azure Portal uzyskaj dostęp do manifestu aplikacji.
-
allowPublicClient
Ustaw atrybut nanull
lubtrue
.
- Błąd:
Pliki cookie i dane witryn
Pliki cookie i dane witryn mogą być utrwalane w aktualizacjach aplikacji i zakłócać testowanie i rozwiązywanie problemów. Wyczyść następujące informacje podczas wprowadzania zmian w kodzie aplikacji, zmiany konta użytkownika w dostawcy lub zmiany konfiguracji aplikacji dostawcy:
- Pliki cookie logowania użytkownika
- Pliki cookie aplikacji
- Buforowane i przechowywane dane lokacji
Jedną z metod zapobiegania wpływowi utrzymujących się plików cookie i danych witryny na testowanie i rozwiązywanie problemów jest:
- Konfigurowanie przeglądarki
- Użyj przeglądarki do testowania, którą można skonfigurować do usuwania wszystkich cookie i danych witryny za każdym razem, gdy przeglądarka jest zamykana.
- Upewnij się, że przeglądarka jest zamknięta ręcznie lub przez środowisko IDE w celu zmiany konfiguracji aplikacji, użytkownika testowego lub dostawcy.
- Użyj polecenia niestandardowego, aby otworzyć przeglądarkę w trybie InPrivate lub Incognito w programie Visual Studio:
- Otwórz okno dialogowe Przeglądaj za pomocą z przycisku Uruchom programu Visual Studio.
- Kliknij przycisk Dodaj.
- Podaj ścieżkę do przeglądarki w polu Program . Następujące ścieżki wykonywalne to typowe lokalizacje instalacji systemu Windows 10. Jeśli przeglądarka jest zainstalowana w innej lokalizacji lub nie używasz systemu Windows 10, podaj ścieżkę do pliku wykonywalnego przeglądarki.
- 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:
-
W polu Argumenty podaj opcję wiersza polecenia używaną przez przeglądarkę do otwierania w trybie InPrivate lub Incognito. Niektóre przeglądarki wymagają adresu URL aplikacji.
- Microsoft Edge: Użyj
-inprivate
. - Google Chrome: użyj symboli
--incognito --new-window {URL}
, gdzie symbol zastępczy to adres URL do otwarcia (na przykładhttps://localhost:5001
). - Mozilla Firefox: użyj
-private -url {URL}
, gdzie element zastępczy{URL}
to adres URL do otwarcia (na przykładhttps://localhost:5001
).
- Microsoft Edge: Użyj
- Podaj nazwę w polu Przyjazna nazwa . Na przykład
Firefox Auth Testing
. - Wybierz przycisk OK.
- Aby uniknąć konieczności wybierania profilu przeglądarki dla każdej iteracji testowania za pomocą aplikacji, ustaw profil jako domyślny przy użyciu przycisku Ustaw jako domyślny .
- Upewnij się, że przeglądarka jest zamknięta przez środowisko IDE w celu zmiany konfiguracji aplikacji, użytkownika testowego lub dostawcy.
Uaktualnienia aplikacji
Działająca aplikacja może zakończyć się niepowodzeniem natychmiast po uaktualnieniu zestawu .NET Core SDK na komputerze deweloperskim lub zmianie wersji pakietów w aplikacji. W niektórych przypadkach niespójne pakiety mogą spowodować przerwanie aplikacji podczas przeprowadzania głównych uaktualnień. Większość z tych problemów można rozwiązać, wykonując następujące instrukcje:
- Wyczyść pamięć podręczną pakietów NuGet systemu lokalnego, wykonując
dotnet nuget locals all --clear
w terminalu. - Usuń foldery
bin
iobj
projektu. - Przywróć i przebuduj projekt.
- Usuń wszystkie pliki w folderze wdrażania na serwerze przed ponownym wdrożeniem aplikacji.
Uwaga
Korzystanie z wersji pakietów niezgodnych z platformą docelową aplikacji nie jest obsługiwane. Aby uzyskać informacje na temat pakietu, użyj galerii NuGet lub Eksploratora pakietów FuGet.
Server
Uruchamianie aplikacji
Podczas testowania i rozwiązywania problemów z hostowanym Blazor WebAssemblyrozwiązaniem upewnij się, że używasz aplikacji z Server
projektu.
Sprawdzanie użytkownika
Poniższy User
składnik może być używany bezpośrednio w aplikacjach lub służyć jako podstawa dalszego dostosowywania.
User.razor
:
@page "/user"
@attribute [Authorize]
@using System.Text.Json
@using System.Security.Claims
@inject IAccessTokenProvider AuthorizationService
<h1>@AuthenticatedUser?.Identity?.Name</h1>
<h2>Claims</h2>
@foreach (var claim in AuthenticatedUser?.Claims ?? Array.Empty<Claim>())
{
<p class="claim">@(claim.Type): @claim.Value</p>
}
<h2>Access token</h2>
<p id="access-token">@AccessToken?.Value</p>
<h2>Access token claims</h2>
@foreach (var claim in GetAccessTokenClaims())
{
<p>@(claim.Key): @claim.Value.ToString()</p>
}
@if (AccessToken != null)
{
<h2>Access token expires</h2>
<p>Current time: <span id="current-time">@DateTimeOffset.Now</span></p>
<p id="access-token-expires">@AccessToken.Expires</p>
<h2>Access token granted scopes (as reported by the API)</h2>
@foreach (var scope in AccessToken.GrantedScopes)
{
<p>Scope: @scope</p>
}
}
@code {
[CascadingParameter]
private Task<AuthenticationState> AuthenticationState { get; set; }
public ClaimsPrincipal AuthenticatedUser { get; set; }
public AccessToken AccessToken { get; set; }
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
var state = await AuthenticationState;
var accessTokenResult = await AuthorizationService.RequestAccessToken();
if (!accessTokenResult.TryGetToken(out var token))
{
throw new InvalidOperationException(
"Failed to provision the access token.");
}
AccessToken = token;
AuthenticatedUser = state.User;
}
protected IDictionary<string, object> GetAccessTokenClaims()
{
if (AccessToken == null)
{
return new Dictionary<string, object>();
}
// header.payload.signature
var payload = AccessToken.Value.Split(".")[1];
var base64Payload = payload.Replace('-', '+').Replace('_', '/')
.PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=');
return JsonSerializer.Deserialize<IDictionary<string, object>>(
Convert.FromBase64String(base64Payload));
}
}
Sprawdzanie zawartości tokenu internetowego JSON (JWT)
Aby zdekodować token internetowy JSON (JWT), użyj narzędzia jwt.ms firmy Microsoft. Wartości w interfejsie użytkownika nigdy nie opuszczają przeglądarki.
Przykład zakodowany JWT (skrócony do wyświetlania):
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q
Przykładowy kod JWT dekodowany przez narzędzie dla aplikacji, która uwierzytelnia się w usłudze Azure AAD B2C:
{
"typ": "JWT",
"alg": "RS256",
"kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"
}.{
"exp": 1610059429,
"nbf": 1610055829,
"ver": "1.0",
"iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
"sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
"aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
"nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
"iat": 1610055829,
"auth_time": 1610055822,
"idp": "idp.com",
"tfp": "B2C_1_signupsignin"
}.[Signature]
Dodatkowe zasoby
- Wdrażanie do usługi Azure App Service
- Importowanie certyfikatu z usługi Key Vault (dokumentacja platformy Azure)
- Dodatkowe scenariusze zabezpieczeń dotyczące platformy ASP.NET Core Blazor WebAssembly
- Nieuwierzytelnione lub nieautoryzowane żądania internetowego interfejsu API w aplikacji z bezpiecznym klientem domyślnym
-
Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia: zawiera wskazówki dotyczące:
- Używanie oprogramowania pośredniczącego nagłówków przekazywanych w celu zachowania informacji o schemacie HTTPS między serwerami proxy i sieciami wewnętrznymi.
- Dodatkowe scenariusze i przypadki użycia, w tym ręczna konfiguracja schematu, żądanie zmiany ścieżki żądania na potrzeby prawidłowego routingu żądań i przekazywanie schematu żądań dla zwrotnych serwerów proxy systemu Linux i innych niż IIS.
- Serwer Duende Identity