
Focus su Blazor WebAssembly (WASM)
Blazor WebAssembly è l’opzione più adatta per creare applicazioni client per il consumo di API.
Punti Chiave
-
C# nel Browser: L’intero runtime .NET e la tua applicazione sono scaricati dal browser come file WebAssembly. Il codice C# viene eseguito direttamente nel browser in un sandbox.
-
Architettura SPA: Blazor WASM crea applicazioni Single Page Application (SPA), il che significa che l’applicazione viene caricata una volta e le successive interazioni utente aggiornano dinamicamente solo le parti necessarie della pagina, offrendo un’esperienza utente fluida.
-
Componenti Razor: Le interfacce utente sono costruite utilizzando i componenti Razor (
.razor), che combinano markup HTML con logica C# (usando la direttiva@code).
Scrivere un’app in Blazor significa usare una tecnologia Microsoft (C#) che però poggia su una base totalmente aperta e universale (WebAssembly). Questo garantisce che la tua app funzionerà su qualsiasi dispositivo moderno, senza dipendere da plugin proprietari
Focus su Auth0
-
Auth0 è un Identity Provider che usa il protocollo OIDC (OpenID Connect).
-
Blazor WASM è un client OIDC nativo e Microsoft fornisce le librerie
Microsoft.AspNetCore.Components.WebAssembly.Authenticationper gestirlo. -
L’applicazione Blazor reindirizza l’utente alla pagina di login Auth0 (Universal Login), riceve l’Access Token e lo memorizza.
Progetto Blazor WebAssembly
Creazione del Progetto in Visual Studio
-
Apri Visual Studio e crea un Nuovo Progetto.
-
Cerca e seleziona il template “Blazor WebAssembly App” (assicurati che non sia “Blazor Server App”).
-
Nella finestra di configurazione, per quanto riguarda l’Autenticazione, scegli “Nessuna”
✅ Riepilogo delle Tue Scelte (Consigliate)
| Opzione | Stato (Check) | Note |
| Applicazione Web Progressiva (PWA) | Deselezionato | Non necessario ora, aumenta la complessità. |
| Non usare istruzioni di primo livello | Deselezionato | Usa il codice moderno e conciso di .NET. |
| Configura per HTTPS | Selezionato | Essenziale. La tua app deve usare HTTPS per l’autenticazione con Auth0 (e per chiamare le API in produzione). |
| Include sample pages | Selezionato | Utile per avere un’architettura di base già pronta (layout, menu) e per testare velocemente l’autenticazione. |
Configurazione su Auth0.com
Applicazione
Nel portale Auth0 crea una nuova applicazione di tipo “Single Page Application“.
Nella applicazione , nella tab settings :
- prendi nota di : Domain e ClientID.
- Seleziona “Cross-Origin Authentication”
API
Nella sezione API , Clicca su + Create API. Devi compilare questi campi:
-
Name (Nome): Un nome descrittivo (es. “Mio Servizio Dati API”).
-
Identifier (Identificativo): Questo è l’Audience!
Il Campo Identifier (Audience)
L’Identificativo (Audience) deve essere un URI (Uniform Resource Identifier) e di solito ha questo formato:
Esempio Audience:
https://api.iltuoservizio.com
Importante: Non deve per forza essere un URL funzionante, ma deve essere un URI univoco.
Configurazione di Auth0 e delle Dipendenze
Pacchetti
Per autenticare un’applicazione Blazor WebAssembly con Auth0, devi utilizzare il supporto integrato di Microsoft per l’autenticazione OIDC (OpenID Connect), che è il protocollo utilizzato da Auth0. Con Nuget
- installa il pacchetto Microsoft.Authentication.WebAssembly.Msal
- installa il pacchetto Microsoft.AspNetCore.Components.WebAssembly.Authentication. Attenzione: installare la versione 8.0.1
- installa il pacchetto Microsoft.Extensions.Http
Configurazione Applicazione
Nelle applicazioni .NET (inclusi i client Blazor WASM), il file appsettings.json è lo standard per archiviare le configurazioni, come: le Credenziali di Autenticazione: (Il Domain e il Client ID di Auth0). Blazor WebAssembly è progettato per leggere le impostazioni da questo file. Crea il file appsettings.json nella directory wwwroot per mantenere le configurazioni separate dal codice (il che è una best practice).
{
"Auth0":
{
"Domain": "[IL-TUO-TENANT].auth0.com",
"Authority": "https://[IL-TUO-TENANT].auth0.com",
"ClientId": "[IL-TUO-CLIENT-ID-AUTH0.COM]",
"Audience": "https://api.iltuoservizio.com"
},
"TestWebservice:
{
"Address": "localhost:7003"
}
}
File Applicazione
Program.cs
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
// =========================================================
// >>> REGISTRAZIONI DI BASE (Devono venire prima di AddOidcAuthentication) <<<
// =========================================================
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<SignOutSessionStateManager>();
// =========================================================
// =========================================================
// >>> Parte cruciale per l'autenticazione Auth0/OIDC <<<
// =========================================================
builder.Services.AddOidcAuthentication(options =>
{
// Impostazione dell'Audience (CRUCIALE per chiamare le API)
// L'Audience deve essere passato come parametro aggiuntivo OIDC
options.ProviderOptions.AdditionalProviderParameters.Add(
"audience",
builder.Configuration["Auth0:Audience"]!
);
// Modifica o aggiungi questo per assegnare esplicitamente l'Authority
options.ProviderOptions.Authority = builder.Configuration["Auth0:Authority"]!;
// Assegna il ClientId
options.ProviderOptions.ClientId = builder.Configuration["Auth0:ClientId"]!;
// 3. Configurazione degli Scope
// Sostituiamo gli Scope predefiniti con la tua lista completa.
options.ProviderOptions.DefaultScopes.Clear(); // Rimuovi gli scope predefiniti
// Aggiungi tutti gli scope richiesti, inclusi quelli personalizzati:
options.ProviderOptions.DefaultScopes.Add("openid");
options.ProviderOptions.DefaultScopes.Add("profile");
options.ProviderOptions.DefaultScopes.Add("email");
options.ProviderOptions.DefaultScopes.Add("address");
options.ProviderOptions.DefaultScopes.Add("phone");
options.ProviderOptions.DefaultScopes.Add("read:appointments"); // <--- Scope API
});
// =========================================================
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
MainLayout.razor
Per mostrare lo stato di login, devi usare il componente Blazor integrato CascadingAuthenticationState nel file di layout principale.
Nel file Layout/MainLayout.razor, assicurati che il contenuto sia racchiuso in questo
@using Microsoft.AspNetCore.Components.Authorization @inherits LayoutComponentBase <div class="page"> <div class="sidebar"> <NavMenu /> </div> <CascadingAuthenticationState> <main> <div class="top-row px-4"> <LoginDisplay /> <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a> </div> <article class="content px-4"> @Body </article> </main> </CascadingAuthenticationState> </div>
LoginDisplay.razor
Crea la cartella Shared ed in essa il componente LoginDisplay.razor.
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject NavigationManager Navigation
@inject SignOutSessionStateManager SignOutManager
<AuthorizeView>
<Authorized>
Ciao, @context.User.Identity?.Name!
<button class="nav-link btn btn-link" @onclick="BeginSignOut">Log out</button>
</Authorized>
<NotAuthorized>
<a href="authentication/login">Log in</a>
</NotAuthorized>
</AuthorizeView>
@code {
[CascadingParameter]
private Task<AuthenticationState>? AuthenticationState { get; set; }
private async Task BeginSignOut()
{
// Reindirizza l'utente al flusso di Logout di Auth0 (tramite il gestore Blazor)
await SignOutManager.SetSignOutState();
Navigation.NavigateTo("authentication/logout");
}
}
Importante. Per usare questo componente è necessario aggiungere a _Imports.razor il collegamento alla cartella Shared.
Script di Autenticazione (index.html)
Devi semplicemente aggiungere il tag <script> mancante nel tuo index.html nella sezione <body>, prima del tag che carica Blazor (_framework/blazor.webassembly.js).
Aggiungi questa riga:
<script src="_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>
Authentication.razor
Crea il componente Pages/Authentication.razor
@page "/authentication/{action}"
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="@Action" />
@code {
[Parameter]
public string? Action { get; set; }
// NOTA BENE: Non è necessario dichiarare RouteData
// in questo componente specifico se usi solo l'Action
}
Configurazione Auth0.com (seconda parte)
Lanciando l’app vedrete che la scritta Login in alto compare ma compare con u lieve ritardo. Se spingo login , scrive “Checking login state…” , poi, dopo alcuni secondi, vieni reindirizzato su una pagina si Auth0.com con errore “Callback URL mismatch.The provided redirect_uri is not in the list of allowed callback URLs.”
Trovate la vostra applicazione :
- alla voce “Allowed Callback Urls” aggiungete : https://localhost:7004/authentication/login-callback
- alla voce “Allowed Logout Urls” aggiungete : https://localhost:7004/authentication/logout-callback
Riprovate. Dovreste avere implementato Login e Logout

