Proteggere un'app Web core Blazor ASP.NET con OpenID Connect (OIDC)

Questo articolo descrive come proteggere un'app Web con OpenID Connect (OIDC) usando un'app di esempio nel dotnet/blazor-samples repository GitHub (.NET 8 o versione successiva) (come scaricare).Blazor

Questa versione dell'articolo illustra l'implementazione di OIDC senza adottare il modello Back-end per front-end (BFF). Il modello BFF è utile per effettuare richieste autenticate a servizi esterni. Modificare il selettore di versione dell'articolo in OIDC con modello BFF se la specifica dell'app richiede l'adozione del modello BFF.

La specifica seguente è descritta:

  • L'app Blazor Web usa la modalità di rendering automatico con interattività globale.
  • I servizi provider di stato di autenticazione personalizzati vengono usati dal server e dalle app client per acquisire lo stato di autenticazione dell'utente e fluirlo tra il server e il client.
  • Questa app è un punto di partenza per qualsiasi flusso di autenticazione OIDC. OIDC viene configurato manualmente nell'app e non si basa su Microsoft Entra ID o pacchetti Web MicrosoftIdentity, né l'app di esempio richiede l'hosting di Microsoft Azure. Tuttavia, l'app di esempio può essere usata con Entra, Microsoft Identity Web e ospitata in Azure.
  • Aggiornamento automatico del token non interattivo.
  • Chiama in modo sicuro un'API (Web) nel progetto server per i dati.

Esempio di app

L'app di esempio è costituita da due progetti:

  • BlazorWebAppOidc: progetto lato server dell'app Blazor Web contenente un esempio di endpoint API minimo per i dati meteo.
  • BlazorWebAppOidc.Client: progetto lato client dell'app Blazor Web.

Accedere alle app di esempio tramite la cartella della versione più recente dalla radice del repository con il collegamento seguente. I progetti si trovano nella BlazorWebAppOidc cartella per .NET 8 o versione successiva.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Progetto app Web sul lato Blazor server (BlazorWebAppOidc)

Il BlazorWebAppOidc progetto è il progetto lato server dell'app Blazor Web.

Il BlazorWebAppOidc.http file può essere usato per testare la richiesta di dati meteo. Si noti che il BlazorWebAppOidc progetto deve essere in esecuzione per testare l'endpoint e l'endpoint è hardcoded nel file. Per altre informazioni, vedere Usare file .http in Visual Studio 2022.

Nota

Il progetto server usa IHttpContextAccessor/HttpContext, ma non per i componenti di cui è stato eseguito il rendering interattivo. Per altre informazioni, vedere Linee guida per la mitigazione delle minacce per ASP.NET rendering lato server interattivo CoreBlazor.

Impostazione

Questa sezione illustra come configurare l'app di esempio.

Nota

