Come implementare il Single Sign-On con SAML 2.0 e OpenID Connect tra le applicazioni aziendali e Microsoft Entra ID o Google Workspace
Per implementare il Single Sign-On tra le applicazioni aziendali e Microsoft Entra ID o Google Workspace non si integra ogni applicazione con ogni identity provider: si mette al centro un broker di identità. Le applicazioni parlano un solo protocollo — OpenID Connect — con il broker; il broker parla SAML 2.0 o OIDC con Entra ID e Google Workspace. Il risultato è che una nuova applicazione richiede una configurazione (redirect URI e chiave di progetto) invece di N configurazioni SAML, e che aggiungere un nuovo identity provider non tocca il codice delle applicazioni già in produzione.
OIDC o SAML 2.0: quale usare, e dove
La domanda "SAML o OIDC?" ha risposte diverse a seconda del lato dell'integrazione. Fra le tue applicazioni e il broker conviene quasi sempre OIDC: è JSON, funziona con SPA e app mobile, gestisce il refresh dei token e non richiede parsing e validazione di XML firmato. Fra il broker e l'identity provider aziendale la scelta la detta l'IdP: Entra ID e Google Workspace supportano entrambi, ma molte configurazioni enterprise consolidate (e ADFS on-premise) espongono solo SAML 2.0.
| Criterio | OpenID Connect | SAML 2.0 |
|---|---|---|
| Formato | JSON / JWT | XML firmato |
| Trasporto tipico | Redirect HTTPS + POST su /token | HTTP-Redirect (AuthnRequest) + HTTP-POST (Response) |
| SPA e app mobile | Nativo (Authorization Code + PKCE) | Non adatto: richiede un backend che processi l'asserzione |
| Rinnovo sessione | Refresh token e prompt=none | Ri-autenticazione presso l'IdP |
| Attributi utente | Claim nell'ID token e /userinfo | Attribute Statement nell'asserzione |
| Logout globale | RP-Initiated Logout / Front-Channel | Single Logout (SLO), spesso implementato parzialmente |
| Sensibilità all'orologio | Bassa (tolleranza sui claim iat/exp) | Alta: NotBefore / NotOnOrAfter tipicamente ±5 minuti |
| Quando sceglierlo | Nuove app, API, mobile, integrazione con il broker | IdP enterprise legacy, ADFS, applicazioni SaaS che espongono solo SAML |
Se ti interessa il confronto teorico fra i protocolli, la trattazione estesa è in OAuth 2.0, OIDC e SAML: differenze e casi d'uso. Qui procediamo con la configurazione.
Passo 1 — Registra l'applicazione come progetto
Ogni applicazione che deleghi il login è un progetto: app web, app mobile e pannello di amministrazione sono tre progetti distinti, ciascuno con la propria chiave crittografica e le proprie policy. È quello che permette di imporre la 2FA obbligatoria sul pannello admin lasciandola opzionale sull'app pubblica, senza duplicare la base utenti.
- 1Crea il progetto nel tenant e annota il project key (pk_live_…): è l'identificativo pubblico usato nelle chiamate di autenticazione.
- 2Registra i redirect URI esatti, uno per ambiente. Il confronto è carattere per carattere: https://app.example.com/callback e https://app.example.com/callback/ sono due URI diversi.
- 3Imposta la durata della sessione e la policy 2FA del progetto (disabilitata, opzionale, obbligatoria).
- 4Genera una API key (ak_live_…) separata, se il backend dovrà anche fare provisioning: la chiave di progetto serve al login, la API key alle operazioni amministrative.
npm install @loginmaster/sdkimport { LoginMaster } from "@loginmaster/sdk";
const lm = new LoginMaster({
projectKey: process.env.LOGINMASTER_PROJECT_KEY,
tenant: "https://tenant.example.com",
});
// Nel callback OIDC: verifica il token a doppia firma (tenant + cloud)
const session = await lm.verifyToken(token);
if (session.valid) {
const userId = session.subject; // es. sub_9f2a7c
}Lo stesso vale lato .NET, con il middleware ASP.NET Core; entrambi i quickstart completi sono su Integrazione. Chi non usa TypeScript o .NET integra le stesse operazioni via REST: POST /v1/auth/token e POST /v1/auth/verify.
Passo 2 — Federare Microsoft Entra ID via OpenID Connect
È il percorso da preferire con Entra ID quando non ci sono vincoli storici. Nel portale Entra ID: App registrations → New registration.
- 1Supported account types: scegli "Accounts in this organizational directory only" per un SSO aziendale chiuso, oppure multitenant se devi accettare più directory clienti.
- 2Redirect URI (tipo Web): l'endpoint di callback del broker, non quello dell'applicazione finale.
- 3Certificates & secrets: genera un client secret (o, meglio, registra un certificato) e conservalo nel tenant del broker.
- 4API permissions: openid, profile, email. Aggiungi User.Read solo se ti serve leggere il profilo Graph; per il solo SSO non è necessario.
- 5Token configuration: aggiungi il claim dei gruppi se vuoi mappare i gruppi Entra sui ruoli applicativi.
https://login.microsoftonline.com/{tenantId}/v2.0/.well-known/openid-configurationDa quel documento il broker ricava automaticamente authorization endpoint, token endpoint e jwks_uri, quindi la rotazione delle chiavi di firma di Microsoft non richiede interventi manuali. I claim rilevanti dell'ID token sono:
| Claim | Contenuto | Uso consigliato |
|---|---|---|
| oid | Object ID immutabile dell'utente nella directory | Chiave di correlazione dell'identità: usa questo, non l'email |
| tid | Tenant ID della directory Entra | Verifica che l'utente venga dalla directory attesa (multitenant) |
| preferred_username | UPN o email di accesso | Visualizzazione; può cambiare nel tempo |
| Indirizzo email | Notifiche; non usarlo come identificatore stabile | |
| groups / roles | Gruppi o app role assegnati | Mappatura sui ruoli di progetto |
Passo 3 — Federare Microsoft Entra ID via SAML 2.0
Serve quando l'organizzazione ha già standardizzato su SAML o quando l'IdP è ADFS on-premise. Nel portale: Enterprise applications → New application → Create your own application → Integrate any other application, poi Single sign-on → SAML.
| Campo Entra ID | Cosa inserire | Nome nello standard SAML |
|---|---|---|
| Identifier (Entity ID) | L'identificativo univoco del Service Provider, es. https://tenant.example.com/saml/metadata | SP EntityID |
| Reply URL | L'endpoint che riceve l'asserzione firmata, es. https://tenant.example.com/saml/acs | Assertion Consumer Service (ACS) URL |
| Sign on URL | Punto di ingresso per il flusso SP-initiated | SP-initiated SSO URL |
| Logout URL | Endpoint di Single Logout, se lo implementi | SLO endpoint |
| User Identifier (Name ID) | user.objectid, non user.mail | NameID (formato persistent) |
Scarica poi la Federation Metadata XML e caricala sul broker: contiene EntityID dell'IdP, endpoint SSO e certificato di firma, e la sua importazione evita la trascrizione manuale del certificato.
https://login.microsoftonline.com/{tenantId}/federationmetadata/2007-06/federationmetadata.xmlSul NameID vale la stessa regola del claim oid: imposta user.objectid con formato persistent. Il valore predefinito di Entra ID è spesso l'indirizzo email, ed è la causa numero uno degli account duplicati dopo una riorganizzazione aziendale.
Rotazione del certificato di firma
I certificati SAML di Entra ID hanno una validità predefinita di tre anni e la scadenza interrompe il login di tutti gli utenti nello stesso istante. Due contromisure concrete: configurare le notifiche di scadenza su una casella presidiata, e importare i metadata dell'IdP via URL invece che come file, così il broker rilegge il certificato senza un intervento manuale programmato tre anni prima.
Passo 4 — Federare Google Workspace via OpenID Connect
Google espone un discovery document pubblico e un unico issuer per tutti i domini, quindi la configurazione è più breve di quella di Entra ID — ma con un requisito di sicurezza in più.
https://accounts.google.com/.well-known/openid-configuration- 1In Google Cloud Console crea un progetto e, in APIs & Services → Credentials, un OAuth 2.0 Client ID di tipo Web application.
- 2Authorized redirect URIs: l'endpoint di callback del broker (esatto, https, senza slash finale se non lo usi).
- 3Configura la OAuth consent screen come Internal se vuoi limitarla al solo dominio Workspace.
- 4Scope richiesti: openid, email, profile.
- 5Valida il claim hd (hosted domain) a ogni login lato broker: senza questo controllo, qualunque account Gmail personale che passa dalla stessa schermata di consenso è tecnicamente un login valido.
Passo 5 — Federare Google Workspace via SAML 2.0
Nella Admin console: Apps → Web and mobile apps → Add app → Add custom SAML app. Google mostra i propri metadata (SSO URL, Entity ID, certificato) da caricare sul broker; poi si compilano ACS URL ed Entity ID del Service Provider.
- 1Copia o scarica i metadata IdP di Google e importali sul broker.
- 2Service provider details: ACS URL ed Entity ID del broker; Name ID format PERSISTENT e Name ID = Basic Information > Primary email (oppure un attributo custom immutabile, se lo gestisci).
- 3Attribute mapping: mappa almeno primary email, first name, last name; aggiungi i gruppi se ti servono per i ruoli.
- 4User access: assegna l'app alle unità organizzative o ai gruppi che devono accedere. Se salti questo passo il login fallisce con app_not_configured_for_user.
- 5Attendi la propagazione: le modifiche alla Admin console possono richiedere alcuni minuti prima di essere effettive su tutti gli utenti.
Passo 6 — Mappare claim e gruppi sui ruoli applicativi
Il valore vero del SSO federato non è risparmiare una password: è che l'autorizzazione smette di vivere in una tabella locale che nessuno aggiorna. Un utente che cambia reparto cambia gruppo nella directory, e il ruolo applicativo lo segue al login successivo senza ticket all'IT.
| Sorgente | Esempio | Ruolo di progetto |
|---|---|---|
| Gruppo Entra ID (claim groups) | GRP-FINANCE-APPROVERS | approver |
| App role Entra ID (claim roles) | Admin.Billing | billing-admin |
| Gruppo Google Workspace | amministrazione@example.com | admin |
| Attributo custom Workspace | department = Support | support-agent |
| Dominio email verificato (claim hd) | example.com | member (ruolo di base) |
Due regole che evitano incidenti: assegna sempre un ruolo di base minimo a chi si autentica ma non corrisponde a nessuna regola (invece di ereditare l'ultimo ruolo noto), e ricalcola i ruoli a ogni login invece che solo alla creazione dell'account. Il secondo punto è ciò che rende effettiva la revoca dei privilegi, non solo quella dell'accesso.
Se i gruppi da propagare sono molti, considera che Entra ID "sovraccarica" il token oltre una certa soglia di gruppi e restituisce un riferimento Graph invece dell'elenco: in quel caso conviene mappare app role espliciti anziché gruppi grezzi.
Passo 7 — Sessione, revoca e deprovisioning
Il SSO è metà del problema; l'altra metà è cosa succede quando l'accesso deve cessare. Con la federazione, disattivare l'account nella directory aziendale interrompe l'emissione di nuove sessioni sui servizi federati: non serve ricordarsi di disattivare l'utente su ogni piattaforma. La finestra residua è la durata dei token già emessi, ed è per questo che va dimensionata consapevolmente.
| Scenario | Effetto | Leva di configurazione |
|---|---|---|
| Account disabilitato nell'IdP | Nessuna nuova sessione federata | Immediato al successivo login |
| Token di accesso già emesso | Resta valido fino alla scadenza | Durata del token di progetto (es. 3600 s) |
| Revoca immediata necessaria | Sessione chiusa lato applicazione | Webhook subject.deactivated + invalidazione lato app |
| Cambio di ruolo | Permessi aggiornati al login successivo | Ricalcolo dei ruoli a ogni autenticazione |
| Dispositivo smarrito | Chiusura delle sessioni attive | Pagina di gestione sessioni dell'utente |
Per la revoca immediata la leva è il webhook: il broker notifica l'applicazione dell'evento e l'applicazione invalida la propria sessione, senza polling.
POST /hooks/loginmaster HTTP/1.1
X-LoginMaster-Signature: sha256=9f86d081884c...
Content-Type: application/json
{
"id": "evt_7c1e2f",
"type": "subject.deactivated",
"createdAt": "2026-09-10T09:24:00Z",
"tenant": "https://tenant.example.com",
"data": { "subjectId": "sub_9f2a7c", "project": "prj_12ab" }
}Il ciclo di vita completo (creazione, cambio ruolo, sospensione, cancellazione) è trattato in Provisioning e ciclo di vita degli utenti via REST API e SDK.
Il collaudo: nove verifiche prima del rilascio
- 1Login SP-initiated: dall'applicazione, utente non ancora autenticato presso l'IdP.
- 2Login IdP-initiated: dal portale Microsoft o Google (solo SAML; con OIDC non esiste e chiederlo è un segnale di requisito mal posto).
- 3Utente valido ma non assegnato all'applicazione: deve fallire con un messaggio comprensibile, non con una pagina bianca.
- 4Utente di un dominio esterno: deve essere respinto (verifica del claim hd o del tid).
- 5Sessione scaduta: rinnovo silenzioso e, se non possibile, ritorno pulito alla schermata di login.
- 6Logout: verifica se la sessione IdP resta aperta; con SLO parziale l'utente 'esce' e rientra con un clic, e va documentato.
- 7Account disabilitato nell'IdP: nuovo login rifiutato entro il tempo atteso.
- 8Orologio disallineato: sposta l'ora di un client di 10 minuti e verifica il messaggio d'errore (SAML fallirà sulle condizioni NotBefore / NotOnOrAfter).
- 9Rotazione del certificato di firma: simulala in ambiente di test, non scoprirla in produzione.
Errori tipici e come si leggono
| Sintomo | Causa più probabile | Correzione |
|---|---|---|
| AADSTS50011 | Redirect URI non corrispondente a quello registrato | Allinea carattere per carattere, slash finale compreso |
| AADSTS700016 | Applicazione non trovata nella directory | Client ID errato o app registrata in un altro tenant |
| AADSTS50105 | Utente non assegnato all'applicazione | Assegna utente o gruppo alla Enterprise application |
| app_not_configured_for_user (Google) | App SAML non assegnata all'unità organizzativa | Assegna l'app all'OU o al gruppo in Admin console |
| Signature validation failed | Certificato dell'IdP scaduto o non aggiornato sul SP | Reimporta i metadata dell'IdP, meglio se via URL |
| Asserzione rifiutata per condizioni temporali | Disallineamento di orologio fra IdP e SP | Sincronizza via NTP; tolleranza tipica ±5 minuti |
| Utenti duplicati dopo una riorganizzazione | Identità correlata sull'email invece che su un ID immutabile | Correla su oid / sub / NameID persistent |
| invalid_client sul token endpoint | Client secret scaduto | Ruota il secret e programma la scadenza successiva |
Broker gestito, self-hosting o integrazione diretta
Le tre strade sono tutte percorribili, ma hanno profili di costo e di rischio molto diversi. Il confronto onesto è sul lavoro che resta da fare dopo il primo login riuscito.
| Aspetto | Integrazione diretta app-per-app | Broker self-hosted (es. Keycloak) | Broker gestito (LoginMaster) |
|---|---|---|---|
| Configurazioni da mantenere | N app × M identity provider | 1 per IdP, ma con l'infrastruttura a carico tuo | 1 per IdP, infrastruttura gestita |
| Rotazione certificati SAML | Manuale su ogni applicazione | Centralizzata, da presidiare | Centralizzata, tramite metadata URL |
| Patch e CVE dell'IdP | A carico di ogni team applicativo | A carico del tuo team (upgrade major inclusi) | A carico del fornitore |
| Isolamento fra clienti/tenant | Da progettare | Realm separati, isolamento logico | Isolamento crittografico: token firmati per tenant e progetto |
| Reset credenziali da parte dell'admin | Dipende dall'app | Possibile dall'admin del realm | Tecnicamente impossibile: solo l'utente |
| Costo al crescere degli utenti | Nascosto nel tempo dei team | Infrastruttura + presidio | Per tenant e progetto, utenti illimitati |
| Giurisdizione dei dati | Variabile | Dove lo installi | UE, dati personali solo nel tenant |
Il punto che distingue LoginMaster nella riga più in basso non è commerciale ma architetturale: il token restituito all'applicazione porta due firme indipendenti, una del tenant e una del cloud, e un token emesso per il tenant A fallisce la validazione nel contesto del tenant B anche se i due condividono il deployment. Il dettaglio dell'architettura è su Sicurezza, mentre la pagina SSO raccoglie le funzionalità di federazione disponibili. Chi arriva da un'installazione Keycloak trova il percorso completo in Migrare da Keycloak self-hosted a un IAM gestito.
Da dove viene questa guida
LoginMaster è la piattaforma IAM di CDBKR S.r.l., società italiana che sviluppa e gestisce l'infrastruttura di autenticazione per software house, MSP e organizzazioni enterprise europee. Le procedure qui descritte sono quelle che il team applica nei progetti di federazione verso Entra ID e Google Workspace, incluso il caso in cui le due directory convivono nella stessa organizzazione. Un esempio reale di adozione è documentato nei case study; per una valutazione sul proprio scenario il punto di partenza è la pagina contatti.
Domande frequenti
Dipende dal lato dell'integrazione. Fra le tue applicazioni e il broker di identità usa OpenID Connect: è JSON, supporta SPA e app mobile con Authorization Code + PKCE e gestisce il rinnovo dei token. Fra il broker e Entra ID scegli OIDC se non hai vincoli storici; usa SAML 2.0 se l'organizzazione ha già standardizzato su SAML o se l'identity provider è ADFS on-premise. Non serve che tutte le applicazioni parlino lo stesso protocollo dell'identity provider: è esattamente il lavoro che fa il broker.
Sì, ed è uno scenario frequente dopo acquisizioni o in aziende con reparti su suite diverse. Il broker registra entrambi gli identity provider e presenta all'utente la scelta, oppure indirizza automaticamente in base al dominio dell'indirizzo email inserito (home realm discovery). Le applicazioni non vedono la differenza: ricevono sempre un token OIDC con lo stesso formato di claim, indipendentemente dall'IdP che ha autenticato l'utente.
La configurazione tecnica di una federazione OIDC verso Entra ID o Google Workspace è dell'ordine di poche ore: registrazione dell'app lato IdP, redirect URI, scope e mappatura dei claim. Il percorso SAML 2.0 richiede in più lo scambio dei metadata e la verifica del NameID. Il tempo reale di un progetto è quasi sempre dominato dal collaudo — utenti non assegnati, domini esterni, revoca, rotazione certificati — non dalla configurazione iniziale.
L'accesso ai servizi federati cessa senza interventi manuali: la directory aziendale non autentica più l'utente, quindi il broker non emette nuove sessioni. I token già emessi restano validi fino alla scadenza configurata (tipicamente un'ora), quindi per una revoca immediata si usa il webhook subject.deactivated, che notifica l'applicazione perché invalidi la propria sessione. È la differenza fra revocare l'accesso e revocare la sessione in corso: vanno progettate entrambe.
Perché l'email cambia: matrimoni, cambi di cognome, fusioni di dominio, riorganizzazioni. Se l'identità applicativa è agganciata all'email, al login successivo l'utente risulta una persona nuova e perde storico, ruoli e dati. Correla sempre su un identificatore immutabile: il claim oid in Entra ID, il claim sub in Google, il NameID di formato persistent in SAML. L'email resta un attributo utile, ma aggiornabile.
Nel SSO federato le password non transitano mai dal broker: l'utente si autentica presso Entra ID o Google e il broker riceve solo un'asserzione o un ID token. Per gli utenti locali — quelli non federati, tipici degli scenari misti con partner e clienti finali — la risposta dipende dal fornitore. In LoginMaster le credenziali sono protette con Argon2 e split-salt fra tenant e cloud, e non esiste una funzione che restituisca o reimposti la password di un utente: nemmeno l'amministratore del tenant può farlo.
Il broker può agire da Identity Provider SAML verso quelle applicazioni, pur restando Service Provider verso Entra ID o Google Workspace. In pratica l'applicazione legacy vede un IdP SAML classico (Entity ID, ACS URL, certificato di firma) mentre a monte l'autenticazione avviene sulla directory aziendale. Così non si tocca il codice dell'applicazione e non si duplicano le credenziali, che è la ragione principale per cui la migrazione di quelle applicazioni viene rimandata per anni.
Si aggiunge. Se l'identity provider aziendale applica già la MFA, il broker può accettarla e non richiederne una seconda, leggendo le informazioni di autenticazione presenti nel token. Se invece serve un secondo fattore specifico su applicazioni sensibili — un pannello di amministrazione, un'area con dati finanziari — la policy si imposta a livello di progetto, indipendentemente da quello che fa l'IdP. Il dettaglio delle policy TOTP e di accesso condizionale è nella guida dedicata su LoginMaster.
Vuoi vedere LoginMaster in azione?
Richiedi una demo personalizzata e scopri come gestire identità e accessi in modo sicuro e conforme.