Microsoft Entra è la famiglia di prodotti per la gestione delle identità e dell’accesso (IAM) e della sicurezza di Microsoft (noto in passato principalmente come Azure Active Directory o Azure AD).
Non si tratta di un singolo servizio, ma di un ecosistema completo che comprende:
- Microsoft Entra ID:Il motore centrale di cloud identity (il successore di Azure AD), che gestisce utenti, gruppi e l’accesso ad applicazioni aziendali e cloud.
- Microsoft Entra External ID: Per la gestione delle identità dei clienti e dei partner (CIAM).
- Microsoft Entra Permissions Management: Per il controllo dei permessi e della sicurezza multi-cloud.
In un’applicazione moderna, l’utilizzo di Entra ID permette di delegare l’autenticazione (chi è l’utente) e l’autorizzazione (a cosa può accedere) direttamente a Microsoft, sfruttando standard aperti come OAuth 2.0 e OpenID Connect (OIDC), e integrando nativamente funzionalità di sicurezza avanzate come l’Autenticazione a più fattori (MFA) e i criteri di accesso condizionale.
Integrazione in un’applicazione Web .NET Core 10
Nelle ultime versioni del framework, e pienamente supportato in .NET 10, il modo migliore per integrare Microsoft Entra ID è l’utilizzo della libreria Microsoft.Identity.Web. Questa libreria semplifica drasticamente la configurazione e la gestione dei token di sicurezza.
1. Installazione dei pacchetti NuGet
Dalla riga di comando del tuo progetto .NET 10, installa i pacchetti necessari:
dotnet add package Microsoft.Identity.Web dotnet add package Microsoft.Identity.Web.UI
2. Configurazione in appsettings.json
Aggiungi la sezione dedicata alla tua applicazione registrata su Microsoft Entra ID:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "IL_TUO_TENANT_ID",
"ClientId": "IL_TUO_CLIENT_ID",
"ClientSecret": "IL_TUO_CLIENT_SECRET",
"CallbackPath": "/signin-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
3. Configurazione dei servizi in Program.cs
Nel file Program.cs della tua applicazione web .NET 10, configura l’autenticazione basata su OpenID Connect usando Microsoft.Identity.Web:
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
var builder = WebApplication.CreateBuilder(args);
// Aggiunge l'autenticazione Microsoft Entra ID all'app
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
builder.Services.AddControllersWithViews()
.AddMicrosoftIdentityUI(); // Aggiunge le pagine pronte per Login/Logout
var app = builder.Build();
// Configurazione della pipeline HTTP
if (!app.Environment.IsDevelopment())
{
app.ExceptionHandler("/Home/Error");
app.Hsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// Middleware di autenticazione e autorizzazione (fondamentale l'ordine)
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages(); // Necessario per le rotte UI di Microsoft.Identity.Web
app.Run();
4. Protezione dei Controller e utilizzo dei dati utente
Ora puoi proteggere qualsiasi controller o singola azione utilizzando l’attributo [Authorize] e accedere facilmente alle informazioni del profilo utente fornite dai token di Entra ID:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
[Authorize] // Richiede che l'utente sia autenticato tramite Microsoft Entra
public class ProfiloController : Controller
{
public IActionResult Index()
{
// Recupera i claims dell'utente autenticato (es. nome, email)
var nomeUtente = User.Identity?.Name;
var email = User.FindFirst("preferred_username")?.Value;
ViewData["NomeUtente"] = nomeUtente;
ViewData["Email"] = email;
return View();
}
}
Quando un utente visita la rotta protetta,
.NET Corereindirizzerà automaticamente il browser alla pagina di login ospitata da Microsoft Entra ID. Una volta inserite le credenziali (e superata l’eventuale MFA), l’utente tornerà all’applicazione con una sessione sicura gestita tramite cookie crittografati.Per estendere la tua applicazione .NET Core 10 e consentirle di chiamare Microsoft Graph (ad esempio per leggere il profilo dell’utente autenticato, l’elenco dei suoi messaggi o dei suoi file su OneDrive), dobbiamo configurare i permessi corretti e utilizzare i pacchetti dedicati per l’integrazione del client Graph.
Ecco i passaggi dettagliati con gli esempi di codice.
1. Installazione dei pacchetti NuGet
Installa il pacchetto che semplifica l’integrazione di Microsoft Graph con
Microsoft.Identity.Web:dotnet add package Microsoft.Identity.Web.GraphSdk2. Aggiornamento della configurazione (
appsettings.json)Per chiamare Microsoft Graph, la tua applicazione ha bisogno di conoscere quali permessi (scopes) richiedere all’utente. Aggiungi la sezione
DownstreamApi(oMicrosoftGraph) al tuoappsettings.json:{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "IL_TUO_TENANT_ID", "ClientId": "IL_TUO_CLIENT_ID", "ClientSecret": "IL_TUO_CLIENT_SECRET", "CallbackPath": "/signin-oidc", // Definiamo i permessi (Scopes) necessari per Microsoft Graph "Scopes": "User.Read Mail.Read" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }3. Configurazione dei servizi in
Program.csDobbiamo aggiornare la pipeline di autenticazione per indicare che l’applicazione richiederà un codice di accesso (token) da usare per invocare le API di Microsoft Graph per conto dell’utente loggato (
EnableTokenAcquisitionToCallDownstreamApi):using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.Identity.Web; using Microsoft.Identity.Web.UI; var builder = WebApplication.CreateBuilder(args); // Configurazione dell'autenticazione con supporto a Microsoft Graph builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) // Aggiunge il supporto per acquisire token e abilitare l'SDK di Microsoft Graph .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("AzureAd")) .AddInMemoryTokenCaches(); // O un sistema di cache distribuito (es. Redis) per produzione builder.Services.AddControllersWithViews() .AddMicrosoftIdentityUI(); var app = builder.Build(); // Pipeline HTTP standard... if (!app.Environment.IsDevelopment()) { app.ExceptionHandler("/Home/Error"); app.Hsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapRazorPages(); app.Run();4. Utilizzo di Microsoft Graph in un Controller
Ora puoi iniettare l’oggetto
GraphServiceClientdirettamente all’interno di un Controller tramite Dependency Injection. Grazie aMicrosoft.Identity.Web, il token di accesso viene gestito e rinnovato in modo del tutto trasparente.using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Graph; using Microsoft.Identity.Web; [Authorize] public class GraphController : Controller { private readonly GraphServiceClient _graphServiceClient; // GraphServiceClient viene iniettato automaticamente dal container IoC di .NET public GraphController(GraphServiceClient graphServiceClient) { _graphServiceClient = graphServiceClient; } public async Task<IActionResult> Index() { try { // 1. Chiamata per ottenere il profilo dell'utente loggato da Microsoft Graph var user = await _graphServiceClient.Me.GetAsync(); // 2. Esempio di chiamata multipla: recupero dei messaggi recenti (richiede Mail.Read) var messages = await _graphServiceClient.Me.Messages.GetAsync(config => { config.QueryParameters.Top = 5; // Prendi solo i primi 5 messaggi config.QueryParameters.Select = new[] { "subject", "receivedDateTime", "from" }; }); // Passiamo i dati alla View ViewData["DisplayName"] = user?.DisplayName; ViewData["UserPrincipalName"] = user?.UserPrincipalName; ViewData["Messages"] = messages?.Value; return View(); } // Se l'utente non ha acconsentito ai permessi richiesti, gestiamo la richiesta di consenso incrementale catch (Microsoft.Identity.Web.TokenAcquisitionException ex) { // Richiede all'utente di concedere i permessi mancanti (es. Mail.Read) _tokenAcquisition.ReplyForbiddenWithHttperception(ex, new[] { "User.Read", "Mail.Read" }); throw; } } }5. Esempio di View (
Index.cshtml) per mostrare i datiAll’interno della tua vista Razor puoi stampare le informazioni recuperate:
@{ ViewData["Title"] = "Profilo Microsoft Graph"; } <div class="text-center"> <h1>Benvenuto, @ViewData["DisplayName"]!</h1> <p class="text-muted">Username: @ViewData["UserPrincipalName"]</p> </div> <hr /> <h3>I tuoi ultimi messaggi email (tramite Microsoft Graph):</h3> @if (ViewData["Messages"] is IEnumerable<Microsoft.Graph.Models.Message> messages && messages.Any()) { <ul class="list-group"> @foreach (var message in messages) { <li class="list-group-item"> <strong>@message.Subject</strong> <span class="text-muted small">(Da: @message.From?.EmailAddress?.Name)</span> </li> } </ul> } else { <p>Nessun messaggio trovato o permessi non ancora concessi.</p> }Nota di sicurezza importante (Consenso dell’utente)
La prima volta che un utente effettuerà il login e visiterà la pagina che usa Microsoft Graph, Entra ID mostrerà una schermata di consenso (Consent Screen) in cui chiederà all’utente di autorizzare l’applicazione ad accedere ai suoi dati (profilo ed email, in base agli
Scopesdefiniti).