Per Microsoft Entra ID e Azure AD B2C, è possibile usare microsoft AddMicrosoftIdentityWebApp Identity Web (Microsoft.Identity.Web pacchetto NuGet, documentazione dell'API), che aggiunge sia i gestori OIDC Cookie che i gestori di autenticazione con le impostazioni predefinite appropriate. L'app di esempio e le indicazioni contenute in questa sezione non usano Microsoft Identity Web. Le linee guida illustrano come configurare manualmente il gestore OIDC per qualsiasi provider OIDC. Per altre informazioni sull'implementazione di Microsoft Identity Web, vedere le risorse collegate.

La configurazione seguente OpenIdConnectOptions è disponibile nel file del Program progetto nella chiamata a AddOpenIdConnect:

  • SignInScheme: imposta lo schema di autenticazione corrispondente al middleware responsabile della persistenza dell'identità dell'utente dopo un'autenticazione riuscita. Il gestore OIDC deve usare uno schema di accesso in grado di rendere persistenti le credenziali utente tra le richieste. La seguente riga è presente solo a scopo dimostrativo. Se omesso, DefaultSignInScheme viene usato come valore di fallback.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Ambiti per openid e () (Scopefacoltativo): anche gli openid ambiti e profile profile sono configurati per impostazione predefinita perché sono necessari per il funzionamento del gestore OIDC, ma potrebbe essere necessario aggiungerli nuovamente se gli ambiti sono inclusi nella Authentication:Schemes:MicrosoftOidc:Scope configurazione. Per indicazioni generali sulla configurazione, vedere Configurazione in ASP.NET Core e configurazione di ASP.NET CoreBlazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: definisce se i token di accesso e aggiornamento devono essere archiviati in AuthenticationProperties dopo un'autorizzazione riuscita. Questa proprietà è impostata su false per impostazione predefinita per ridurre le dimensioni dell'autenticazione cookiefinale.

    oidcOptions.SaveTokens = false;
    
  • Ambito per l'accesso offline (Scope): l'ambito offline_access è obbligatorio per il token di aggiornamento.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Authority e ClientId: imposta l'autorità e l'ID client per le chiamate OIDC.

    oidcOptions.Authority = "{AUTHORITY}";
    oidcOptions.ClientId = "{CLIENT ID}";
    

    Esempio:

    • Autorità (): https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/ ({AUTHORITY}usa l'ID a3942615-d115-4eb7-bc84-9974abcf5064tenant )
    • ID client ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
    oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
    oidcOptions.ClientId = "4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
    

    Esempio per l'autorità "common" di Microsoft Azure:

    L'autorità "comune" deve essere usata per le app multi-tenant. È anche possibile usare l'autorità "comune" per le app a tenant singolo, ma è necessario un personalizzato IssuerValidator , come illustrato più avanti in questa sezione.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ClientSecret: segreto client OIDC.

    L'esempio seguente è solo a scopo di test e dimostrazione. Non archiviare il segreto client nell'assembly dell'app o controllare il segreto nel controllo del codice sorgente. Archiviare il segreto client in Segreti utente, Azure Key Vault o una variabile di ambiente.

    La configurazione dello schema di autenticazione viene letta automaticamente da builder.Configuration["Authentication:Schemes:{SCHEME NAME}:{PropertyName}"], dove il {SCHEME NAME} segnaposto è lo schema, ovvero per MicrosoftOidc impostazione predefinita. Poiché la configurazione è preconfigurata, un segreto client può essere letto automaticamente tramite la Authentication:Schemes:MicrosoftOidc:ClientSecret chiave di configurazione. Nel server che usa variabili di ambiente assegnare alla variabile Authentication__Schemes__MicrosoftOidc__ClientSecretdi ambiente il nome :

    set Authentication__Schemes__MicrosoftOidc__ClientSecret={CLIENT SECRET}
    

    Solo per la dimostrazione e il test, ClientSecret è possibile impostare direttamente . Non impostare il valore direttamente per le app di produzione distribuite. Per una sicurezza leggermente migliorata, compilare in modo condizionale la riga con il DEBUG simbolo :

    #if DEBUG
    oidcOptions.ClientSecret = "{CLIENT SECRET}";
    #endif
    

    Esempio:

    Segreto client (): 463471c8c4...f90d674bc9 ({CLIENT SECRET}abbreviato per la visualizzazione)

    #if DEBUG
    oidcOptions.ClientSecret = "463471c8c4...137f90d674bc9";
    #endif
    
  • ResponseType: configura il gestore OIDC per eseguire solo il flusso del codice di autorizzazione. Le concessioni implicite e i flussi ibridi non sono necessari in questa modalità.

    Nella configurazione di registrazione dell'app Entra o portale di Azure implicita e dei flussi ibridi, non selezionare la casella di controllo relativa all'endpoint di autorizzazione per restituire token di accesso o token ID. Il gestore OIDC richiede automaticamente i token appropriati usando il codice restituito dall'endpoint di autorizzazione.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    
  • MapInboundClaimse la configurazione di NameClaimType e : molti server OIDC usano "name" e "role" anziché le impostazioni predefinite SOAP/WS-Fed in ClaimTypesRoleClaimType. Quando MapInboundClaims è impostato su false, il gestore non esegue i mapping delle attestazioni e i nomi delle attestazioni del token JWT vengono usati direttamente dall'app. Nell'esempio seguente il tipo di attestazione del ruolo viene impostato su "roles", appropriato per Microsoft Entra ID (ME-ID). Per altre informazioni, vedere la documentazione del provider di identità.

Nota

MapInboundClaims deve essere impostato su false per la maggior parte dei provider OIDC, che impedisce la ridenominazione delle attestazioni.

oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
  • Configurazione del percorso: i percorsi devono corrispondere all'URI di reindirizzamento (percorso di callback di accesso) e ai percorsi di reindirizzamento post disconnessione (percorso di callback con disconnessione) configurati durante la registrazione dell'applicazione con il provider OIDC. Nel portale di Azure i percorsi vengono configurati nel pannello Autenticazione della registrazione dell'app. Entrambi i percorsi di accesso e disconnessione devono essere registrati come URI di reindirizzamento. I valori predefiniti sono /signin-oidc e /signout-callback-oidc.

    • CallbackPath: percorso della richiesta all'interno del percorso di base dell'app in cui viene restituito l'agente utente.

      In Entra o portale di Azure impostare il percorso nell'URI di reindirizzamento della configurazione della piattaforma Web:

      https://localhost/signin-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi quando si usa Microsoft Entra ID. La maggior parte degli altri provider OIDC richiede una porta corretta.

    • SignedOutCallbackPath: percorso della richiesta all'interno del percorso di base dell'app in cui viene restituito l'agente utente dopo la disconnessione dal provider di identità.

      In Entra o portale di Azure impostare il percorso nell'URI di reindirizzamento della configurazione della piattaforma Web:

      https://localhost/signout-callback-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi quando si usa Microsoft Entra ID. La maggior parte degli altri provider OIDC richiede una porta corretta.

      Nota

      Se si usa Microsoft Identity Web, il provider attualmente reindirizza di nuovo a SignedOutCallbackPath se viene usata l'autorità microsoftonline.com (https://login.microsoftonline.com/{TENANT ID}/v2.0/). Questa limitazione non esiste se è possibile usare l'autorità "comune" con Microsoft Identity Web. Per altre informazioni, vedere postLogoutRedirectUri not working when authority URL contains a tenant ID (AzureAD/microsoft-authentication-library-for-js #5783).

    • RemoteSignOutPath: le richieste ricevute in questo percorso causano il richiamo della disconnessione da parte del gestore tramite lo schema di disconnessione.

      In Entra o portale di Azure impostare l'URL di disconnessione del canale anteriore:

      https://localhost/signout-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi quando si usa Microsoft Entra ID. La maggior parte degli altri provider OIDC richiede una porta corretta.

    oidcOptions.CallbackPath = new PathString("{PATH}");
    oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
    oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
    

    Esempi (valori predefiniti):

    oidcOptions.CallbackPath = new PathString("/signin-oidc");
    oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
    oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
    
  • (Microsoft Azure solo con l'endpoint "comune") TokenValidationParameters.IssuerValidator: molti provider OIDC funzionano con il validator predefinito dell'autorità di certificazione, ma è necessario tenere conto dell'autorità di certificazione con parametri con l'ID tenant ({TENANT ID}) restituito da https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. Per altre informazioni, vedere SecurityTokenInvalidIssuerException con OpenID Connect e l'endpoint "common" di Azure AD (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Solo per le app che usano Microsoft Entra ID o Azure AD B2C con l'endpoint "comune":

    var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
    oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
    

Codice dell'app di esempio

Esaminare l'app di esempio per le funzionalità seguenti:

  • Aggiornamento automatico del token non interattivo con l'aiuto di un aggiornamento personalizzato cookie (CookieOidcRefresher.cs).
  • La PersistingAuthenticationStateProvider classe (PersistingAuthenticationStateProvider.cs) è un lato AuthenticationStateProvider server che usa PersistentComponentState per trasferire lo stato di autenticazione al client, che viene quindi risolto per la durata dell'applicazione WebAssembly.
  • Un esempio di richieste all'app Web per i Blazor dati meteo viene gestito da un endpoint API minimo (/weather-forecast) nel Program file (Program.cs). L'endpoint richiede l'autorizzazione chiamando RequireAuthorization. Per tutti i controller aggiunti al progetto, aggiungere l'attributo [Authorize] al controller o all'azione.
  • L'app chiama in modo sicuro un'API (Web) nel progetto server per i dati meteo:
    • Quando si esegue il rendering del Weather componente nel server, il componente usa sul ServerWeatherForecaster server per ottenere i dati meteo direttamente (non tramite una chiamata API Web).
    • Quando viene eseguito il rendering del componente nel client, il componente usa l'implementazione del ClientWeatherForecaster servizio, che usa un preconfigurato HttpClient (nel file del Program progetto client) per effettuare una chiamata API Web al progetto server. Un endpoint API minimo (/weather-forecast) definito nel file del progetto server Program ottiene i dati meteo da ServerWeatherForecaster e restituisce i dati al client.

Per altre informazioni sulle chiamate API (Web) tramite astrazioni di servizio in Blazor App Web, vedere Chiamare un'API Web da un'app ASP.NET CoreBlazor.

Progetto app Web sul lato Blazor client (BlazorWebAppOidc.Client)

Il BlazorWebAppOidc.Client progetto è il progetto lato client dell'app Blazor Web.

La PersistentAuthenticationStateProvider classe (PersistentAuthenticationStateProvider.cs) è un lato AuthenticationStateProvider client che determina lo stato di autenticazione dell'utente cercando i dati persistenti nella pagina quando è stato eseguito il rendering nel server. Lo stato di autenticazione è fisso per la durata dell'applicazione WebAssembly.

Se l'utente deve accedere o disconnettersi, è necessario ricaricare una pagina completa.

L'app di esempio fornisce solo un nome utente e un messaggio di posta elettronica a scopo di visualizzazione. Non include token che eseguono l'autenticazione al server durante l'esecuzione di richieste successive, che funziona separatamente usando un cookie oggetto incluso nelle HttpClient richieste al server.

Questa versione dell'articolo illustra l'implementazione di OIDC con il modello Back-end per il front-end (BFF). Modificare il selettore della versione dell'articolo in OIDC senza modello BFF se la specifica dell'app non richiede l'adozione del modello BFF.

La specifica seguente è descritta:

  • L'app Blazor Web usa la modalità di rendering automatico con interattività globale.
  • I servizi provider di stato di autenticazione personalizzati vengono usati dal server e dalle app client per acquisire lo stato di autenticazione dell'utente e fluirlo tra il server e il client.
  • Questa app è un punto di partenza per qualsiasi flusso di autenticazione OIDC. OIDC viene configurato manualmente nell'app e non si basa su Microsoft Entra ID o pacchetti Web MicrosoftIdentity, né l'app di esempio richiede l'hosting di Microsoft Azure. Tuttavia, l'app di esempio può essere usata con Entra, Microsoft Identity Web e ospitata in Azure.
  • Aggiornamento automatico del token non interattivo.
  • Il modello Back-end per front-end (BFF) viene adottato usando .NET Aspire per l'individuazione del servizio e YARP per il proxy delle richieste a un endpoint di previsione meteo nell'app back-end.
    • Un'API Web back-end cookieusa l'autenticazione con connessione JWT per convalidare i token JWT salvati dall'app Web nell'accesso Blazor .
    • L'aspirare migliora l'esperienza di creazione di app native del cloud .NET. Fornisce un set di strumenti e modelli coerente e con opinioni per la creazione e l'esecuzione di app distribuite.
    • YARP (Yet Another Reverse Proxy) è una libreria usata per creare un server proxy inverso.

Per altre informazioni su .NET Aspire, vedere Disponibilità generale di : Semplificazione dello .NET Aspiresviluppo nativo del cloud .NET (maggio 2024).

Prerequisito

.NET Aspire richiede Visual Studio versione 17.10 o successiva.

Esempio di app

L'app di esempio è costituita da cinque progetti:

  • .NET Aspire:
    • Aspire.AppHost: usato per gestire i problemi di orchestrazione di alto livello dell'app.
    • Aspire.ServiceDefaults: contiene configurazioni di app predefinite .NET Aspire che possono essere estese e personalizzate in base alle esigenze.
  • MinimalApiJwt: API Web back-end contenente un esempio di endpoint API minimo per i dati meteo.
  • BlazorWebAppOidc: progetto lato server dell'app Blazor Web.
  • BlazorWebAppOidc.Client: progetto lato client dell'app Blazor Web.

Accedere alle app di esempio tramite la cartella della versione più recente dalla radice del repository con il collegamento seguente. I progetti si trovano nella BlazorWebAppOidcBff cartella per .NET 8 o versione successiva.

Visualizzare o scaricare il codice di esempio (procedura per il download)

.NET Aspire progetti

Per altre informazioni sull'uso .NET Aspire e sui .AppHost progetti e .ServiceDefaults dell'app di esempio, vedere la .NET Aspire documentazione.

Verificare di aver soddisfatto i prerequisiti per .NET Aspire. Per altre informazioni, vedere la sezione Prerequisiti di Avvio rapido: Creare la prima .NET Aspire app.

L'app di esempio configura solo un profilo di avvio HTTP non sicuro (http) da usare durante i test di sviluppo. Per altre informazioni, incluso un esempio di profili di impostazioni di avvio non sicure e sicure, vedere Consentire il trasporto non sicuro in .NET Aspire (.NET Aspire documentazione).

Progetto app Web sul lato Blazor server (BlazorWebAppOidc)

Il BlazorWebAppOidc progetto è il progetto lato server dell'app Blazor Web. Il progetto usa YARP per eseguire il proxy delle richieste a un endpoint delle previsioni meteo nel progetto API Web back-end (MinimalApiJwt) con l'oggetto access_token archiviato nell'autenticazione cookie.

Il BlazorWebAppOidc.http file può essere usato per testare la richiesta di dati meteo. Si noti che il BlazorWebAppOidc progetto deve essere in esecuzione per testare l'endpoint e l'endpoint è hardcoded nel file. Per altre informazioni, vedere Usare file .http in Visual Studio 2022.

Nota

Il progetto server usa IHttpContextAccessor/HttpContext, ma non per i componenti di cui è stato eseguito il rendering interattivo. Per altre informazioni, vedere Linee guida per la mitigazione delle minacce per ASP.NET rendering lato server interattivo CoreBlazor.

Impostazione

Questa sezione illustra come configurare l'app di esempio.

Nota

Per Microsoft Entra ID e Azure AD B2C, è possibile usare microsoft AddMicrosoftIdentityWebApp Identity Web (Microsoft.Identity.Web pacchetto NuGet, documentazione dell'API), che aggiunge sia i gestori OIDC Cookie che i gestori di autenticazione con le impostazioni predefinite appropriate. L'app di esempio e le indicazioni contenute in questa sezione non usano Microsoft Identity Web. Le linee guida illustrano come configurare manualmente il gestore OIDC per qualsiasi provider OIDC. Per altre informazioni sull'implementazione di Microsoft Identity Web, vedere le risorse collegate.

La configurazione seguente OpenIdConnectOptions è disponibile nel file del Program progetto nella chiamata a AddOpenIdConnect:

  • SignInScheme: imposta lo schema di autenticazione corrispondente al middleware responsabile della persistenza dell'identità dell'utente dopo un'autenticazione riuscita. Il gestore OIDC deve usare uno schema di accesso in grado di rendere persistenti le credenziali utente tra le richieste. La seguente riga è presente solo a scopo dimostrativo. Se omesso, DefaultSignInScheme viene usato come valore di fallback.

    oidcOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    
  • Ambiti per openid e () (Scopefacoltativo): anche gli openid ambiti e profile profile sono configurati per impostazione predefinita perché sono necessari per il funzionamento del gestore OIDC, ma potrebbe essere necessario aggiungerli nuovamente se gli ambiti sono inclusi nella Authentication:Schemes:MicrosoftOidc:Scope configurazione. Per indicazioni generali sulla configurazione, vedere Configurazione in ASP.NET Core e configurazione di ASP.NET CoreBlazor.

    oidcOptions.Scope.Add(OpenIdConnectScope.OpenIdProfile);
    
  • SaveTokens: definisce se i token di accesso e aggiornamento devono essere archiviati in AuthenticationProperties dopo un'autorizzazione riuscita. Il valore è impostato su true per autenticare le richieste di dati meteo dal progetto API Web back-end (MinimalApiJwt).

    oidcOptions.SaveTokens = true;
    
  • Ambito per l'accesso offline (Scope): l'ambito offline_access è obbligatorio per il token di aggiornamento.

    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
    
  • Ambiti per ottenere i dati meteo dall'API Web (Scope): l'ambito Weather.Get è configurato nel portale di Azure o Entra in Esporre un'API. Questa operazione è necessaria per il progetto API Web back-end (MinimalApiJwt) per convalidare il token di accesso con bearer JWT.

    oidcOptions.Scope.Add("{APP ID URI}/{API NAME}");
    

    Esempio:

    • URI ID app ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}
      • Nome directory ({DIRECTORY NAME}): contoso
      • ID applicazione (client) ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
    • Ambito configurato per i dati meteo da MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f/Weather.Get");
    

    L'esempio precedente riguarda un'app registrata in un tenant con un tipo di tenant AAD B2C. Se l'app viene registrata in un tenant ME-ID, l'URI ID app è diverso, quindi l'ambito è diverso.

    Esempio:

    • URI ID app ({APP ID URI}): api://{CLIENT ID} con ID applicazione (client) ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
    • Ambito configurato per i dati meteo da MinimalApiJwt ({API NAME}): Weather.Get
    oidcOptions.Scope.Add("api://4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f/Weather.Get");
    
  • Authority e ClientId: imposta l'autorità e l'ID client per le chiamate OIDC.

    oidcOptions.Authority = "{AUTHORITY}";
    oidcOptions.ClientId = "{CLIENT ID}";
    

    Esempio:

    • Autorità (): https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/ ({AUTHORITY}usa l'ID a3942615-d115-4eb7-bc84-9974abcf5064tenant )
    • ID client ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
    oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
    oidcOptions.ClientId = "4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
    

    Esempio per l'autorità "common" di Microsoft Azure:

    L'autorità "comune" deve essere usata per le app multi-tenant. È anche possibile usare l'autorità "comune" per le app a tenant singolo, ma è necessario un personalizzato IssuerValidator , come illustrato più avanti in questa sezione.

    oidcOptions.Authority = "https://login.microsoftonline.com/common/v2.0/";
    
  • ClientSecret: segreto client OIDC.

    L'esempio seguente è solo a scopo di test e dimostrazione. Non archiviare il segreto client nell'assembly dell'app o controllare il segreto nel controllo del codice sorgente. Archiviare il segreto client in Segreti utente, Azure Key Vault o una variabile di ambiente.

    La configurazione dello schema di autenticazione viene letta automaticamente da builder.Configuration["Authentication:Schemes:{SCHEME NAME}:{PropertyName}"], dove il {SCHEME NAME} segnaposto è lo schema, ovvero per MicrosoftOidc impostazione predefinita. Poiché la configurazione è preconfigurata, un segreto client può essere letto automaticamente tramite la Authentication:Schemes:MicrosoftOidc:ClientSecret chiave di configurazione. Nel server che usa variabili di ambiente assegnare alla variabile Authentication__Schemes__MicrosoftOidc__ClientSecretdi ambiente il nome :

    set Authentication__Schemes__MicrosoftOidc__ClientSecret={CLIENT SECRET}
    

    Solo per la dimostrazione e il test, ClientSecret è possibile impostare direttamente . Non impostare il valore direttamente per le app di produzione distribuite. Per una sicurezza leggermente migliorata, compilare in modo condizionale la riga con il DEBUG simbolo :

    #if DEBUG
    oidcOptions.ClientSecret = "{CLIENT SECRET}";
    #endif
    

    Esempio:

    Segreto client (): 463471c8c4...f90d674bc9 ({CLIENT SECRET}abbreviato per la visualizzazione)

    #if DEBUG
    oidcOptions.ClientSecret = "463471c8c4...137f90d674bc9";
    #endif
    
  • ResponseType: configura il gestore OIDC per eseguire solo il flusso del codice di autorizzazione. Le concessioni implicite e i flussi ibridi non sono necessari in questa modalità.

    Nella configurazione di registrazione dell'app Entra o portale di Azure implicita e dei flussi ibridi, non selezionare la casella di controllo relativa all'endpoint di autorizzazione per restituire token di accesso o token ID. Il gestore OIDC richiede automaticamente i token appropriati usando il codice restituito dall'endpoint di autorizzazione.

    oidcOptions.ResponseType = OpenIdConnectResponseType.Code;
    
  • MapInboundClaimse la configurazione di NameClaimType e : molti server OIDC usano "name" e "role" anziché le impostazioni predefinite SOAP/WS-Fed in ClaimTypesRoleClaimType. Quando MapInboundClaims è impostato su false, il gestore non esegue mapping delle attestazioni e i nomi delle attestazioni del token JWT vengono usati direttamente dall'app. Nell'esempio seguente il tipo di attestazione del ruolo viene impostato su "roles", appropriato per Microsoft Entra ID (ME-ID). Per altre informazioni, vedere la documentazione del provider di identità.

Nota

MapInboundClaims deve essere impostato su false per la maggior parte dei provider OIDC, che impedisce la ridenominazione delle attestazioni.

oidcOptions.MapInboundClaims = false;
oidcOptions.TokenValidationParameters.NameClaimType = JwtRegisteredClaimNames.Name;
oidcOptions.TokenValidationParameters.RoleClaimType = "roles";
  • Configurazione del percorso: i percorsi devono corrispondere all'URI di reindirizzamento (percorso di callback di accesso) e ai percorsi di reindirizzamento post disconnessione (percorso di callback con disconnessione) configurati durante la registrazione dell'applicazione con il provider OIDC. Nel portale di Azure i percorsi vengono configurati nel pannello Autenticazione della registrazione dell'app. Entrambi i percorsi di accesso e disconnessione devono essere registrati come URI di reindirizzamento. I valori predefiniti sono /signin-oidc e /signout-callback-oidc.

    • CallbackPath: percorso della richiesta all'interno del percorso di base dell'app in cui viene restituito l'agente utente.

      In Entra o portale di Azure impostare il percorso nell'URI di reindirizzamento della configurazione della piattaforma Web:

      https://localhost/signin-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi.

    • SignedOutCallbackPath: percorso della richiesta all'interno del percorso di base dell'app in cui viene restituito l'agente utente dopo la disconnessione dal provider di identità.

      In Entra o portale di Azure impostare il percorso nell'URI di reindirizzamento della configurazione della piattaforma Web:

      https://localhost/signout-callback-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi.

      Nota

      Se si usa Microsoft Identity Web, il provider attualmente reindirizza di nuovo a SignedOutCallbackPath se viene usata l'autorità microsoftonline.com (https://login.microsoftonline.com/{TENANT ID}/v2.0/). Questa limitazione non esiste se è possibile usare l'autorità "comune" con Microsoft Identity Web. Per altre informazioni, vedere postLogoutRedirectUri not working when authority URL contains a tenant ID (AzureAD/microsoft-authentication-library-for-js #5783).

    • RemoteSignOutPath: le richieste ricevute in questo percorso causano il richiamo della disconnessione da parte del gestore tramite lo schema di disconnessione.

      In Entra o portale di Azure impostare l'URL di disconnessione del canale anteriore:

      https://localhost/signout-oidc

      Nota

      Una porta non è necessaria per localhost gli indirizzi.

    oidcOptions.CallbackPath = new PathString("{PATH}");
    oidcOptions.SignedOutCallbackPath = new PathString("{PATH}");
    oidcOptions.RemoteSignOutPath = new PathString("{PATH}");
    

    Esempi (valori predefiniti):

    oidcOptions.CallbackPath = new PathString("/signin-oidc");
    oidcOptions.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
    oidcOptions.RemoteSignOutPath = new PathString("/signout-oidc");
    
  • (Microsoft Azure solo con l'endpoint "comune") TokenValidationParameters.IssuerValidator: molti provider OIDC funzionano con il validator predefinito dell'autorità di certificazione, ma è necessario tenere conto dell'autorità di certificazione con parametri con l'ID tenant ({TENANT ID}) restituito da https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. Per altre informazioni, vedere SecurityTokenInvalidIssuerException con OpenID Connect e l'endpoint "common" di Azure AD (AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet #1731).

    Solo per le app che usano Microsoft Entra ID o Azure AD B2C con l'endpoint "comune":

    var microsoftIssuerValidator = AadIssuerValidator.GetAadIssuerValidator(oidcOptions.Authority);
    oidcOptions.TokenValidationParameters.IssuerValidator = microsoftIssuerValidator.Validate;
    

Codice dell'app di esempio

Esaminare l'app di esempio per le funzionalità seguenti:

  • Aggiornamento automatico del token non interattivo con l'aiuto di un aggiornamento personalizzato cookie (CookieOidcRefresher.cs).
  • La PersistingAuthenticationStateProvider classe (PersistingAuthenticationStateProvider.cs) è un lato AuthenticationStateProvider server che usa PersistentComponentState per trasferire lo stato di autenticazione al client, che viene quindi risolto per la durata dell'applicazione WebAssembly.
  • Le richieste all'app Blazor Web vengono inoltrate tramite proxy al progetto API Web back-end (MinimalApiJwt). MapForwarder nel file aggiunge l'inoltro Program diretto di richieste HTTP che corrispondono al modello specificato a una destinazione specifica usando la configurazione predefinita per la richiesta in uscita, le trasformazioni personalizzate e il client HTTP predefinito:
    • Quando si esegue il rendering del Weather componente nel server, il componente usa ServerWeatherForecaster per proxyare la richiesta di dati meteo con il token di accesso dell'utente.
    • Quando viene eseguito il rendering del componente nel client, il componente usa l'implementazione del ClientWeatherForecaster servizio, che usa un preconfigurato HttpClient (nel file del Program progetto client) per effettuare una chiamata API Web al progetto server. Un endpoint API minimo (/weather-forecast) definito nel file del Program progetto server trasforma la richiesta con il token di accesso dell'utente per ottenere i dati meteo.

Per altre informazioni sulle chiamate API (Web) tramite astrazioni di servizio in Blazor App Web, vedere Chiamare un'API Web da un'app ASP.NET CoreBlazor.

Progetto app Web sul lato Blazor client (BlazorWebAppOidc.Client)

Il BlazorWebAppOidc.Client progetto è il progetto lato client dell'app Blazor Web.

La PersistentAuthenticationStateProvider classe (PersistentAuthenticationStateProvider.cs) è un lato AuthenticationStateProvider client che determina lo stato di autenticazione dell'utente cercando i dati persistenti nella pagina quando è stato eseguito il rendering nel server. Lo stato di autenticazione è fisso per la durata dell'applicazione WebAssembly.

Se l'utente deve accedere o disconnettersi, è necessario ricaricare una pagina completa.

L'app di esempio fornisce solo un nome utente e un messaggio di posta elettronica a scopo di visualizzazione. Non include token che eseguono l'autenticazione al server durante l'esecuzione di richieste successive, che funziona separatamente usando un cookie oggetto incluso nelle HttpClient richieste al server.

Progetto API Web back-end (MinimalApiJwt)

Il MinimalApiJwt progetto è un'API Web back-end per più progetti front-end. Il progetto configura un endpoint API minimo per i dati meteo. Le richieste dal progetto sul lato server dell'app Blazor Web (BlazorWebAppOidc) vengono inviate tramite proxy al MinimalApiJwt progetto.

Impostazione

Configurare il progetto nella JwtBearerOptions classe della AddJwtBearer chiamata nel file del Program progetto:

  • Audience: imposta il gruppo di destinatari per qualsiasi token OpenID Connect ricevuto.

    Nel portale di Azure o Entra: associare il valore solo al percorso dell'URI ID applicazione configurato quando si aggiunge l'ambito Weather.Get in Esporre un'API:

    jwtOptions.Audience = "{APP ID URI}";
    

    Esempio:

    URI ID app ({APP ID URI}): https://{DIRECTORY NAME}.onmicrosoft.com/{CLIENT ID}:

    • Nome directory ({DIRECTORY NAME}): contoso
    • ID applicazione (client) ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f
    jwtOptions.Audience = "https://contoso.onmicrosoft.com/4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
    

    L'esempio precedente riguarda un'app registrata in un tenant con un tipo di tenant AAD B2C. Se l'app viene registrata in un tenant ME-ID, l'URI ID app è diverso, quindi il gruppo di destinatari è diverso.

    Esempio:

    URI ID app ({APP ID URI}): api://{CLIENT ID} con ID applicazione (client) ({CLIENT ID}): 4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f

    jwtOptions.Audience = "api://4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f";
    
  • Authority: imposta l'autorità per l'esecuzione di chiamate OpenID Connect. Trovare la corrispondenza del valore con l'autorità configurata per il gestore OIDC in BlazorWebAppOidc/Program.cs:

    jwtOptions.Authority = "{AUTHORITY}";
    

    Esempio:

    Autorità (): https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/ ({AUTHORITY}usa l'ID a3942615-d115-4eb7-bc84-9974abcf5064tenant )

    jwtOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
    

    L'esempio precedente riguarda un'app registrata in un tenant con un tipo di tenant AAD B2C. Se l'app è registrata in un tenant ME-ID, l'autorità deve corrispondere all'issurer (iss) del token JWT restituito dal provider di identità:

    jwtOptions.Authority = "https://sts.windows.net/a3942615-d115-4eb7-bc84-9974abcf5064/";
    

API minima per i dati meteo

Proteggere l'endpoint dei dati delle previsioni meteo nel file del Program progetto:

app.MapGet("/weather-forecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
}).RequireAuthorization();

Il RequireAuthorization metodo di estensione richiede l'autorizzazione per la definizione di route. Per tutti i controller aggiunti al progetto, aggiungere l'attributo [Authorize] al controller o all'azione.

Aggiunta di componenti che adottano il rendering lato server interattivo

Poiché l'app usa il rendering automatico interattivo globale tramite il Routes componente , i singoli componenti che specificano il rendering lato server interattivo (SSR interattivo, @rendermode InteractiveServer) nel file di definizione del componente (.razor) vengono inseriti nella .Client cartella del Pages progetto.

L'inserimento di componenti SSR interattivi nel .Client progetto è anti-intuitivo perché tali componenti vengono visualizzati solo nel server.

Se si inserisce un componente SSR interattivo nella cartella del Components/Pages progetto server, il componente viene pre-risolto normalmente e brevemente visualizzato nel browser dell'utente. Tuttavia, il router lato client non è in grado di trovare il componente, con conseguente errore 404 - Non trovato nel browser.

Posizionare quindi componenti SSR interattivi nella .Client cartella del Pages progetto.

Reindirizzamento alla home page all'accesso

Quando un utente si sposta all'interno dell'app, il LogInOrOut componente (Layout/LogInOrOut.razor) imposta un campo nascosto per l'URL restituito (ReturnUrl) sul valore dell'URL corrente (currentURL). Quando l'utente si disconnette dall'app, il provider di identità li restituisce alla pagina da cui si è disconnesso.

Se l'utente si disconnette da una pagina sicura, viene restituito alla stessa pagina protetta dopo la disconnessione solo per essere restituito tramite il processo di autenticazione. Questo comportamento è corretto quando gli utenti devono cambiare account di frequente. Tuttavia, una specifica di app alternativa può richiedere che l'utente venga restituito alla home page dell'app o ad altre pagine dopo la disconnettersi. L'esempio seguente illustra come impostare la home page dell'app come URL restituito per le operazioni di disconnessione.

Le modifiche importanti apportate al LogInOrOut componente sono illustrate nell'esempio seguente. L'oggetto value del campo nascosto per è ReturnUrl impostato sulla home page in /. IDisposable non è più implementato. l'oggetto NavigationManager non viene più inserito. L'intero @code blocco viene rimosso.

Layout/LogInOrOut.razor:

@using Microsoft.AspNetCore.Authorization

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

Nonce crittografico

Un nonce è un valore stringa che associa la sessione di un client a un token ID per attenuare gli attacchi di riproduzione.

Se si riceve un errore nonce durante lo sviluppo e il test dell'autenticazione, usare una nuova sessione del browser InPrivate/incognito per ogni esecuzione di test, indipendentemente dalla piccola modifica apportata all'app o dall'utente di test perché i dati non aggiornati cookie possono causare un errore nonce. Per altre informazioni, vedere la sezione s e i dati del Cookiesito.

Un nonce non è obbligatorio o viene usato quando un token di aggiornamento viene scambiato per un nuovo token di accesso. Nell'app di esempio , (CookieOidcRefresherCookieOidcRefresher.cs) imposta OpenIdConnectProtocolValidator.RequireNonce deliberatamente su false.

Ruoli applicazione per le app non registrate con Microsoft Entra (ME-ID)

Questa sezione riguarda le app che non usano Microsoft Entra ID (ME-ID) come provider di identità. Per le app registrate con ME-ID, vedere la sezione Ruoli applicazione per le app registrate con Microsoft Entra (ME-ID).

Configurare il tipo di attestazione del ruolo (TokenValidationParameters.RoleClaimType) in OpenIdConnectOptions di Program.cs:

oidcOptions.TokenValidationParameters.RoleClaimType = "{ROLE CLAIM TYPE}";

Per molti provider di identità OIDC, il tipo di attestazione del ruolo è role. Controllare la documentazione del provider di identità per il valore corretto.

Sostituire la UserInfo classe nel BlazorWebAppOidc.Client progetto con la classe seguente.

UserInfo.cs:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using System.Security.Claims;

namespace BlazorWebAppOidc.Client;

// Add properties to this class and update the server and client 
// AuthenticationStateProviders to expose more information about 
// the authenticated user to the client.
public sealed class UserInfo
{
    public required string UserId { get; init; }
    public required string Name { get; init; }
    public required string[] Roles { get; init; }

    public const string UserIdClaimType = "sub";
    public const string NameClaimType = "name";
    private const string RoleClaimType = "role";

    public static UserInfo FromClaimsPrincipal(ClaimsPrincipal principal) =>
        new()
        {
            UserId = GetRequiredClaim(principal, UserIdClaimType),
            Name = GetRequiredClaim(principal, NameClaimType),
            Roles = principal.FindAll(RoleClaimType).Select(c => c.Value)
                .ToArray(),
        };

    public ClaimsPrincipal ToClaimsPrincipal() =>
        new(new ClaimsIdentity(
            Roles.Select(role => new Claim(RoleClaimType, role))
                .Concat([
                    new Claim(UserIdClaimType, UserId),
                    new Claim(NameClaimType, Name),
                ]),
            authenticationType: nameof(UserInfo),
            nameType: NameClaimType,
            roleType: RoleClaimType));

    private static string GetRequiredClaim(ClaimsPrincipal principal,
        string claimType) =>
            principal.FindFirst(claimType)?.Value ??
            throw new InvalidOperationException(
                $"Could not find required '{claimType}' claim.");
}

A questo punto, Razor i componenti possono adottare l'autorizzazione basata sui ruoli e basata su criteri. I ruoli applicazione vengono visualizzati nelle role attestazioni, un'attestazione per ogni ruolo.

Ruoli applicazione per le app registrate con Microsoft Entra (ME-ID)

Usare le indicazioni riportate in questa sezione per implementare i ruoli applicazione, i gruppi di sicurezza ME-ID e i ruoli di amministratore predefiniti ME-ID per le app usando Microsoft Entra ID (ME-ID).

L'approccio descritto in questa sezione configura ME-ID per inviare gruppi e ruoli nell'intestazione di autenticazione cookie . Quando gli utenti sono solo membri di alcuni gruppi di sicurezza e ruoli, l'approccio seguente dovrebbe funzionare per la maggior parte delle piattaforme di hosting senza riscontrare un problema per cui le intestazioni sono troppo lunghe, ad esempio con l'hosting IIS con un limite di lunghezza dell'intestazione predefinito di 16 KB (MaxRequestBytes). Se la lunghezza dell'intestazione è un problema dovuto all'appartenenza a gruppi o ruoli elevati, è consigliabile non seguire le indicazioni riportate in questa sezione a favore dell'implementazione di Microsoft Graph per ottenere i gruppi e i ruoli di un utente da ME-ID separatamente, un approccio che non gonfia le dimensioni dell'autenticazione cookie. Per altre informazioni, vedere Richiesta non valida - Richiesta troppo lunga - Server IIS (dotnet/aspnetcore #57545)..

Configurare il tipo di attestazione del ruolo (TokenValidationParameters.RoleClaimType) in OpenIdConnectOptions di Program.cs. Impostare il valore su roles:

oidcOptions.TokenValidationParameters.RoleClaimType = "roles";

Anche se non è possibile assegnare ruoli ai gruppi senza un account PREMIUM ME-ID, è possibile assegnare ruoli agli utenti e ricevere attestazioni di ruolo per gli utenti con un account Azure standard. Le indicazioni contenute in questa sezione non richiedono un account ME-ID Premium.

Quando si usa la directory predefinita, seguire le indicazioni riportate in Aggiungere ruoli dell'app all'applicazione e riceverli nel token (documentazione di ME-ID) per configurare e assegnare ruoli. Se non si usa la directory predefinita, modificare il manifesto dell'app nel portale di Azure per stabilire manualmente i ruoli dell'app nella appRoles voce del file manifesto. Per altre informazioni, vedere Configurare l'attestazione del ruolo (documentazione di ME-ID).

I gruppi di sicurezza di Azure di un utente arrivano nelle groups attestazioni e le assegnazioni di ruolo di amministratore ME-ID predefinite di un utente arrivano in attestazioni di IDwids () note. I valori per entrambi i tipi di attestazione sono GUID. Quando vengono ricevute dall'app, queste attestazioni possono essere usate per stabilire l'autorizzazione di ruoli e criteri nei Razor componenti.

Nel manifesto dell'app nel portale di Azure impostare l'attributo groupMembershipClaims su .All Un valore di All restituisce ME-ID inviando tutti i gruppi di sicurezza/distribuzione (groups attestazioni) e ruoli (wids attestazioni) dell'utente connesso. Per impostare l'attributo groupMembershipClaims :

  1. Aprire la registrazione dell'app nel portale di Azure.
  2. Selezionare Gestisci>manifesto nella barra laterale.
  3. Trovare l'attributo groupMembershipClaims .
  4. Impostare il valore su All ("groupMembershipClaims": "All").
  5. Selezionare il pulsante Salva.

Sostituire la UserInfo classe nel BlazorWebAppOidc.Client progetto con la classe seguente.

UserInfo.cs:

using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using System.Security.Claims;

namespace BlazorWebAppOidc.Client;

// Add properties to this class and update the server and client 
// AuthenticationStateProviders to expose more information about 
// the authenticated user to the client.
public sealed class UserInfo
{
    public required string UserId { get; init; }
    public required string Name { get; init; }
    public required string[] Roles { get; init; }
    public required string[] Groups { get; init; }
    public required string[] Wids { get; init; }

    public const string UserIdClaimType = "sub";
    public const string NameClaimType = "name";
    private const string RoleClaimType = "roles";
    private const string GroupsClaimType = "groups";
    private const string WidsClaimType = "wids";

    public static UserInfo FromClaimsPrincipal(ClaimsPrincipal principal) =>
        new()
        {
            UserId = GetRequiredClaim(principal, UserIdClaimType),
            Name = GetRequiredClaim(principal, NameClaimType),
            Roles = principal.FindAll(RoleClaimType).Select(c => c.Value)
                .ToArray(),
            Groups = principal.FindAll(GroupsClaimType).Select(c => c.Value)
                .ToArray(),
            Wids = principal.FindAll(WidsClaimType).Select(c => c.Value)
                .ToArray(),
        };

    public ClaimsPrincipal ToClaimsPrincipal() =>
        new(new ClaimsIdentity(
            Roles.Select(role => new Claim(RoleClaimType, role))
                .Concat(Groups.Select(role => new Claim(GroupsClaimType, role)))
                .Concat(Wids.Select(role => new Claim(WidsClaimType, role)))
                .Concat([
                    new Claim(UserIdClaimType, UserId),
                    new Claim(NameClaimType, Name),
                ]),
            authenticationType: nameof(UserInfo),
            nameType: NameClaimType,
            roleType: RoleClaimType));

    private static string GetRequiredClaim(ClaimsPrincipal principal,
        string claimType) =>
            principal.FindFirst(claimType)?.Value ??
            throw new InvalidOperationException(
                $"Could not find required '{claimType}' claim.");
}

A questo punto, Razor i componenti possono adottare l'autorizzazione basata sui ruoli e basata su criteri:

  • I ruoli applicazione vengono visualizzati nelle roles attestazioni, un'attestazione per ogni ruolo.
  • I gruppi di sicurezza vengono visualizzati nelle groups attestazioni, un'attestazione per gruppo. I GUID del gruppo di sicurezza vengono visualizzati nella portale di Azure quando si crea un gruppo di sicurezza e vengono elencati quando si seleziona Identity>Panoramica>Gruppi>di visualizzazione.
  • I ruoli di amministratore ME-ID predefiniti vengono visualizzati nelle wids attestazioni, un'attestazione per ogni ruolo. L'attestazione wids con un valore di b79fbf4d-3ef9-4689-8143-76b194e85509 viene sempre inviata da ME-ID per gli account non guest del tenant e non fa riferimento a un ruolo di amministratore. I GUID ruolo amministratore (ID modello di ruolo) vengono visualizzati nel portale di Azure quando si seleziona Ruoli e amministratori, seguiti dai puntini di sospensione (...) >Descrizione per il ruolo elencato. Gli ID modello di ruolo sono elencati anche in Ruoli predefiniti di Microsoft Entra (documentazione entra).

Risoluzione dei problemi

Registrazione

L'app server è un'app standard ASP.NET Core. Vedere le linee guida per la registrazione di ASP.NET Core per abilitare un livello di registrazione inferiore nell'app server.

Per abilitare la registrazione di debug o traccia per Blazor WebAssembly l'autenticazione, vedere la sezione Registrazione dell'autenticazione lato client di ASP.NET Core Blazor con il selettore della versione dell'articolo impostato su ASP.NET Core 7.0 o versione successiva.

Errori comuni

  • Configurazione errata dell'app o Identity del provider (IP)

    Gli errori più comuni sono causati da una configurazione errata. Di seguito sono riportati alcuni esempi:

    • A seconda dei requisiti dello scenario, un'autorità mancante o non corretta, istanza, ID tenant, dominio tenant, ID client o URI di reindirizzamento impedisce a un'app di autenticare i client.
    • Gli ambiti di richiesta non corretti impediscono ai client di accedere agli endpoint DELL'API Web del server.
    • Autorizzazioni DELL'API server non corrette o mancanti impediscono ai client di accedere agli endpoint DELL'API Web del server.
    • L'esecuzione dell'app in una porta diversa da quella configurata nell'URI di reindirizzamento della registrazione dell'app ip. Si noti che non è necessaria una porta per Microsoft Entra ID e un'app in esecuzione in un localhost indirizzo di test di sviluppo, ma la configurazione della porta dell'app e la porta in cui è in esecuzione l'app devono corrispondere per gli indirizzi nonlocalhost .

    La copertura della configurazione in questo articolo illustra esempi della configurazione corretta. Controllare attentamente la configurazione alla ricerca di errori di configurazione di app e IP.

    Se la configurazione è corretta:

    • Analizzare i log delle applicazioni.

    • Esaminare il traffico di rete tra l'app client e l'app IP o server con gli strumenti di sviluppo del browser. Spesso, un messaggio di errore esatto o un messaggio con un indizio sulla causa del problema viene restituito al client dall'app IP o server dopo aver effettuato una richiesta. Strumenti di sviluppo materiale sussidiario sono disponibili negli articoli seguenti:

    Il team della documentazione risponde al feedback e ai bug dei documenti negli articoli (aprire un problema dalla sezione Commenti e suggerimenti della pagina ), ma non è in grado di fornire supporto tecnico. Sono disponibili diversi forum di supporto pubblico per facilitare la risoluzione dei problemi di un'app. Consigliamo quanto segue:

    I forum precedenti non sono di proprietà o controllati da Microsoft.

    Per i report sui bug del framework non riservati, non sensibili e non riservati, aprire un problema con l'unità del prodotto ASP.NET Core. Non aprire un problema con l'unità di prodotto fino a quando non hai approfondito la causa di un problema e non puoi risolverlo autonomamente e con l'aiuto della community in un forum di supporto pubblico. L'unità prodotto non è in grado di risolvere i problemi relativi alle singole app interrotte a causa di semplici errori di configurazione o casi d'uso che coinvolgono servizi di terze parti. Se un report è sensibile o riservato in natura o descrive un potenziale difetto di sicurezza nel prodotto che gli utenti malintenzionati possono sfruttare, vedere Segnalazione di problemi di sicurezza e bug (dotnet/aspnetcorerepository GitHub).

  • Client non autorizzato per ME-ID

    info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Autorizzazione non riuscita. Questi requisiti non sono stati soddisfatti: DenyAnonymousAuthorizationRequirement: richiede un utente autenticato.

    Errore di callback di accesso da ME-ID:

    • Errore: unauthorized_client
    • Description (Descrizione): AADB2C90058: The provided application is not configured to allow public clients.

    Per risolvere l'errore:

    1. Nella portale di Azure accedere al manifesto dell'app.
    2. Impostare l'attributo allowPublicClient su null o .true

Cookies e i dati del sito

Cookies e i dati del sito possono persistere tra gli aggiornamenti delle app e interferire con i test e la risoluzione dei problemi. Cancellare quanto segue quando si apportano modifiche al codice dell'app, modifiche all'account utente con il provider o modifiche alla configurazione dell'app del provider:

  • Account di accesso cookieutente
  • App cookies
  • Dati del sito memorizzati nella cache e archiviati

Un approccio per evitare che i dati del sito e di s persistenti cookieinterferiscano con i test e la risoluzione dei problemi consiste nel:

  • Configurare un browser
    • Usare un browser per i test che è possibile configurare per eliminare tutti i cookie dati del sito e ogni volta che il browser viene chiuso.
    • Assicurarsi che il browser venga chiuso manualmente o dall'IDE per qualsiasi modifica apportata alla configurazione dell'app, dell'utente di test o del provider.
  • Usare un comando personalizzato per aprire un browser in modalità InPrivate o In incognito in Visual Studio:
    • Aprire la finestra di dialogo Sfoglia con dal pulsante Esegui di Visual Studio.
    • Seleziona il pulsante Aggiungi.
    • Specificare il percorso del browser nel campo Programma . I percorsi eseguibili seguenti sono percorsi di installazione tipici per Windows 10. Se il browser è installato in un percorso diverso o non si usa Windows 10, specificare il percorso dell'eseguibile del 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
    • Nel campo Argomenti specificare l'opzione della riga di comando usata dal browser per aprire in modalità InPrivate o Incognito. Alcuni browser richiedono l'URL dell'app.
      • Microsoft Edge: usare -inprivate.
      • Google Chrome: usare --incognito --new-window {URL}, dove il {URL} segnaposto è l'URL da aprire (ad esempio, https://localhost:5001).
      • Mozilla Firefox: usare -private -url {URL}, dove il {URL} segnaposto è l'URL da aprire (ad esempio, https://localhost:5001).
    • Specificare un nome nel campo Nome descrittivo. Ad esempio: Firefox Auth Testing.
    • Selezionare il pulsante OK.
    • Per evitare di dover selezionare il profilo del browser per ogni iterazione di test con un'app, impostare il profilo come predefinito con il pulsante Imposta come predefinito .
    • Assicurarsi che il browser sia chiuso dall'IDE per qualsiasi modifica apportata all'app, all'utente di test o alla configurazione del provider.

Aggiornamenti di app

Un'app funzionante potrebbe non riuscire immediatamente dopo l'aggiornamento di .NET Core SDK nel computer di sviluppo o la modifica delle versioni dei pacchetti all'interno dell'app. In alcuni casi i pacchetti incoerenti possono interrompere un'app quando si eseguono aggiornamenti principali. La maggior parte di questi problemi può essere risolta attenendosi alle istruzioni seguenti:

  1. Cancellare le cache dei pacchetti NuGet del sistema locale eseguendo dotnet nuget locals all --clear da una shell dei comandi.
  2. Eliminare le cartelle e obj del bin progetto.
  3. Ripristinare e ricompilare il progetto.
  4. Eliminare tutti i file nella cartella di distribuzione nel server prima di ridistribuire l'app.

Nota

L'uso di versioni del pacchetto incompatibili con il framework di destinazione dell'app non è supportato. Per informazioni su un pacchetto, usare La raccolta NuGet o Esplora pacchetti FuGet.

Eseguire l'app server

Durante il test e la risoluzione dei problemi dell'app Blazor Web, assicurarsi di eseguire l'app dal progetto server.

Esaminare l'utente

Il componente seguente UserClaims può essere usato direttamente nelle app o funge da base per un'ulteriore personalizzazione.

UserClaims.razor:

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

<PageTitle>User Claims</PageTitle>

<h1>User Claims</h1>

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

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

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

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

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

Risorse aggiuntive