Informazioni sul flusso di concessione implicita OAuth2 in Azure Active Directory (AD)Understanding the OAuth2 implicit grant flow in Azure Active Directory (AD)

È noto che la concessione implicita OAuth2 è quella con il più lungo elenco di preoccupazioni relative alla sicurezza nella specifica OAuth2.The OAuth2 implicit grant is notorious for being the grant with the longest list of security concerns in the OAuth2 specification. Nonostante ciò, è l'approccio implementato da ADAL JS e quello consigliato da Microsoft quando si scrivono applicazioni a singola pagina.And yet, that is the approach implemented by ADAL JS and the one we recommend when writing SPA applications. Quali sono i vantaggi?What gives? È una questione di compromessi: infatti risulta evidente che la concessione implicita è il miglior approccio che si possa adottare per le applicazioni che utilizzano un'API Web tramite JavaScript da un browser.It’s all a matter of tradeoffs: and as it turns out, the implicit grant is the best approach you can pursue for applications that consume a Web API via JavaScript from a browser.

Che cos'è la concessione implicita OAuth2?What is the OAuth2 implicit grant?

La tipica concessione del codice di autorizzazione OAuth2 è la concessione di autorizzazione che usa due endpoint separati.The quintessential OAuth2 authorization code grant is the authorization grant that uses two separate endpoints. L'endpoint di autorizzazione viene usato per la fase di interazione dell'utente, che restituisce un codice di autorizzazione.The authorization endpoint is used for the user interaction phase, which results in an authorization code. L'endpoint di token viene quindi usato dal client per cambiare il codice in un token di accesso e spesso anche in un token di aggiornamento.The token endpoint is then used by the client for exchanging the code for an access token, and often a refresh token as well. Le applicazioni Web devono presentare le proprie credenziali all'endpoint di token, in modo che il server di autorizzazione possa autenticare il client.Web applications are required to present their own application credentials to the token endpoint, so that the authorization server can authenticate the client.

La concessione implicita OAuth2 è una variante di altre concessioni di autorizzazioneThe OAuth2 implicit grant is a variant of other authorization grants. e consente a un client di ottenere un token di accesso (e un elemento id_token, quando si usa OpenId Connect) direttamente dall'endpoint di autorizzazione, senza contattare l'endpoint di token né autenticare il client.It allows a client to obtain an access token (and id_token, when using OpenId Connect) directly from the authorization endpoint, without contacting the token endpoint nor authenticating the client. Questa variante è stata progettata per le applicazioni basate su JavaScript in esecuzione in un Web browser: nella specifica OAuth2 originale i token vengono restituiti in un frammento di URI.This variant was designed for JavaScript based applications running in a Web browser: in the original OAuth2 specification, tokens are returned in a URI fragment. In questo modo i bit dei token diventano disponibili per il codice JavaScript nel client, ma non verranno inclusi nei reindirizzamenti al server.That makes the token bits available to the JavaScript code in the client, but it guarantees they won’t be included in redirects toward the server. La restituzione dei token tramite i reindirizzamenti del browser direttamente dagli endpoint di autorizzazioneReturning tokens via browser redirects directly from the authorization endpoint. ha anche il vantaggio di eliminare eventuali requisiti per le chiamate tra origini, necessarie se l'applicazione JavaScript deve contattare l'endpoint di token.It also has the advantage of eliminating any requirements for cross origin calls, which are necessary if the JavaScript application is required to contact the token endpoint.

Un caratteristica importante della concessione implicita OAuth2 è che tali flussi non restituiscono mai token di aggiornamento al client.An important characteristic of the OAuth2 implicit grant is the fact that such flows never return refresh tokens to the client. La sezione successiva spiega che questo non è davvero necessario e costituirebbe anzi un problema di sicurezza.The next section shows how this isn’t necessary and would in fact be a security issue.

Scenari adatti alla concessione implicita OAuth2Suitable scenarios for the OAuth2 implicit grant

