Microsoft Identity Platform e flusso con concessione implicita di OAuth 2.0
Microsoft Identity Platform supporta il flusso di concessione implicita OAuth 2.0 come descritto nella specifica OAuth 2.0. La caratteristica che definisce la concessione implicita è che i token (token ID o token di accesso) vengono restituiti direttamente dall'endpoint /authorize anziché dall'endpoint /token. Viene spesso usato come parte del flusso del codice di autorizzazione, in quello che viene chiamato flusso ibrido, recuperando il token ID nella richiesta /authorize insieme a un codice di autorizzazione.
Questo articolo descrive come programmare direttamente in base al protocollo nell'applicazione per richiedere i token da Microsoft Entra ID. Quando possibile, è consigliabile usare le librerie di autenticazione Microsoft (MSAL) supportate anziché acquisire i token e chiamare le API Web protette. Per un elenco di esempi di codice che usano MSAL, fare riferimento agli esempi di codice di Microsoft Identity Platform.
Avviso
Microsoft consiglia di non usare il flusso di concessione implicita. Per la maggior parte degli scenari sono disponibili e consigliate alternative più sicure. Alcune configurazioni di questo flusso richiedono un livello di attendibilità molto elevato nell'applicazione e comportano rischi che non sono presenti in altri flussi. Si consiglia di usare questo flusso solo quando non è possibile usare altri flussi più sicuri. Per altre informazioni, vedere i problemi di sicurezza relativi al flusso di concessione implicita.
Diagramma del protocollo
Il diagramma seguente mostra come appare l'intero flusso di accesso implicito e le sezioni seguenti descrivono ogni passaggio in modo dettagliato.
Scenari adatti alla concessione implicita OAuth2
La concessione implicita è affidabile solo per la parte iniziale interattiva del flusso di accesso, in cui la mancanza di cookie di terze parti non influisce sull'applicazione. Questa limitazione significa che è consigliabile usarla esclusivamente come parte del flusso ibrido, in cui l'applicazione richiede un codice e un token dall'endpoint di autorizzazione. In un flusso ibrido, l'applicazione riceve un codice che può essere riscattato per un token di aggiornamento, assicurando così che la sessione di accesso dell'app rimanga valida nel tempo.
Preferisce il flusso del codice di autenticazione
Siccome alcuni browser stanno rimuovendo il supporto per i cookie di terze parti, il flusso di concessione implicita non è più un metodo di autenticazione appropriato. Le funzionalità di Single Sign-On (SSO) automatico del flusso implicito non funzionano senza cookie di terze parti, causando l'interruzione delle applicazioni quando tentano di ottenere un nuovo token. È consigliabile che tutte le nuove applicazioni usino il flusso del codice di autorizzazione che ora supporta le app a pagina singola invece del flusso implicito. Anche le app a pagina singola esistenti devono eseguire la migrazione al flusso del codice di autorizzazione.
Problemi di sicurezza con il flusso di concessione implicita
Il flusso di concessione implicita è destinato alle applicazioni Web tradizionali in cui il server ha il controllo sull'elaborazione sicura dei dati POST. Esistono due modi principali per recapitare i token con il flusso di concessione implicita: dove response_mode
viene restituito come frammento di URL o come parametro di query (usando form POST
e GET
). Nel flusso implicito in cui response_mode=form_post
, il token viene recapitato in modo sicuro tramite un POST di un modulo HTML all'URI di reindirizzamento del client. Questo metodo garantisce che il token non sia esposto nel frammento di URL, evitando a sua volta i rischi di perdita di token tramite la cronologia del browser o le intestazioni del referrer.
I problemi di sicurezza relativi al flusso implicito si verificano quando i token vengono recapitati usando response_mode=fragment
. Il frammento di URL è la parte dell'URL che segue il simbolo #
e non viene inviato al server quando il browser richiede una nuova pagina, ma è disponibile per JavaScript in esecuzione nel browser. Ciò significa che il token è esposto a qualsiasi JavaScript in esecuzione nella pagina, che potrebbe essere un rischio per la sicurezza se la pagina include script di terze parti. Questo problema di sicurezza per i token nelle applicazioni a pagina singola non si applica neanche al flusso implicito con form POST
.
Quando è necessario consentire l'emissione di un token di accesso o di un token ID quando richiesto usando una concessione implicita o un flusso ibrido?
La concessione implicita e il flusso ibrido non sono sicuri come altri flussi OAuth. A meno che non sia assolutamente necessario, non è consigliabile consentire l'emissione di un token di accesso o ID quando richiesto usando una concessione implicita o un flusso ibrido nella registrazione dell'app. Se l'utente (o uno sviluppatore) usa MSAL nell'applicazione per implementare l'autenticazione e l'autorizzazione, nessuno dei due campi deve essere abilitato.
Tuttavia, se l'utente (o uno sviluppatore) non usa MSAL nell'applicazione, la seguente tabella delinea quando è necessario abilitare i token di accesso o il token ID.
Tipo di applicazione che si sta creando | Token da abilitare in Registrazione app |
---|---|
Applicazione a pagina singola che non usa il flusso del codice di autorizzazione con PKCE | Token di accesso e token ID |
Un'applicazione Web o a pagina singola che chiama un'API Web tramite JavaScript usando un flusso implicito | Token di accesso e token ID |
Un'app Web core ASP.NET e altre app Web che usano l'autenticazione ibrida | Token ID |
Inviare la richiesta di accesso
Per accedere inizialmente all'utente nell'app, è possibile inviare una richiesta di autenticazione OpenID Connect e ottenere un id_token
da Microsoft Identity Platform.
Importante
Per richiedere correttamente un token ID e/o un token di accesso, la registrazione dell'app nella pagina Interfaccia di amministrazione di Microsoft Entra: Registrazioni app deve avere il flusso di concessione implicita corrispondente abilitato, selezionando token ID e token di accesso nella sezione Concessione implicita e flussi ibridi. Se non è abilitato, verrà restituito un errore unsupported_response
:
The provided value for the input parameter 'response_type' is not allowed for this client. Expected value is 'code'
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&response_type=id_token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=openid
&response_mode=fragment
&state=12345
&nonce=678910
Parametro | Type | Descrizione |
---|---|---|
tenant |
obbligatorio | Il valore {tenant} del percorso della richiesta può essere usato per controllare chi può accedere all'applicazione. I valori consentiti sono common , organizations , consumers e gli identificatori del tenant. Per altre informazioni, vedere le nozioni di base sul protocollo. In modo critico, per gli scenari guest in cui un utente passa da un tenant a un altro tenant, è necessario fornire l'identificatore del tenant per accedere correttamente al tenant della risorsa. |
client_id |
obbligatorio | ID dell'applicazione (client) che la pagina Interfaccia di amministrazione di Microsoft Entra: Registrazioni app ha assegnato all'app. |
response_type |
obbligatorio | Deve includere id_token per l'accesso a OpenID Connect. Può anche includere il response_type , token . Usando qui il token , l'app riceve immediatamente un token di accesso dall'endpoint /autorizzazione senza dover inviare una seconda richiesta a tale endpoint. Se si usa il token come response_type, il parametro scope deve contenere un ambito che indica la risorsa per cui emettere il token (ad esempio, user.read su Microsoft Graph). Può anche contenere code invece di token per fornire un codice di autorizzazione, da usare nel flusso del codice di autorizzazione. Questa risposta id_token +code viene talvolta chiamata flusso ibrido. |
redirect_uri |
consigliato | URI di reindirizzamento dell'app dove le risposte di autenticazione sono inviate e ricevute nell'app. Deve corrispondere esattamente a uno degli URI di reindirizzamento registrati nell'interfaccia di amministrazione di Microsoft Entra, ad eccezione del fatto che deve essere codificato come URL. |
scope |
obbligatorio | Elenco di ambiti separato da spazi. Per OpenID Connect (id_tokens ), deve includere l'ambito openid che esegue la conversione all'autorizzazione per l'accesso nell'interfaccia utente di consenso. Facoltativamente, è anche possibile includere l'ambito email e profile per ottenere l'accesso a dati aggiuntivi dell'utente. È anche possibile includere altri ambiti in questa richiesta per richiedere il consenso per varie risorse, se è richiesto un token di accesso. |
response_mode |
consigliato | Specifica il metodo da usare per inviare il token risultante a un'app. L'impostazione predefinita è query per un solo token di accesso, ma è fragment se la richiesta include un id_token. Per motivi di sicurezza, è consigliabile usare form_post per il flusso implicito per assicurarsi che il token non sia esposto nel frammento di URL. |
state |
consigliato | Un valore incluso nella richiesta viene anche restituito nella risposta del token. Può trattarsi di una stringa di qualsiasi contenuto desiderato. Per evitare gli attacchi di richiesta intersito falsa, viene in genere usato un valore univoco generato casualmente. Il parametro state viene anche usato per codificare le informazioni sullo stato dell'utente nell'app attivo prima dell'esecuzione della richiesta di autenticazione, ad esempio la pagina o la vista attiva. |
nonce |
obbligatorio | Valore incluso nella richiesta, generata dall'app, che viene incluso nel token ID risultante come attestazione. L'app può quindi verificare questo valore per l'attenuazione degli attacchi di riproduzione del token. Il valore è in genere una stringa casuale univoca che può essere usata per identificare l'origine della richiesta. Obbligatorio solo quando viene richiesto un valore id_token. |
prompt |
facoltative | Indica il tipo di interazione utente richiesto. Gli unici valori validi al momento sono login , none , select_account e consent . prompt=login forza l'utente a immettere le sue credenziali alla richiesta, negando l'accesso Single Sign-On. prompt=none è l'opposto: garantisce che all'utente non venga presentata alcuna richiesta interattiva. Se la richiesta non può essere completata automaticamente mediante Single-Sign-On, Microsoft Identity Platform restituisce un errore. prompt=select_account invia l'utente a un selettore di account in cui vengono visualizzati tutti gli account memorizzati nella sessione. prompt=consent attiva la finestra di dialogo di consenso di OAuth dopo l'accesso dell'utente, che chiede all'utente di concedere le autorizzazioni all'app. |
login_hint |
facoltative | È possibile usare questo parametro per pre-compilare i campi nome utente e indirizzo di posta elettronica nella pagina di accesso, se già si conosce il nome utente. Spesso le app usano questo parametro durante la riautenticazione, dopo aver già estratto l'attestazione facoltativa login_hint da un accesso precedente. |
domain_hint |
facoltative | Se incluso, non viene eseguito il processo di individuazione basato sulla posta elettronica a cui viene sottoposto l'utente nella pagina di accesso. Questo comporta un'esperienza utente leggermente semplificata. Questo parametro viene comunemente usato per le app line-of-business che operano in un singolo tenant, in cui forniscono un nome di dominio all'interno di un determinato tenant, inoltrando l'utente al provider di federazione per tale tenant. Questo hint impedisce agli utenti guest di accedere a questa applicazione e limita l'uso di credenziali cloud come ad esempio FIDO. |
A questo punto viene chiesto all'utente di immettere le credenziali e completare l'autenticazione. Microsoft Identity Platform garantisce inoltre che l'utente ha dato il consenso all'autorizzazione indicata nel parametro di query scope
. Se l'utente non ha acconsentito a nessuna di queste autorizzazioni, l'endpoint chiede all'utente di fornire il consenso per le autorizzazioni obbligatorie. Per altre informazioni, vedere autorizzazioni, consenso e app multi-tenant.
Dopo che l'utente viene autenticato e fornisce il consenso, Microsoft Identity Platform restituisce una risposta all'app nell'URI redirect_uri
indicato, usando il metodo specificato nel parametro response_mode
.
Risposta con esito positivo
Una risposta con esito positivo che usa response_mode=fragment
e response_type=id_token+code
è simile a quanto riportato di seguito. Sono state aggiunte interruzioni di riga per migliorare la leggibilità:
GET https://localhost/myapp/#
code=0.AgAAktYV-sfpYESnQynylW_UKZmH-C9y_G1A
&id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
Parametro | Descrizione |
---|---|
code |
Incluso se response_type include code . È un codice di autorizzazione adatto al flusso del codice di autorizzazione. |
access_token |
Incluso se response_type include token . Token di accesso richiesto dall'app. Il token di accesso non deve essere decodificato o controllato in altro modo ma deve essere trattato come una stringa opaca. |
token_type |
Incluso se response_type include token . Questo valore è sempre Bearer . |
expires_in |
Incluso se response_type include token . Indica il numero di secondi di validità del token, ai fini della memorizzazione nella cache. |
scope |
Incluso se response_type include token . Indica uno o più ambiti per i quali il valore access_token è valido. Potrebbe non includere tutti gli ambiti richiesti se non sono applicabili all'utente. Ad esempio, gli ambiti solo di Microsoft Entra richiesti durante l'accesso tramite un account personale. |
id_token |
Token JSON Web (JWT) firmato. L'app può decodificare i segmenti di questo token per richiedere informazioni sull'utente che ha eseguito l'accesso. L'app può memorizzare nella cache i valori e visualizzarli, ma non deve basarsi su di essi per i limiti di autorizzazione o di sicurezza. Per altre informazioni sugli oggetti token ID, vedere id_token reference . Nota: fornito solo se è stato richiesto l'ambito openid e response_type incluso id_tokens . |
state |
Se nella richiesta è incluso un parametro state, lo stesso valore deve essere visualizzato nella risposta. L'app deve verificare che i valori state nella richiesta e nella risposta siano identici. |
Avviso
Non tentare di convalidare o leggere i token per qualsiasi API di cui non si è proprietari, inclusi i token in questo esempio, nel codice. I token per i servizi Microsoft possono usare un formato speciale che non verrà convalidato come token JWT e potrebbe anche essere crittografato per gli utenti (account Microsoft). Sebbene la lettura dei token sia uno strumento utile per il debug e l'apprendimento, è consigliabile non dipendere da questo per il codice o presupporre specifiche sui token che non sono per un'API che si controlla.
Risposta con errore
Le risposte di errore possono essere inviate anche a redirect_uri
, in modo che l'app possa gestirle adeguatamente:
GET https://localhost/myapp/#
error=access_denied
&error_description=the+user+canceled+the+authentication
Parametro | Descrizione |
---|---|
error |
Stringa di codice di errore che può essere usata per classificare i tipi di errori che si verificano e correggerli. |
error_description |
Messaggio di errore specifico che consente a uno sviluppatore di identificare la causa principale di un errore di autenticazione. |
Acquisire i token di accesso automaticamente
Dopo che l'utente ha effettuato l'accesso all'app a pagina singola, è possibile ottenere in modo silenzioso i token di accesso per chiamare le API Web protette da Microsoft Identity Platform, come ad esempio Microsoft Graph. Anche se si è già ricevuto un token usando il token
response_type, è possibile usare questo metodo per acquisire i token per risorse aggiuntive senza dover reindirizzare l'utente perché esegua di nuovo l'accesso.
Importante
Questa parte del flusso implicito è improbabile che funzioni per l'applicazione perché viene usata in diversi browser a causa della rimozione di cookie di terze parti per impostazione predefinita. Anche se questo funziona ancora nei browser basati su Chromium che non sono in incognito, gli sviluppatori dovrebbero riconsiderare l'uso di questa parte del flusso. Nei browser che non supportano cookie di terze parti, si riceverà un errore che indica che nessun utente è connesso, perché i cookie della sessione della pagina di accesso sono stati rimossi dal browser.
Nel normale flusso OpenID Connect/OAuth, per eseguire questa operazione, si effettua una richiesta all'endpoint /token
di Microsoft Identity Platform. È possibile effettuare la richiesta in un iframe nascosto per ottenere nuovi token per altre API Web:
// Line breaks for legibility only
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=00001111-aaaa-2222-bbbb-3333cccc4444&response_type=token
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read
&response_mode=fragment
&state=12345
&nonce=678910
&prompt=none
&login_hint=myuser@mycompany.com
Per informazioni dettagliate sui parametri di query nell'URL, vedere Inviare la richiesta di accesso.
Suggerimento
Provare a copiare e incollare la richiesta seguente in una scheda del browser usando una registrazione reale client_id
e username
dalla registrazione dell'app. In questo modo sarà possibile visualizzare la richiesta silenziosa di token in azione.
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={your-client-id}&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&scope=https%3A%2F%2Fgraph.microsoft.com%2Fuser.read&response_mode=fragment&state=12345&nonce=678910&prompt=none&login_hint={username}
Si noti che questo funzionerà anche nei browser senza supporto di cookie di terze parti, poiché si sta immettendo direttamente in una barra del browser invece di aprirlo all'interno di un iframe.
Con il parametro prompt=none
, questa richiesta ha immediatamente esito positivo o negativo e fa tornare all'applicazione. La risposta viene inviata all'app all'indirizzo redirect_uri
indicato, usando il metodo specificato nel parametro response_mode
.
Risposta con esito positivo
Una risposta con esito positivo che usa response_mode=fragment
ha un aspetto simile al seguente:
GET https://localhost/myapp/#
access_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...
&state=12345
&token_type=Bearer
&expires_in=3599
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fdirectory.read
Parametro | Descrizione |
---|---|
access_token |
Incluso se response_type include token . Token di accesso richiesto dall'app, in questo caso per Microsoft Graph. Il token di accesso non deve essere decodificato o controllato in altro modo ma deve essere trattato come una stringa opaca. |
token_type |
Questo valore è sempre Bearer . |
expires_in |
Indica il numero di secondi di validità del token, ai fini della memorizzazione nella cache. |
scope |
Indica uno o più ambiti per i quali il token di accesso è valido. Potrebbe non includere tutti gli ambiti richiesti, se non erano applicabili all'utente (se gli ambiti esclusivi di Microsoft Entra vengono richiesti quando viene usato un account personale per l'accesso). |
id_token |
Token JSON Web (JWT) firmato. Incluso se response_type include id_token . L'app può decodificare i segmenti di questo token per richiedere informazioni sull'utente che ha eseguito l'accesso. L'app può memorizzare nella cache i valori e visualizzarli, ma non deve basarsi su di essi per i limiti di autorizzazione o di sicurezza. Per altre informazioni sugli oggetti id_token, vedere le informazioni di riferimento su id_token . Nota: viene fornito solo è stato richiesto l'ambito openid . |
state |
Se nella richiesta è incluso un parametro state, lo stesso valore deve essere visualizzato nella risposta. L'app deve verificare che i valori state nella richiesta e nella risposta siano identici. |
Risposta con errore
Le risposte di errore possono essere inviate anche a redirect_uri
, in modo che l'app possa gestirle adeguatamente. Se prompt=none
, si verifica un errore previsto:
GET https://localhost/myapp/#
error=user_authentication_required
&error_description=the+request+could+not+be+completed+silently
Parametro | Descrizione |
---|---|
error |
Stringa di codice di errore che può essere usata per classificare i tipi di errori che si verificano e correggerli. |
error_description |
Messaggio di errore specifico che consente a uno sviluppatore di identificare la causa principale di un errore di autenticazione. |
Se si riceve questo errore nella richiesta iframe, l'utente deve accedere di nuovo in modo interattivo per recuperare un nuovo token. È possibile scegliere di gestire questa situazione in qualsiasi modo appropriato per l'applicazione.
Aggiornare i token
La concessione implicita non fornisce token di aggiornamento. I token di accesso e quelli ID scadranno dopo un breve periodo, quindi l'app deve essere preparata per aggiornare regolarmente questi token. Per aggiornare entrambi i tipi di token, è possibile eseguire la stessa richiesta nascosta iframe delineata in precedenza usando il parametro prompt=none
per controllare il comportamento della piattaforma di identità. Per ricevere un nuovo token ID, assicurarsi di usare id_token
in response_type
e scope=openid
, e un parametro nonce
.
Nei browser che non supportano cookie di terze parti, viene generato un errore che indica che nessun utente ha eseguito l'accesso.
Inviare una richiesta di disconnessione
end_session_endpoint
di OpenID Connect consente all'app di inviare una richiesta a Microsoft Identity Platform per terminare una sessione utente e cancellare i cookie impostati da Microsoft Identity Platform. Per disconnettere completamente un utente da un'applicazione Web, l'app deve terminare la sessione in cui è presente l'utente (in genere cancellando la cache di un token o eliminando i cookie) e quindi reindirizzare il browser all'indirizzo seguente:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout?post_logout_redirect_uri=https://localhost/myapp/
Parametro | Type | Descrizione |
---|---|---|
tenant |
obbligatorio | Il valore {tenant} del percorso della richiesta può essere usato per controllare chi può accedere all'applicazione. I valori consentiti sono common , organizations , consumers e gli identificatori del tenant. Per altre informazioni, vedere le nozioni di base sul protocollo. |
post_logout_redirect_uri |
consigliato | URL di destinazione al quale l'utente deve essere reindirizzato dopo la disconnessione. Questo valore deve corrispondere a uno degli URI di reindirizzamento registrati per l'applicazione. In caso contrario, all'utente viene mostrato un messaggio generico da parte di Microsoft Identity Platform. |
Vedere anche
- Per iniziare a codificare, passare agli esempi di MSAL JS.
- Esaminare il flusso del codice di autorizzazione come alternativa più recente e migliore alla concessione implicita.