Delen via


Een gehoste ASP.NET Core Blazor WebAssembly-app beveiligen met Identity Server

Belangrijk

De gehoste Blazor WebAssembly projectsjabloon is verwijderd uit het framework met de release van .NET 8 (november 2023). De richtlijnen in dit artikel worden alleen ondersteund voor .NET 7 of eerder. Gehoste Blazor WebAssembly-apps die voor elke release worden bijgewerkt, blijven productondersteuning ontvangen. U kunt de app ook herstructureren in een zelfstandige Blazor WebAssembly-app of een Blazor Web App.

In dit artikel wordt uitgelegd hoe u een gehoste Blazor WebAssembly-oplossing maakt die gebruikmaakt van Duende Identity Server voor het verifiëren van gebruikers en API-aanroepen.

Belangrijk

Duende Software moet u mogelijk een licentiekosten betalen voor productiegebruik van Duende Identity Server. Zie Migreren van ASP.NET Core 5.0 naar 6.0voor meer informatie.

Notitie

Als u een zelfstandige of gehoste Blazor WebAssembly-app wilt configureren voor het gebruik van een bestaand, extern Identity Server-exemplaar, volgt u de richtlijnen in Een zelfstandige ASP.NET Core Blazor WebAssembly-app beveiligen met de verificatiebibliotheek.

Zie ASP.NET Core Blazor WebAssembly aanvullende beveiligingsscenario'svoor aanvullende dekking van beveiligingsscenario's na het lezen van dit artikel.

Stapsgewijze handleiding

In de subsecties van het overzicht wordt uitgelegd hoe u het volgende kunt doen:

  • De Blazor-app maken
  • De app uitvoeren

Een Blazor-app maken

Een nieuw Blazor WebAssembly-project maken met een verificatiemechanisme:

  1. Maak een nieuw project.

  2. Kies de sjabloon Blazor WebAssembly App. Selecteer Volgende.

  3. Geef een projectnaam op zonder streepjes te gebruiken. Controleer of de Locatie juist is. Selecteer Volgende.

    Vermijd het gebruik van streepjes (-) in de projectnaam die de vorming van de OIDC-app-id verbreken. Logica in het Blazor WebAssembly-projectsjabloon gebruikt de projectnaam als een OIDC-app-identificator in de configuratie van de oplossing, en streepjes zijn niet toegestaan in een OIDC-app-identificator. Pascal case (BlazorSample) ofwel onderstrepingstekens (Blazor_Sample) zijn acceptabele alternatieven.

  4. Selecteer in het dialoogvenster Aanvullende informatieIndividuele accounts als het authenticatietype om gebruikers in de app op te slaan met behulp van het systeem voor ASP.NET Core Identity.

  5. Selecteer het selectievakje ASP.NET Core Hosted.

  6. Klik op de knop Create om de app te maken.

De app uitvoeren

Voer de app uit vanuit het Server-project. Wanneer u Visual Studio gebruikt, kunt u het volgende doen:

  • Selecteer de vervolgkeuzepijl naast de knop Uitvoeren. Open Configureer opstartprojecten uit de vervolgkeuzelijst. Selecteer de optie enkelvoudig opstartproject. Bevestig of verander het project voor het startproject naar project Server.

  • Controleer of het Server project is gemarkeerd in Solution Explorer- voordat u de app start met een van de volgende methoden:

    • Selecteer de knop Uitvoeren.
    • Gebruik Foutopsporing>Start Debugging in het menu.
    • Druk op F5-.
  • Navigeer in een opdrachtshell naar de Server projectmap van de oplossing. Voer de opdracht dotnet watch (of dotnet run) uit.

Onderdelen van de oplossing

In deze sectie worden de onderdelen van een oplossing beschreven die is gegenereerd op basis van de Blazor WebAssembly projectsjabloon en wordt beschreven hoe de Client- en Server-projecten van de oplossing zijn geconfigureerd voor referentie. Er zijn geen specifieke richtlijnen die u in deze sectie kunt volgen voor een basiswerktoepassing als u de app hebt gemaakt met behulp van de richtlijnen in de sectie Walkthrough. De richtlijnen in deze sectie zijn handig voor het bijwerken van een app om gebruikers te verifiëren en te autoriseren. Een alternatieve benadering voor het bijwerken van een app is echter om een nieuwe app te maken op basis van de richtlijnen in de sectie walkthrough en het verplaatsen van de onderdelen, klassen en resources van de app naar de nieuwe app.

Server app-services

Deze sectie heeft betrekking op de Server-app van de oplossing.