La specifica OAuth2 dichiara che la concessione implicita è stata definita per abilitare le applicazioni agente utente, ovvero le applicazioni JavaScript in esecuzione in un browser.The OAuth2 specification declares that the implicit grant has been devised to enable user-agent applications – that is to say, JavaScript applications executing within a browser. La caratteristica distintiva di tali applicazioni è che il codice JavaScript viene usato per accedere alle risorse del server, in genere un'API Web, e per aggiornare di conseguenza l'esperienza utente delle applicazioni.The defining characteristic of such applications is that JavaScript code is used for accessing server resources (typically a Web API) and for updating the application user experience accordingly. Ad esempio in applicazioni come Gmail o Outlook Web Access, quando si seleziona un messaggio dalla Posta in arrivo, solo il pannello per la visualizzazione dei messaggi viene modificato per poter visualizzare la nuova selezione, mentre il resto della pagina rimane invariato.Think of applications like Gmail or Outlook Web Access: when you select a message from your inbox, only the message visualization panel changes to display the new selection, while the rest of the page remains unmodified. Avviene invece il contrario nelle app Web basate sul reindirizzamento tradizionale, in cui ogni interazione dell'utente restituisce un postback di pagina completo e un rendering di pagina completo della nuova risposta del server.This characteristic is in contrast with traditional redirect-based Web apps, where every user interaction results in a full page postback and a full page rendering of the new server response.

Le applicazioni che portano all'estremo l'approccio basato su JavaScript sono chiamate applicazioni a singola pagina: l'idea è che tali applicazioni gestiscano solo una pagina HTML iniziale e il codice JavaScript associato, mentre tutte le interazioni successive vengono gestite dalle chiamate API Web eseguite tramite JavaScript.Applications that take the JavaScript based approach to its extreme are called Single Page Applications, or SPAs: the idea is that those applications only serve an initial HTML page and associated JavaScript, with all subsequent interactions being driven by Web API calls performed via JavaScript. Gli approcci ibridi, tuttavia, in cui l'applicazione è basata principalmente sul postback, ma esegue chiamate JS occasionali, non sono comuni e il discorso sull'utilizzo del flusso implicito riguarda anche tali approcci.However, hybrid approaches, where the application is mostly postback-driven but performs occasional JS calls, are not uncommon – the discussion about implicit flow usage is relevant for those as well.

Le applicazioni basate sul reindirizzamento in genere proteggono le richieste tramite cookie, tuttavia questo approccio non funziona anche per le applicazioni JavaScript.Redirect-based applications typically secure their requests via cookies, however, that approach does not work as well for JavaScript applications. I cookie funzionano solo nel dominio per cui sono stati generati, mentre le chiamate JavaScript potrebbero essere dirette ad altri domini.Cookies only work against the domain they have been generated for, while JavaScript calls might be directed toward other domains. Di fatto ciò accade molto spesso. Si pensi, ad esempio, alle applicazioni che richiamano l'API Microsoft Graph, l'API di Office e l'API di Azure, che si trovano tutte all'esterno del dominio da cui è gestita l'applicazione.In fact, that will frequently be the case: think of applications invoking Microsoft Graph API, Office API, Azure API – all residing outside the domain from where the application is served. Una tendenza sempre più diffusa per le applicazioni JavaScript è quella di non avere back-end e di basarsi al 100% su API Web di terze parti per implementare la funzione aziendale.A growing trend for JavaScript applications is to have no backend at all, relying 100% on third party Web APIs to implement their business function.

