Perché autenticare con Entra ID

Nelle app Azure moderne l’identità è gestita da Microsoft Entra ID (il servizio prima noto come Azure AD). Come sviluppatori non implementiamo login e password: deleghiamo a Entra ID il rilascio di token standard (OAuth 2.0 / OpenID Connect) e usiamo la libreria MSAL (Microsoft Authentication Library) per ottenerli e presentarli alle API protette. Il compito d’esame AZ-204 è saper collegare la registrazione dell’app, il tipo di client e il flusso di acquisizione token allo scenario giusto.

Registrare l’app in Entra ID

Ogni applicazione che partecipa al flusso deve avere una App registration. Da lì ottieni i tre valori che configuri in MSAL:

  • Application (client) ID — identifica univocamente l’app.
  • Directory (tenant) ID — il tenant Entra ID. In authority puoi usare il tenant specifico (https://login.microsoftonline.com/{tenant}), organizations, consumers o common a seconda di chi deve autenticarsi (single-tenant vs multi-tenant vs account personali).
  • Redirect URI — dove Entra ID rimanda dopo il consenso; deve corrispondere esattamente a quello registrato, incluso lo schema (es. http://localhost per desktop, https://... per web).

Secret vs certificate

Se l’app è confidential (vedi sotto) deve autenticarsi verso Entra ID con una credenziale:

  • Client secret — stringa condivisa, semplice ma con scadenza e va custodita (idealmente in Azure Key Vault, mai in codice). Adatta a dev/test.
  • Certificate — coppia di chiavi, più sicura: solo la chiave pubblica sta in Entra ID, quella privata resta nel Key Vault o nell’host. È la scelta consigliata in produzione.

Public client vs confidential client

La distinzione è centrale:

  • Public client — app che non può custodire in modo sicuro un secret: desktop, mobile, SPA, CLI. Non usa credenziali proprie; si affida all’interazione dell’utente. In MSAL si usa PublicClientApplication.
  • Confidential client — app server (web app ASP.NET Core, API, daemon) che gira in un ambiente fidato e può usare secret o certificate. In MSAL si usa ConfidentialClientApplication. Solo qui ha senso il flow client credentials (daemon senza utente).

Scegliere il tipo sbagliato è un errore d’esame classico: una SPA o una app mobile è sempre public client.

MSAL: acquisizione e cache dei token

MSAL non serve solo a fare login: gestisce una token cache e il rinnovo automatico. Il pattern corretto è prima la cache, poi l’interazione:

try
{
    result = await app.AcquireTokenSilent(scopes, account)
                      .ExecuteAsync();
}
catch (MsalUiRequiredException)
{
    result = await app.AcquireTokenInteractive(scopes)
                      .ExecuteAsync();
}
  • AcquireTokenSilent cerca un access token valido in cache; se è scaduto, MSAL usa silenziosamente il refresh token per ottenerne uno nuovo. Nessuna UI.
  • Solo se il silent fallisce con MsalUiRequiredException (primo accesso, consenso mancante, MFA richiesta, sessione scaduta) si fa fallback interattivo.

Il messaggio chiave: non gestisci tu il refresh token. MSAL lo tiene in cache e lo riusa; il tuo codice deve solo chiamare AcquireTokenSilent a ogni richiesta e lasciare che la libreria decida se serve rinnovare.

ID token vs access token

Entra ID rilascia token con scopi diversi:

  • ID token — prova l’autenticazione dell’utente (chi è). Lo consumi nella tua app per identificare l’utente; non si manda a una web API.
  • Access token — serve l’autorizzazione verso una risorsa: contiene gli scope (es. User.Read, api://.../access_as_user) e va nell’header Authorization: Bearer ... verso l’API. Gli scope che passi ad AcquireToken... determinano risorsa e permessi.

Confondere i due è la trappola più frequente della sezione security dell’esame.

Trappole tipiche d’esame

  • Scenario: una web API deve autorizzare le chiamate. → Usa l’access token con gli scope corretti, non l’ID token (che serve solo a identificare l’utente lato app).
  • Scenario: il token è scaduto e vuoi rinnovarlo. → Chiama AcquireTokenSilent e lascia il refresh a MSAL; non implementare a mano la logica di refresh token.
  • Scenario: app mobile o SPA che vuole usare un client secret. → Sbagliato: sono public client, niente secret; la credenziale server vale solo per i confidential client.
  • Scenario: app in produzione che si autentica verso Entra ID. → Preferisci il certificate al client secret e conserva la chiave in Azure Key Vault.
  • Scenario: AcquireTokenSilent lancia MsalUiRequiredException. → È il segnale di fallback interattivo (consenso/MFA/nuovo login), non un errore da sopprimere.
  • Scenario: il redirect dopo login fallisce. → Verifica che il Redirect URI in MSAL coincida esattamente con quello registrato in Entra ID (schema, host, porta).