De volgende services zijn geregistreerd.

  • In het bestand Program:

    • Entity Framework Core en 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 Server met een extra AddApiAuthorization helpermethode waarmee standaardconventies voor ASP.NET Core worden ingesteld boven op Identity Server:

      builder.Services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Verificatie met een extra AddIdentityServerJwt helpermethode waarmee de app wordt geconfigureerd voor het valideren van JWT-tokens die worden geproduceerd door Identity Server:

      builder.Services.AddAuthentication()
          .AddIdentityServerJwt();
      
  • In Startup.ConfigureServices van Startup.cs:

    • Entity Framework Core en ASP.NET Core Identity:

      services.AddDbContext<ApplicationDbContext>(options =>
          options.UseSqlite(
              Configuration.GetConnectionString("DefaultConnection")));
      
      services.AddDefaultIdentity<ApplicationUser>(options => 
              options.SignIn.RequireConfirmedAccount = true)
          .AddEntityFrameworkStores<ApplicationDbContext>();
      

      Waarschuwing

      Sla geen app-geheimen, verbindingsreeksen, referenties, wachtwoorden, persoonlijke identificatienummers (PINCODE's), persoonlijke C#/.NET-code of persoonlijke sleutels/tokens op in code aan de clientzijde. Dit is altijd onveilig. In test-/staging- en productieomgevingen moeten aan de serverzijde van Blazor code en web-API's beveiligde authenticatiestromen gebruiken die vermijden dat referenties in projectcode of configuratiebestanden worden opgeslagen. Buiten het testen van lokale ontwikkeling raden we u aan het gebruik van omgevingsvariabelen voor het opslaan van gevoelige gegevens te vermijden, omdat omgevingsvariabelen niet de veiligste benadering zijn. Voor het testen van lokale ontwikkeling wordt het hulpprogramma Secret Manager aanbevolen voor het beveiligen van gevoelige gegevens. Zie Gevoelige gegevens en referenties veilig onderhoudenvoor meer informatie.

    • Identity Server met een extra AddApiAuthorization helpermethode waarmee standaardconventies voor ASP.NET Core worden ingesteld boven op Identity Server:

      services.AddIdentityServer()
          .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
      
    • Verificatie met een extra AddIdentityServerJwt helpermethode waarmee de app wordt geconfigureerd voor het valideren van JWT-tokens die worden geproduceerd door Identity Server:

      services.AddAuthentication()
          .AddIdentityServerJwt();
      

Notitie

Wanneer één verificatieschema is geregistreerd, wordt het verificatieschema automatisch gebruikt als het standaardschema van de app en hoeft het schema niet te worden opgegeven voor AddAuthentication of via AuthenticationOptions. Zie Overzicht van ASP.NET Core Authentication en de ASP.NET Core-aankondiging (aspnet/Aankondigingen #490)voor meer informatie.

  • In het bestand Program:
  • In Startup.Configure van Startup.cs:
  • De Identity Server Middleware maakt de OpenID Connect-eindpunten (OIDC) beschikbaar:

    app.UseIdentityServer();
    
  • De verificatie-middleware is verantwoordelijk voor het valideren van aanvraagreferenties en het instellen van de gebruiker in de aanvraagcontext:

    app.UseAuthentication();
    
  • Autorisatie-middleware maakt autorisatiemogelijkheden mogelijk:

    app.UseAuthorization();
    

API-autorisatie

Deze sectie heeft betrekking op de Server-app van de oplossing.

De helpermethode AddApiAuthorization configureert Identity Server- voor ASP.NET Core-scenario's. Identity Server is een krachtig en uitbreidbaar framework voor het afhandelen van problemen met app-beveiliging. Identity Server maakt onnodige complexiteit beschikbaar voor de meest voorkomende scenario's. Daarom wordt er een set conventies en configuratieopties geboden die we als een goed uitgangspunt beschouwen. Zodra uw verificatiebehoeften zijn gewijzigd, is de volledige kracht van Identity Server beschikbaar om verificatie aan te passen aan de vereisten van een app.

Een verificatiehandler toevoegen voor een API die naast Identity Server wordt gebruikt

Deze sectie heeft betrekking op de Server-app van de oplossing.

De AddIdentityServerJwt helpermethode configureert een beleidsschema voor de app als standaardverificatiehandler. Het beleid is zo geconfigureerd dat Identity alle aanvragen kan verwerken die worden doorgestuurd naar een subpad in de Identity URL-ruimte onder /Identity. De JwtBearerHandler verwerkt alle andere aanvragen. Bovendien werkt deze methode als volgt:

  • Registreert een API-resource bij Identity Server met een standaardbereik van {PROJECT NAME}API, waarbij de tijdelijke aanduiding {PROJECT NAME} de naam van het project is bij het maken van de app.
  • Hiermee configureert u de JWT Bearer Token Middleware om tokens te valideren die zijn uitgegeven door Identity Server voor de app.

Weersvoorspellingscontroller

Deze sectie heeft betrekking op de Server-app van de oplossing.

In de WeatherForecastController (Controllers/WeatherForecastController.cs) wordt het [Authorize] kenmerk toegepast op de klasse. Het kenmerk geeft aan dat de gebruiker moet worden geautoriseerd op basis van het standaardbeleid voor toegang tot de resource. Het standaardautorisatiebeleid is geconfigureerd voor het gebruik van het standaardverificatieschema, dat is ingesteld door AddIdentityServerJwt. De helpermethode configureert JwtBearerHandler als de standaardhandler voor aanvragen voor de app.

Context van toepassingsdatabase

Deze sectie heeft betrekking op de Server-app van de oplossing.

In de ApplicationDbContext (Data/ApplicationDbContext.cs) breidt DbContextApiAuthorizationDbContext<TUser> uit om het schema voor Identity Server op te nemen. ApiAuthorizationDbContext<TUser> is afgeleid van IdentityDbContext.

Als u het databaseschema volledig wilt beheren, neemt u de gegevens over van een van de beschikbare IdentityDbContext klassen en configureert u de context om het Identity schema op te nemen door builder.ConfigurePersistedGrantContext(_operationalStoreOptions.Value) aan te roepen in de OnModelCreating methode.

OIDC-configuratiecontroller

Deze sectie heeft betrekking op de Server-app van de oplossing.

In de OidcConfigurationController (Controllers/OidcConfigurationController.cs) is het klantendpunt geconfigureerd om OIDC-parameters te dienen.

App-instellingen

Deze sectie heeft betrekking op de Server-app van de oplossing.

In het bestand met app-instellingen (appsettings.json) in de hoofdmap van het project wordt in de sectie IdentityServer de lijst met geconfigureerde clients beschreven. In het volgende voorbeeld is er één client. De clientnaam komt overeen met de assemblynaam van de Client-app en wordt standaard toegewezen aan de parameter OAuth ClientId. Het profiel geeft aan welk app-type wordt geconfigureerd. Het profiel wordt intern gebruikt om conventies te stimuleren die het configuratieproces voor de server vereenvoudigen.

"IdentityServer": {
  "Clients": {
    "{ASSEMBLY NAME}": {
      "Profile": "IdentityServerSPA"
    }
  }
}

De plaatsaanduiding {ASSEMBLY NAME} is de assembly-naam van de Client-app (bijvoorbeeld BlazorSample.Client).

Verificatiepakket

Deze sectie heeft betrekking op de Client-app van de oplossing.

Wanneer een app wordt gemaakt voor het gebruik van afzonderlijke gebruikersaccounts (Individual), ontvangt de app automatisch een pakketreferentie voor het Microsoft.AspNetCore.Components.WebAssembly.Authentication-pakket. Het pakket biedt een set primitieven waarmee de app gebruikers kan verifiëren en tokens kan verkrijgen om beveiligde API's aan te roepen.

Als u verificatie toevoegt aan een app, voegt u het Microsoft.AspNetCore.Components.WebAssembly.Authentication-pakket handmatig toe aan de app.

Notitie

Zie de artikelen onder Installeren en beheren van pakketten bij Pakketconsumptiewerkstroom (NuGet-documentatie)voor hulp bij het toevoegen van pakketten aan .NET-apps. Bevestig de juiste pakketversies op NuGet.org.

configuratie van HttpClient

Deze sectie heeft betrekking op de Client-app van de oplossing.

In het Program-bestand is een benoemde HttpClient geconfigureerd voor het leveren van HttpClient exemplaren die toegangstokens bevatten bij het indienen van aanvragen voor de server-API. Bij het opstellen van de oplossing heet de genaamde HttpClient{PROJECT NAME}.ServerAPI, waarbij de plaatsaanduiding {PROJECT NAME} de projectnaam is.

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

De tijdelijke aanduiding {PROJECT NAME} is de projectnaam bij de aanmaak van de oplossing. Het opgeven van een projectnaam van BlazorSample produceert bijvoorbeeld een genaamde HttpClient van BlazorSample.ServerAPI.

Notitie

Als u een Blazor WebAssembly-app configureert om een bestaand Identity Server-exemplaar te gebruiken dat geen deel uitmaakt van een gehoste Blazor-oplossing, wijzigt u de HttpClient basisadresregistratie van IWebAssemblyHostEnvironment.BaseAddress (builder.HostEnvironment.BaseAddress) in de EINDPUNT-URL voor API-autorisatie van de server-app.

API-autorisatieondersteuning

Deze sectie heeft betrekking op de Client-app van de oplossing.

De ondersteuning voor authenticatie van gebruikers wordt via de extensiemethode in het Microsoft.AspNetCore.Components.WebAssembly.Authentication-pakket in de servicecontainer geplaatst. Met deze methode stelt u de services in die de app nodig heeft om te communiceren met het bestaande autorisatiesysteem.

builder.Services.AddApiAuthorization();

De configuratie voor de app wordt standaard geladen vanuit _configuration/{client-id}. Standaard wordt de client-id ingesteld op de assemblynaam van de app. Deze URL kan worden gewijzigd zodat deze verwijst naar een afzonderlijk eindpunt door de overbelasting aan te roepen met opties.

Imports-bestand

Deze sectie heeft betrekking op de Client-app van de oplossing.

De Microsoft.AspNetCore.Components.Authorization naamruimte wordt beschikbaar gesteld in de app via het _Imports.razor-bestand:

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

Deze sectie heeft betrekking op de Client-app van de oplossing.

De pagina Index (wwwroot/index.html) bevat een script waarmee de AuthenticationService in JavaScript wordt gedefinieerd. AuthenticationService verwerkt de details op laag niveau van het OIDC-protocol. De app roept intern methoden aan die in het script zijn gedefinieerd om de verificatiebewerkingen uit te voeren.

<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

App-onderdeel

Deze sectie heeft betrekking op de Client-app van de oplossing.

Het App-onderdeel (App.razor) is vergelijkbaar met het App onderdeel dat is gevonden in Blazor Server-apps:

  • Het CascadingAuthenticationState-onderdeel regelt de blootstelling van de AuthenticationState aan de rest van de app.
  • Het AuthorizeRouteView-onderdeel zorgt ervoor dat de huidige gebruiker gemachtigd is om toegang te krijgen tot een bepaalde pagina of op een andere manier het RedirectToLogin onderdeel weergeeft.
  • Het RedirectToLogin onderdeel beheert het omleiden van onbevoegde gebruikers naar de aanmeldingspagina.

Vanwege wijzigingen in het framework in releases van ASP.NET Core, worden Razor markeringen voor het App-onderdeel (App.razor) niet weergegeven in deze sectie. Gebruik van de volgende benaderingen om de markering van het onderdeel voor een bepaalde release te controleren:

  • Maak een app die is ingericht voor verificatie op basis van de standaardsjabloon Blazor WebAssembly project voor de versie van ASP.NET Core die u wilt gebruiken. Inspecteer het App-onderdeel (App.razor) in de gegenereerde app.

  • Inspecteer het App-onderdeel (App.razor) in referentiebron. Selecteer de versie in de vertakkingskiezer en zoek naar het onderdeel in de ProjectTemplates map van de opslagplaats, omdat de locatie van het App onderdeel in de loop van de jaren is gewijzigd.

    Notitie

    Documentatiekoppelingen naar .NET-referentiebron laden meestal de standaardbranch van de opslagplaats, die de huidige ontwikkeling vertegenwoordigt voor de volgende release van .NET. Als u een tag voor een specifieke release wilt selecteren, gebruikt u de Switch-vertakkingen of tags vervolgkeuzelijst. Zie Een versietag selecteren van ASP.NET Core-broncode (dotnet/AspNetCore.Docs #26205)voor meer informatie.

RedirectToLogin onderdeel

Deze sectie heeft betrekking op de Client-app van de oplossing.

Het RedirectToLogin-onderdeel (RedirectToLogin.razor):

  • Beheert het omleiden van onbevoegde gebruikers naar de aanmeldingspagina.
  • De huidige URL waartoe de gebruiker toegang probeert te krijgen, wordt onderhouden, zodat deze naar die pagina kan worden geretourneerd als de verificatie is geslaagd:

Inspecteer het onderdeel RedirectToLogin bij referentiebron . De locatie van het onderdeel is in de loop van de tijd gewijzigd, dus gebruik GitHub-zoekhulpprogramma's om het onderdeel te vinden.

Notitie

Documentatiekoppelingen naar .NET-referentiebron laden meestal de standaardbranch van de opslagplaats, die de huidige ontwikkeling vertegenwoordigt voor de volgende release van .NET. Als u een tag voor een specifieke release wilt selecteren, gebruikt u de Switch-vertakkingen of tags vervolgkeuzelijst. Zie Een versietag selecteren van ASP.NET Core-broncode (dotnet/AspNetCore.Docs #26205)voor meer informatie.

LoginDisplay-onderdeel

Deze sectie heeft betrekking op de Client-app van de oplossing.

Het LoginDisplay onderdeel (LoginDisplay.razor) wordt weergegeven in het MainLayout-onderdeel (MainLayout.razor) en beheert het volgende gedrag:

  • Voor geverifieerde gebruikers:
    • Geeft de huidige gebruikersnaam weer.
    • Biedt een koppeling naar de gebruikersprofielpagina in ASP.NET Core Identity.
    • Biedt een knop om u af te melden bij de app.
  • Voor anonieme gebruikers:
    • Biedt de mogelijkheid om te registreren.
    • Biedt de mogelijkheid om u aan te melden.

Vanwege wijzigingen in het framework tussen releases van ASP.NET Core, wordt de Razor opmaak voor de LoginDisplay component in dit gedeelte niet weergegeven. Gebruik van de volgende benaderingen om de markering van het onderdeel voor een bepaalde release te controleren:

  • Maak een app die is ingericht voor verificatie op basis van de standaardsjabloon Blazor WebAssembly project voor de versie van ASP.NET Core die u wilt gebruiken. Inspecteer het LoginDisplay onderdeel in de gegenereerde app.

  • Inspecteer het onderdeel LoginDisplay bij referentiebron . De locatie van het onderdeel is in de loop van de tijd gewijzigd, dus gebruik GitHub-zoekhulpprogramma's om het onderdeel te vinden. De gesjabloneerde inhoud voor Hosted die gelijk is aan true wordt gebruikt.

    Notitie

    Documentatiekoppelingen naar .NET-referentiebron laden meestal de standaardbranch van de opslagplaats, die de huidige ontwikkeling vertegenwoordigt voor de volgende release van .NET. Als u een tag voor een specifieke release wilt selecteren, gebruikt u de Switch-vertakkingen of tags vervolgkeuzelijst. Zie Een versietag selecteren van ASP.NET Core-broncode (dotnet/AspNetCore.Docs #26205)voor meer informatie.

Authentication-onderdeel

Deze sectie heeft betrekking op de Client-app van de oplossing.

De pagina die door het Authentication onderdeel (Pages/Authentication.razor) wordt geproduceerd, definieert de routes die vereist zijn voor het verwerken van verschillende verificatiefasen.

Het RemoteAuthenticatorView-onderdeel:

@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication

<RemoteAuthenticatorView Action="@Action" />

@code {
    [Parameter]
    public string? Action { get; set; }
}

Notitie

Nullable reference types (NRTs) en .NET-compiler statische null-statusanalyse wordt ondersteund in ASP.NET Core in .NET 6 of hoger. Vóór de release van ASP.NET Core in .NET 6 wordt het string type weergegeven zonder de null-typeaanduiding (?).

FetchData-onderdeel

Deze sectie heeft betrekking op de Client-app van de oplossing.

Het FetchData-onderdeel laat zien hoe u het volgende kunt doen:

  • Een toegangstoken inrichten.
  • Gebruik het toegangstoken om een beveiligde resource-API aan te roepen in de Server-app.

De @attribute [Authorize] richtlijn geeft aan aan het Blazor WebAssembly autorisatiesysteem dat de gebruiker moet worden geautoriseerd om dit onderdeel te bezoeken. De aanwezigheid van het kenmerk in de Client-app voorkomt niet dat de API op de server wordt aangeroepen zonder de juiste referenties. De Server-app moet ook [Authorize] op de juiste eindpunten gebruiken om ze correct te beveiligen.

IAccessTokenProvider.RequestAccessToken zorgt ervoor dat er een toegangstoken wordt aangevraagd dat kan worden toegevoegd aan de aanvraag om de API aan te roepen. Als het token in de cache is opgeslagen of als de service een nieuw toegangstoken kan inrichten zonder tussenkomst van de gebruiker, slaagt de tokenaanvraag. Anders mislukt de tokenaanvraag met een AccessTokenNotAvailableException, die wordt afgevangen in een try-catch-statement.

Om het werkelijke token te verkrijgen dat in de aanvraag moet worden opgenomen, moet de app controleren of de aanvraag is geslaagd door tokenResult.TryGetToken(out var token)aan te roepen.

Als de aanvraag is geslaagd, wordt de tokenvariabele gevuld met het toegangstoken. Met de eigenschap AccessToken.Value van het token wordt de letterlijke tekenreeks weergegeven die moet worden opgenomen in de Authorization aanvraagheader.

Als het token niet kan worden ingericht zonder tussenkomst van de gebruiker, wat resulteert in een mislukte aanvraag:

  • ASP.NET Core in .NET 7 of hoger: De app navigeert naar AccessTokenResult.InteractiveRequestUrl met behulp van de opgegeven AccessTokenResult.InteractionOptions om het toegangstoken te vernieuwen.
  • ASP.NET Core in .NET 6 of eerder: het tokenresultaat bevat een omleidings-URL. Als u naar deze URL navigeert, gaat de gebruiker naar de aanmeldingspagina en gaat u terug naar de huidige pagina na een geslaagde verificatie.
@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();
        }
    }
}

Azure App Service in Linux

Geef de verlener expliciet op bij de implementatie in Azure App Service in Linux. Zie voor meer informatie en gebruik Identity om een web-API-backend voor SPA'ste beveiligen.

Naam- en rolaanspraak met API-autorisatie

Aangepaste gebruikersfabriek

Maak in de Client-app een aangepaste gebruikersfabriek. Identity Server verzendt meerdere rollen als een JSON-matrix in één role claim. Er wordt één rol verzonden als een stringwaarde in de aanspraak. De fabriek maakt een afzonderlijke role-claim voor elk van de rollen van de gebruiker.

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

Registreer de fabriek in het Client-bestand in de Program-app.

builder.Services.AddApiAuthorization()
    .AddAccountClaimsPrincipalFactory<CustomUserFactory>();

Roep in de Server-app AddRoles aan op de opbouwfunctie voor Identity, waarmee functiegerelateerde services worden toegevoegd.

In het bestand Program:

using Microsoft.AspNetCore.Identity;

...

builder.Services.AddDefaultIdentity<ApplicationUser>(options => 
    options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

In Startup.cs:

using Microsoft.AspNetCore.Identity;

...

services.AddDefaultIdentity<ApplicationUser>(options => 
    options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

Identity-server configureren

Gebruik één van de volgende methoden:

API-autorisatieopties

In de Server-app:

  • Configureer Identity Server om de name en role claims in het id-token en toegangstoken te plaatsen.
  • Voorkom de standaardtoewijzing van rollen in de JWT-tokenverwerker.

In het bestand 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");

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

Profielbeheer Service

Maak in de Server-app een ProfileService-implementatie.

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

Registreer in de Server-app de Profielservice in het Program-bestand:

using Duende.IdentityServer.Services;

...

builder.Services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Registreer in de Server-app de profielservice in Startup.ConfigureServices van Startup.cs:

using IdentityServer4.Services;

...

services.AddTransient<IProfileService, ProfileService>();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

Autorisatiemechanismen gebruiken

In de Client-app zijn de methoden voor onderdeelautorisatie op dit moment functioneel. Een van de autorisatiemechanismen in onderdelen kan een rol gebruiken om de gebruiker te autoriseren:

User.Identity.Name wordt ingevuld in de Client-app met de gebruikersnaam van de gebruiker. Dit is meestal het e-mailadres van de aanmelding.

UserManager en SignInManager

Stel het claimtype van de gebruikers-id in wanneer dit vereist is door een Server-app.

In Program.cs voor ASP.NET Core in .NET 6 of hoger:

using System.Security.Claims;

...

builder.Services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

In Startup.ConfigureServices voor versies van ASP.NET Core ouder dan 6.0:

using System.Security.Claims;

...

services.Configure<IdentityOptions>(options => 
    options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);

De volgende WeatherForecastController logt de UserName wanneer de methode Get wordt aangeroepen.

Notitie

In het volgende voorbeeld wordt gebruikgemaakt van:

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

In het voorgaande voorbeeld:

  • De naamruimte van het Server project is BlazorSample.Server.
  • De naamruimte van het Shared project is BlazorSample.Shared.

Hosten in Azure App Service met een aangepast domein en certificaat

In de volgende richtlijnen wordt uitgelegd:

  • Een gehoste Blazor WebAssembly-app met Identity Server implementeren in Azure App Service- met een aangepast domein.
  • Een TLS-certificaat maken en gebruiken voor HTTPS-protocolcommunicatie met browsers. Hoewel de richtlijnen gericht zijn op het gebruik van het certificaat met een aangepast domein, zijn de richtlijnen evenzeer van toepassing op het gebruik van een standaardDomein van Azure Apps, bijvoorbeeld contoso.azurewebsites.net.

Gebruik voor dit hostingscenario niet hetzelfde certificaat voor de Duende Identity Server's tokenondertekeningssleutel en de HTTPS-beveiligde communicatie van de site met browsers:

  • Het gebruik van verschillende certificaten voor deze twee vereisten is een goede beveiligingspraktijk omdat hiermee persoonlijke sleutels voor elk doel worden geïsoleerd.
  • TLS-certificaten voor communicatie met browsers worden onafhankelijk beheerd zonder dat dit van invloed is op de tokenondertekening van Identity Server.
  • Wanneer Azure Key Vault een certificaat levert aan een App Service-app voor aangepaste domeinbinding, kan Identity Server niet hetzelfde certificaat verkrijgen van Azure Key Vault voor tokenondertekening. Hoewel het configureren van Identity Server voor het gebruik van hetzelfde TLS-certificaat vanuit een fysiek pad mogelijk is, is het plaatsen van beveiligingscertificaten in broncodebeheer een slechte praktijk en moet worden vermeden in de meeste scenario's.

In de volgende richtlijnen wordt alleen een zelfondertekend certificaat gemaakt in Azure Key Vault voor Identity Server-tokenondertekening. De Identity Server-configuratie maakt gebruik van het sleutelkluiscertificaat via het CurrentUser>My certificaatarchief van de app. Andere certificaten die worden gebruikt voor HTTPS-verkeer met aangepaste domeinen, worden afzonderlijk van het Identity Server-handtekeningcertificaat gemaakt en geconfigureerd.

Een app, Azure App Service en Azure Key Vault configureren om te hosten met een aangepast domein en HTTPS:

  1. Maak een App Service-plan met een planniveau van Basic B1 of hoger. App Service vereist een Basic B1 of een hogere servicelaag voor het gebruik van aangepaste domeinen.

  2. Maak een PFX-certificaat voor de beveiligde browsercommunicatie (HTTPS-protocol) van de site met een algemene naam van de FQDN (Fully Qualified Domain Name) van de site die door uw organisatie wordt beheerd (bijvoorbeeld www.contoso.com). Maak het certificaat met:

    • Sleutelgebruik
      • Validatie van digitale handtekening (digitalSignature)
      • Sleutelcodering (keyEncipherment)
    • Verbeterd/uitgebreid sleutelgebruik
      • Clientauthenticatie (1.3.6.1.5.5.7.3.2)
      • Serververificatie (1.3.6.1.5.5.7.3.1)

    Als u het certificaat wilt maken, gebruikt u een van de volgende benaderingen of een ander geschikt hulpprogramma of een andere onlineservice:

    Noteer het wachtwoord, dat later wordt gebruikt om het certificaat te importeren in Azure Key Vault.

    Zie Azure Key Vault: Certificatenvoor meer informatie over Azure Key Vault-certificaten.

  3. Maak een nieuwe Azure Key Vault of gebruik een bestaande sleutelkluis in uw Azure-abonnement.

  4. Importeer in het gebied Certificates van de sleutelkluis het PFX-sitecertificaat. Noteer de vingerafdruk van het certificaat, die later wordt gebruikt in de configuratie van de app.

  5. Genereer in Azure Key Vault een nieuw zelfondertekend certificaat voor Identity Server-tokenondertekening. Geef het certificaat een Certificaatnaam en Onderwerp. Het onderwerp wordt opgegeven als CN={COMMON NAME}, waarbij de tijdelijke aanduiding {COMMON NAME} de algemene naam van het certificaat vertegenwoordigt. De algemene naam kan elke alfanumerieke tekenreeks zijn. CN=IdentityServerSigning is bijvoorbeeld een geldig certificaat Subject. Gebruik in Uitgiftebeleid>Advanced Policy Configurationde standaardinstellingen. Noteer de vingerafdruk van het certificaat, die later wordt gebruikt in de configuratie van de app.

  6. Navigeer naar Azure App Service in Azure Portal en maak een nieuwe App Service met de volgende configuratie:

    • Publiceren ingesteld op Code.
    • Runtime-stack ingesteld op de runtime van de app.
    • Controleer voor SKU en grootte of de App Service-laag Basic B1 of hoger is. App Service vereist een Basic B1 of een hogere servicelaag voor het gebruik van aangepaste domeinen.
  7. Nadat Azure de App Service heeft gemaakt, opent u de Configuratie van de app en voegt u een nieuwe toepassingsinstelling toe die de vingerafdrukken van de certificaten opgeeft die eerder zijn vastgelegd. De app-instellingssleutel is WEBSITE_LOAD_CERTIFICATES. Scheid de certificaatvingerafdrukken in de app-instellingswaarde met een komma, zoals in het volgende voorbeeld wordt weergegeven.

    • Sleutel: WEBSITE_LOAD_CERTIFICATES
    • Waarde: 57443A552A46DB...D55E28D412B943565,29F43A772CB6AF...1D04F0C67F85FB0B1

    In Azure Portal is het opslaan van app-instellingen een proces in twee stappen: Sla de instelling WEBSITE_LOAD_CERTIFICATES sleutelwaarde op en selecteer vervolgens de knop Opslaan boven aan de blade.

  8. Selecteer de TLS/SSL-instellingen van de app. Selecteer Privésleutelcertificaten (.pfx). Gebruik het proces voor het importeren van Key Vault-certificaten . Gebruik het proces twee keer om zowel het certificaat van de site voor HTTPS-communicatie als het zelfondertekende certificaat van Identity Server-tokenondertekening te importeren.

  9. Navigeer naar het Aangepaste domeinen venster. Gebruik op de website van uw domeinregistrar het IP-adres en aangepaste domeinverificatie-id om het domein te configureren. Een typische domeinconfiguratie omvat:

    • Een A-record met een host van @ en met de waarde van het IP-adres uit de Azure Portal.
    • Een TXT Record met een Host van asuid en de waarde van de verificatie-id die is gegenereerd door Azure en wordt geleverd door Azure Portal.

    Zorg ervoor dat u de wijzigingen op de website van uw domeinregistrar correct opslaat. Voor sommige registrarwebsites is een proces in twee stappen vereist om domeinrecords op te slaan: een of meer records worden afzonderlijk opgeslagen, gevolgd door de registratie van het domein bij te werken met een afzonderlijke knop.

  10. Ga terug naar de Aangepaste domeinen blade in de Azure portal. Selecteer Aangepast domein toevoegen. Selecteer de optie A Record. Geef het domein op en selecteer Valideren. Als de domeinrecords juist zijn en via internet worden doorgegeven, kunt u in de portal de knop Aangepast domein toevoegen selecteren.

    Het kan enkele dagen duren voordat de wijzigingen in domeinregistratie zijn doorgegeven via DNS (Internet Domain Name Servers) nadat ze zijn verwerkt door uw domeinregistrar. Als domeinrecords niet binnen drie werkdagen worden bijgewerkt, controleert u of de records correct zijn ingesteld bij de domeinregistrar en neemt u contact op met de klantondersteuning.

  11. In de sectie Aangepaste domeinen van het beheerportaal, is de SSL STATE voor het domein gemarkeerd als Not Secure. Selecteer de koppeling Binding toevoegen. Selecteer het HTTPS-certificaat van de site in de sleutelkluis voor de aangepaste domeinbinding.

  12. Open in Visual Studio het bestand met app-instellingen ( of appsettings.json) van het project appsettings.Production.json). Voeg in de Identity Server-configuratie de volgende Key sectie toe. Geef het zelfondertekende certificaat voor het onderwerp van de sleutel Name op. In het volgende voorbeeld is de standaardnaam van het certificaat, die in de Key Vault is toegewezen, IdentityServerSigning, wat resulteert in een Onderwerp van CN=IdentityServerSigning:

    "IdentityServer": {
    
      ...
    
      "Key": {
        "Type": "Store",
        "StoreName": "My",
        "StoreLocation": "CurrentUser",
        "Name": "CN=IdentityServerSigning"
      }
    },
    
  13. Maak in Visual Studio een Azure App Service-publiceerprofiel voor het Server--project. Selecteer vanuit de menubalk: Build>Publish>New>Azure>Azure App Service (Windows of Linux). Wanneer Visual Studio is verbonden met een Azure-abonnement, kunt u de weergave van Azure-resources instellen volgens Resourcetype. Navigeer in de web-app lijst om de App Service voor de app te zoeken en selecteer deze. Selecteer voltooien.

  14. Wanneer Visual Studio terugkeert naar het venster Publish, worden de sleutelkluis- en SQL Server-databaseserviceafhankelijkheden automatisch gedetecteerd.

    Er zijn geen configuratiewijzigingen in de standaardinstellingen vereist voor de sleutelkluisservice.

    Voor testdoeleinden kan de lokale SQLite-database van een app, die is geconfigureerd door de Blazor-sjabloon, worden geïmplementeerd met de app zonder extra configuratie. Het configureren van een andere database voor Identity Server in productie valt buiten het bereik van dit artikel. Zie de databaseresources in de volgende documentatiesets voor meer informatie:

  15. Selecteer de koppeling Bewerken onder de naam van het implementatieprofiel boven aan het venster. Wijzig de doel-URL in de URL van het aangepaste domein van de site (bijvoorbeeld https://www.contoso.com). Sla de instellingen op.

  16. Publiceer de app. Visual Studio opent een browservenster en vraagt de site op het aangepaste domein aan.

De Azure-documentatie bevat aanvullende informatie over het gebruik van Azure-services en aangepaste domeinen met TLS-binding in App Service, inclusief informatie over het gebruik van CNAME-records in plaats van A-records. Zie de volgende bronnen voor meer informatie:

U kunt het beste een nieuw browservenster voor de privémodus (bijvoorbeeld de InPrivate-modus van Microsoft Edge of de Incognitomodus van Google Chrome) gebruiken voor elke app-test die wordt uitgevoerd na een wijziging in de app, app-configuratie of Azure-services in Azure Portal. Het hangen van cookies uit een vorige testuitvoering kan leiden tot mislukte verificatie of autorisatie bij het testen van de site, zelfs wanneer de configuratie van de site juist is. Zie de sectie Cookies en sitegegevens voor meer informatie over het configureren van Visual Studio om een nieuw privébrowservenster te openen voor elke testuitvoering.

Wanneer de App Service-configuratie wordt gewijzigd in Azure Portal, worden de updates over het algemeen snel van kracht, maar zijn ze niet direct. Soms moet u een korte periode wachten totdat een App Service opnieuw wordt opgestart om een configuratiewijziging van kracht te laten worden.

Als u problemen met het laden van een certificaat voor Identity Server-sleutelondertekening wilt oplossen, voert u de volgende opdracht uit in een Azure-portal Kudu PowerShell-opdrachtshell. De opdracht bevat een lijst met certificaten waartoe de app toegang heeft vanuit het CurrentUser>My certificaatarchief. De uitvoer bevat certificaatonderwerpers en vingerafdrukken die handig zijn bij het opsporen van fouten in een app:

Get-ChildItem -path Cert:\CurrentUser\My -Recurse | Format-List DnsNameList, Subject, Thumbprint, EnhancedKeyUsageList

Problemen oplossen

Loggen

Als u het debuggen of traceren voor Blazor WebAssembly-verificatie wilt inschakelen, raadpleegt u de sectie Client-side authenticatielogging van de ASP.NET Core Blazor logging, waarbij de artikelversiekiezer is ingesteld op ASP.NET Core 7.0 of hoger.

Veelvoorkomende fouten

  • Onjuiste configuratie van de app of de leverancier (IP) Identity.

    De meest voorkomende fouten worden veroorzaakt door onjuiste configuratie. Hier volgen enkele voorbeelden:

    • Afhankelijk van de vereisten van het scenario voorkomt een ontbrekende of onjuiste autoriteit, instantie, tenant-id, tenantdomein, client-id of omleidings-URI dat een app clients kan authenticeren.
    • Onjuiste aanvraagbereiken voorkomen dat clients toegang hebben tot eindpunten van de serverweb-API.
    • Onjuiste of ontbrekende server-API-machtigingen voorkomen dat clients toegang hebben tot web-API-eindpunten van de server.
    • Het uitvoeren van de app op een andere poort dan dat geconfigureerd is in de omleidings-URI van de app-registratie van het IP-adres. Houd er rekening mee dat een poort niet vereist is voor Microsoft Entra ID en een app die wordt uitgevoerd op een localhost ontwikkelingstestadres, maar de poortconfiguratie van de app en de poort waarop de app wordt uitgevoerd, moet overeenkomen met niet-localhost adressen.

    In de configuratiesecties van de richtlijnen van dit artikel ziet u voorbeelden van de juiste configuratie. Controleer elke sectie van het artikel zorgvuldig op zoek naar onjuiste configuratie van apps en IP-adressen.

    Als de configuratie correct wordt weergegeven:

    • Toepassingslogboeken analyseren.

    • Controleer het netwerkverkeer tussen de client-app en de IP- of server-app met de ontwikkelhulpprogramma's van de browser. Vaak wordt een exacte foutmelding of een bericht met een aanwijzing voor wat het probleem veroorzaakt, geretourneerd door de IP- of server-app nadat u een aanvraag hebt ingediend. Richtlijnen voor ontwikkelhulpprogramma's vindt u in de volgende artikelen:

    • Voor releases van Blazor waarbij een JSON-webtoken (JWT) wordt gebruikt, decodert u de inhoud van het token dat wordt gebruikt voor het verifiëren van een client of het openen van een serverweb-API, afhankelijk van waar het probleem optreedt. Zie De inhoud van een JSON-webtoken (JWT) controlerenvoor meer informatie.

    Het documentatieteam reageert op documentfeedback en fouten in artikelen (open een probleem in de sectie Deze pagina feedback), maar kan geen productondersteuning bieden. Er zijn verschillende openbare ondersteuningsforums beschikbaar om u te helpen bij het oplossen van problemen met een app. U wordt aangeraden het volgende te doen:

    De voorgaande forums zijn niet eigendom van of worden beheerd door Microsoft.

    Voor reproduceerbare frameworkfoutrapporten die niet over beveiliging, gevoeligheid of vertrouwelijkheid gaan, meld een probleem bij de ASP.NET Core-producteenheid. Meld geen probleem bij de productafdeling totdat u de oorzaak van het probleem grondig hebt onderzocht en het zelf niet kunt oplossen, zelfs niet met behulp van de community op een openbaar ondersteuningsforum. De producteenheid kan geen problemen met afzonderlijke apps oplossen die zijn verbroken vanwege eenvoudige onjuiste configuratie of gebruiksscenario's met betrekking tot services van derden. Als een rapport gevoelig of vertrouwelijk is, of een mogelijke beveiligingsfout in het product beschrijft die door cyberaanvallers kan worden misbruikt, raadpleeg dan Beveiligingsproblemen en bugs melden (dotnet/aspnetcore GitHub-opslagplaats).

  • Niet-geautoriseerde cliënt voor ME-ID

    info: Autorisatie van Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] is mislukt. Aan deze vereisten is niet voldaan: DenyAnonymousAuthorizationRequirement: Vereist een geverifieerde gebruiker.

    Aanmeldingsoproepfout van ME-ID:

    • Fout: unauthorized_client
    • Beschrijving: AADB2C90058: The provided application is not configured to allow public clients.

    De fout oplossen:

    1. Open in Azure Portal het manifest van de -app.
    2. Stel de allowPublicClient kenmerk- in op null of true.

Cookies en sitegegevens

Cookies en sitegegevens kunnen worden bewaard in app-updates en kunnen het testen en oplossen van problemen verstoren. Verwijder het volgende bij app-codewijzigingen, gebruikersaccountwijzigingen bij de provider of provider-appconfiguratie wijzigingen:

  • Aanmeldingscookies van gebruikers
  • App-cookies
  • Sitegegevens in cache en opgeslagen

Een benadering om te voorkomen dat achterblijvende cookies en sitegegevens het testen en oplossen van problemen verstoren, is het volgende:

  • Een browser configureren
    • Gebruik een browser om te testen dat u kunt configureren om alle cookie en sitegegevens te verwijderen telkens wanneer de browser wordt gesloten.
    • Zorg ervoor dat de browser handmatig of door de IDE is gesloten voor een wijziging in de configuratie van de app, testgebruiker of provider.
  • Gebruik een aangepaste opdracht om een browser te openen in de InPrivate- of Incognitomodus in Visual Studio:
    • Open dialoogvenster Bladeren met vanuit de knop Uitvoeren van Visual Studio.
    • Selecteer de knop Toevoegen.
    • Geef het pad naar uw browser op in het veld Program. De volgende uitvoerbare paden zijn typische installatielocaties voor Windows 10. Als uw browser is geïnstalleerd op een andere locatie of als u Windows 10 niet gebruikt, geeft u het pad op naar het uitvoerbare bestand van de browser.
      • 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
    • Geef in het veld Argumenten de opdrachtregeloptie op die de browser gebruikt om in de InPrivate- of Incognitomodus te openen. Voor sommige browsers is de URL van de app vereist.
      • Microsoft Edge: gebruik -inprivate.
      • Google Chrome: gebruik --incognito --new-window {URL}, waarbij de {URL} tijdelijke aanduiding de URL is die moet worden geopend (bijvoorbeeld https://localhost:5001).
      • Mozilla Firefox: Gebruik -private -url {URL}, waarbij {URL} de tijdelijke aanduiding is voor de URL die moet worden geopend (bijvoorbeeld https://localhost:5001).
    • Geef een naam op in het veld Vriendelijke naam. Bijvoorbeeld Firefox Auth Testing.
    • Selecteer de knop OK.
    • Om te voorkomen dat u het browserprofiel moet selecteren voor elke iteratie van het testen met een app, stelt u het profiel in als de standaardinstelling met de knop Als standaard instellen.
    • Zorg ervoor dat de browser wordt gesloten door de IDE voor elke wijziging in de app, testgebruiker of providerconfiguratie.

App-upgrades

Een werkende app kan onmiddellijk mislukken na het upgraden van de .NET Core SDK op de ontwikkelcomputer of het wijzigen van pakketversies in de app. In sommige gevallen kunnen incoherent pakketten een app breken bij het uitvoeren van belangrijke upgrades. De meeste van deze problemen kunnen worden opgelost door de volgende instructies te volgen:

  1. Wis de NuGet-pakketcaches van het lokale systeem door dotnet nuget locals all --clear uit te voeren vanuit een opdrachtshell.
  2. Verwijder de bin en obj mappen van het project.
  3. Herstel het project en bouw het opnieuw.
  4. Verwijder alle bestanden in de implementatiemap op de server voordat u de app opnieuw implementeert.

Notitie

Het gebruik van pakketversies die niet compatibel zijn met het doelframework van de app, wordt niet ondersteund. Gebruik de NuGet Galleryvoor informatie over een pakket.

De Server-app uitvoeren

Bij het testen en oplossen van problemen met een gehoste Blazor WebAssembly-oplossing, moet u ervoor zorgen dat u de app uitvoert vanuit het Server project.

De gebruiker inspecteren

Het volgende User onderdeel kan rechtstreeks in apps worden gebruikt of dienen als basis voor verdere aanpassing.

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

De inhoud van een JSON Web Token (JWT) controleren

Als u een JSON-webtoken (JWT) wilt decoderen, gebruikt u het hulpprogramma jwt.ms van Microsoft. Waarden in de gebruikersinterface verlaten uw browser nooit.

Voorbeeld van gecodeerde JWT (ingekort voor weergave):

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrNHh5b2pORnVtMWtsMll0djhkbE5QNC1j ... bQdHBHGcQQRbW7Wmo6SWYG4V_bU55Ug_PW4pLPr20tTS8Ct7_uwy9DWrzCMzpD-EiwT5IjXwlGX3IXVjHIlX50IVIydBoPQtadvT7saKo1G5Jmutgq41o-dmz6-yBMKV2_nXA25Q

Voorbeeld van JWT dat is gedecodeerd door het hulpprogramma voor een app die wordt geverifieerd met 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]

Aanvullende informatiebronnen