Attualmente, il metodo preferito per proteggere le chiamate a un'API Web consiste nell'usare l'approccio basato sul token di connessione OAuth2, in cui ogni chiamata è accompagnata da un token di accesso OAuth2.Currently, the preferred method of protecting calls to a Web API is to use the OAuth2 bearer token approach, where every call is accompanied by an OAuth2 access token. L'API Web esamina il token di accesso in ingresso e, se vi trova gli ambiti necessari, concede l'accesso all'operazione richiesta.The Web API examines the incoming access token and, if it finds in it the necessary scopes, it grants access to the requested operation. Il flusso implicito fornisce alle applicazioni JavaScript un pratico meccanismo per ottenere i token di accesso per un'API Web, con numerosi vantaggi rispetto ai cookie:The implicit flow provides a convenient mechanism for JavaScript applications to obtain access tokens for a Web API, offering numerous advantages in respect to cookies:

  • I token possono essere ottenuti in modo affidabile senza bisogno di chiamate multiorigine. La registrazione obbligatoria dell'URI di reindirizzamento a cui i token vengono restituiti garantisce che non vengano spostati.Tokens can be reliably obtained without any need for cross origin calls – mandatory registration of the redirect URI to which tokens are return guarantees that tokens are not displaced
  • Le applicazioni JavaScript possono ottenere tutti i token di accesso necessari per tutte le API Web di destinazione, senza alcuna restrizione sui domini.JavaScript applications can obtain as many access tokens as they need, for as many Web APIs they target – with no restriction on domains
  • Le funzionalità HTML5, come l'archiviazione locale o di sessione, garantiscono il controllo completo sulla memorizzazione nella cache e sulla gestione del ciclo di vita dei token, mentre la gestione dei cookie è opaca per l'app.HTML5 features like session or local storage grant full control over token caching and lifetime management, whereas cookies management is opaque to the app
  • I token di accesso non sono soggetti agli attacchi di tipo richiesta intersito falsa.Access tokens aren’t susceptible to Cross-site request forgery (CSRF) attacks

Il flusso di concessione implicita non rilascia token di aggiornamento, soprattutto per motivi di sicurezza.The implicit grant flow does not issue refresh tokens, mostly for security reasons. Poiché l'ambito di un token di aggiornamento non è così ristretto come quello dei token di accesso, offre potenzialità decisamente maggiori, ma crea anche molti più danni se passa all'esterno. Nel flusso implicito i token vengono forniti nell'URL, quindi il rischio di intercettazione è maggiore che nella concessione di codice di autorizzazione.A refresh token isn’t as narrowly scoped as access tokens, granting far more power hence inflicting far more damage in case it is leaked out. In the implicit flow, tokens are delivered in the URL, hence the risk of interception is higher than in the authorization code grant.

Tuttavia, un'applicazione JavaScript ha a disposizione un altro meccanismo per rinnovare i token di accesso senza chiedere ripetutamente all'utente le credenziali.However, a JavaScript application has another mechanism at its disposal for renewing access tokens without repeatedly prompting the user for credentials. L'applicazione può usare un iframe nascosto per eseguire le nuove richieste di token nell'endpoint di autorizzazione di Azure AD: finché il browser ha una sessione attiva (ovvero, finché ha un cookie di sessione) nel dominio di Azure AD, la richiesta di autenticazione può essere eseguita correttamente senza alcuna interazione dell'utente.The application can use a hidden iframe to perform new token requests against the authorization endpoint of Azure AD: as long as the browser still has an active session (read: has a session cookie) against the Azure AD domain, the authentication request can successfully occur without any need for user interaction.

Questo modello concede all'applicazione JavaScript la possibilità di rinnovare in modo indipendente i token di accesso e anche di acquisirne di nuovi per una nuova API, purché l'utente abbia già dato il consenso.This model grants the JavaScript application the ability to independently renew access tokens and even acquire new ones for a new API (provided that the user previously consented for them. In questo modo si evita di acquisire, gestire e proteggere un elemento di valore elevato, ad esempio un token di aggiornamento.This avoids the added burden of acquiring, maintaining, and protecting a high value artifact such as a refresh token. L'elemento che rende possibile il rinnovo non interattivo, ovvero il cookie della sessione di Azure AD, viene gestito all'esterno dell'applicazione.The artifact that makes the silent renewal possible, the Azure AD session cookie, is managed outside of the application. Un altro vantaggio di questo approccio è che un utente può disconnettersi da Azure AD usando una delle applicazioni connesse ad Azure AD in esecuzione in una scheda del browser.Another advantage of this approach is a user can sign out from Azure AD, using any of the applications signed into Azure AD, running in any of the browser tabs. Ciò comporta l'eliminazione del cookie della sessione di Azure AD e l'applicazione JavaScript perderà automaticamente la possibilità di rinnovare i token per l'utente disconnesso.This results in the deletion of the Azure AD session cookie, and the JavaScript application will automatically lose the ability to renew tokens for the signed out user.

La concessione implicita è adatta all'app?Is the implicit grant suitable for my app?

La concessione implicita presenta maggiori rischi rispetto ad altre concessioni e le aree a cui è necessario prestare attenzione sono ben documentate,The implicit grant presents more risks than other grants, and the areas you need to pay attention to are well documented. ad esempio, nel paragrafo relativo all'uso improprio dei token di accesso per rappresentare il proprietario della risorsa nel flusso implicito e nel documento relativo al modello di minaccia OAuth 2.0 e alle considerazioni sulla sicurezza).For example, Misuse of Access Token to Impersonate Resource Owner in Implicit Flow and OAuth 2.0 Threat Model and Security Considerations). Tuttavia il profilo di rischio maggiore è per lo più generato dal fatto che lo scopo è abilitare le applicazioni che eseguono codice attivo, fornito da una risorsa remota a un browser.However, the higher risk profile is largely due to the fact that it is meant to enable applications that execute active code, served by a remote resource to a browser. Se si pianifica un'architettura di applicazione a singola pagina, non si hanno componenti back-end o si intende richiamare un'API Web tramite JavaScript, è consigliabile usare il flusso implicito per l'acquisizione dei token.If you are planning an SPA architecture, have no backend components or intend to invoke a Web API via JavaScript, use of the implicit flow for token acquisition is recommended.

Se l'applicazione è un client nativo, il flusso implicito non è la soluzione ideale.If your application is a native client, the implicit flow isn’t a great fit. L'assenza del cookie della sessione di Azure AD nel contesto di un client nativo non consente all'applicazione di mantenere una sessione di lunga durata.The absence of the Azure AD session cookie in the context of a native client deprives your application from the means of maintaining a long lived session. Di conseguenza, 'applicazione chiederà ripetutamente l'interazione dell'utente per ottenere i token di accesso per le nuove risorse.Which means your application will repeatedly prompt the user when obtaining access tokens for new resources.

Se si sta sviluppando un'applicazione Web che include un back-end e utilizza un'API dal codice back-end, nemmeno in questo caso il flusso implicito è la soluzione ideale.If you are developing a Web application that includes a backend, and consuming an API from its backend code, the implicit flow is also not a good fit. Altre concessioni offrono molte più possibilità.Other grants give you far more power. Ad esempio, la concessione delle credenziali client OAuth2 consente di ottenere token che rispecchiano le autorizzazioni assegnate all'applicazione stessa invece che alle deleghe utente.For example, the OAuth2 client credentials grant provides the ability to obtain tokens that reflect the permissions assigned to the application itself, as opposed to user delegations. Ciò significa che il client è in grado di mantenere l'accesso a livello di codice alle risorse anche quando un utente non è attivamente impegnato in una sessione e così via.This means the client has the ability to maintain programmatic access to resources even when a user is not actively engaged in a session, and so on. Tali concessioni offrono poi anche maggiori garanzie di sicurezza.Not only that, but such grants give higher security guarantees. Ad esempio, i token di accesso non passano mai dal browser dell'utente e non rischiano di essere salvati nella cronologia del browser e così via.For instance, access tokens never transit through the user browser, they don’t risk being saved in the browser history, and so on. L'applicazione client può anche eseguire l'autenticazione avanzata quando si richiede un token.The client application can also perform strong authentication when requesting a token.

Passaggi successiviNext steps