Noções básicas sobre o fluxo de concessão implícita OAuth2 no Azure AD (Active Directory)Understanding the OAuth2 implicit grant flow in Azure Active Directory (AD)

Aplica-se a:Applies to:
  • Ponto de extremidade do Azure AD v1.0Azure AD v1.0 endpoint

A concessão implícita OAuth2 é famosa por ser a concessão com a lista mais longa de questões de segurança na especificação OAuth2.The OAuth2 implicit grant is notorious for being the grant with the longest list of security concerns in the OAuth2 specification. Apesar disso, é a abordagem implementada pelo ADAL JS e a que recomendamos ao se escrever aplicativos SPA.And yet, that is the approach implemented by ADAL JS and the one we recommend when writing SPA applications. O que acontece?What gives? É uma questão de compensação: de fato, a concessão implícita é a melhor abordagem que você pode adotar para aplicativos que consomem uma API Web via JavaScript em um navegador.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.

O que é a concessão implícita OAuth2?What is the OAuth2 implicit grant?

A concessão de código de autorização OAuth2 por excelência é a concessão de autorização que usa dois pontos de extremidade separados.The quintessential OAuth2 authorization code grant is the authorization grant that uses two separate endpoints. O ponto de extremidade de autorização é usado para a fase de interação do usuário, que resulta em um código de autorização.The authorization endpoint is used for the user interaction phase, which results in an authorization code. O ponto de extremidade de token é usado pelo cliente para trocar o código para um token de acesso e, com frequência, um token de atualização também.The token endpoint is then used by the client for exchanging the code for an access token, and often a refresh token as well. Os aplicativos Web devem apresentar suas próprias credenciais de aplicativo ao ponto de extremidade de token, para que o servidor de autorização possa autenticar o cliente.Web applications are required to present their own application credentials to the token endpoint, so that the authorization server can authenticate the client.

A concessão implícita OAuth2 é uma variante de outras concessões de autorização.The OAuth2 implicit grant is a variant of other authorization grants. Ele permite que um cliente obtenha um token de acesso (e id_token ao usar OpenId Connect) diretamente do ponto de extremidade de autorização, sem entrar em contato com o ponto de extremidade de token ou autenticar o cliente.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. Essa variante foi projetada para aplicativos baseados em JavaScript em execução em um navegador da Web: na especificação original OAuth2, os tokens são retornados em um fragmento de 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. Isso disponibiliza os bits de token para o código JavaScript no cliente, mas garante que eles não sejam incluídos em redirecionamentos para o servidor.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. Na concessão implícita OAuth2, o ponto de extremidade de autorização emite tokens de acesso diretamente ao cliente usando um URI de redirecionamento fornecido anteriormente.In OAuth2 implicit grant, the authorization endpoint issues access tokens directly to the client using a redirect URI that was previously supplied. Também tem a vantagem de eliminar requisitos para chamadas entre origens, que são necessárias se o aplicativo JavaScript precisa entrar em contato com o ponto de extremidade de 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.

Uma característica importante da concessão implícita OAuth2 é o fato de que esses fluxos nunca retornam tokens de atualização ao cliente.An important characteristic of the OAuth2 implicit grant is the fact that such flows never return refresh tokens to the client. A próxima seção mostra como isso não é realmente necessário e, de fato, seria um problema de segurança.The next section shows how this isn’t necessary and would in fact be a security issue.

Cenários adequados para a concessão implícita OAuth2Suitable scenarios for the OAuth2 implicit grant

A especificação OAuth2 declara que a concessão implícita foi concebida para habilitar aplicativos de agente do usuário, ou seja, aplicativos JavaScript em execução em um navegador.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. A característica que define esses aplicativos é que o código JavaScript é usado para acessar recursos de servidor (normalmente, uma API Web) e para atualizar a experiência do usuário do aplicativo de maneira adequada.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. Pense em aplicativos como Gmail ou Outlook Web Access: quando você seleciona uma mensagem da caixa de entrada, apenas o painel de visualização da mensagem muda para exibir a nova seleção, enquanto o restante da página permanece inalterado.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. Essa característica difere de aplicativos Web tradicionais baseados em redirecionamento, em que cada interação do usuário resulta em um postback de página inteira e em uma renderização de página inteira da nova resposta do servidor.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.

Os aplicativos que levam a abordagem baseada em JavaScript ao extremo são chamados de SPAs ou aplicativos de página única.Applications that take the JavaScript based approach to its extreme are called single-page applications, or SPAs. A ideia é que esses aplicativos servem apenas uma página HTML inicial e o JavaScript associado, com todas as interações posteriores sendo conduzidas por chamadas à API Web realizadas por JavaScript.The idea is that these applications only serve an initial HTML page and associated JavaScript, with all subsequent interactions being driven by Web API calls performed via JavaScript. No entanto, as abordagens híbridas, em que o aplicativo é principalmente orientado por postback, mas executa chamadas JS ocasionais, não são incomuns. A discussão sobre o uso de fluxo implícitos também é relevante para eles.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.

Aplicativos baseados em redirecionamento normalmente protegem suas solicitações por meio de cookies. No entanto, essa abordagem não funciona bem para aplicativos JavaScript.Redirect-based applications typically secure their requests via cookies, however, that approach does not work as well for JavaScript applications. Cookies só funcionam em relação ao domínio em que foram gerados, enquanto chamadas JavaScript podem ser direcionadas para outros domínios.Cookies only work against the domain they have been generated for, while JavaScript calls might be directed toward other domains. De fato, frequentemente esse será o caso: pense em aplicativos que invocam a API do Microsoft Graph, a API do Office e a API do Azure. Todos eles residem fora do domínio de onde o aplicativo é fornecido.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. Uma tendência crescente para aplicativos JavaScript é não ter um back-end, recorrendo totalmente a APIs Web de terceiros para implementar sua função de negócios.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.

Atualmente, o método preferencial para proteger chamadas para uma API Web é usar a abordagem de token de portador de OAuth2, em que cada chamada é acompanhada por um token de acesso 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. A API Web examina o token de acesso de entrada e, se encontrar nele os escopos necessários, concederá acesso à operação solicitada.The Web API examines the incoming access token and, if it finds in it the necessary scopes, it grants access to the requested operation. O fluxo implícito fornece um mecanismo conveniente para que aplicativos JavaScript obtenham tokens de acesso para uma API Web, com diversas vantagens em relação aos cookies: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:

  • Os tokens podem ser obtidos de forma confiável sem a necessidade de chamadas entre origens; o registro obrigatório do URI de redirecionamento ao qual os tokens são retornados garante que os tokens não sejam substituídosTokens 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
  • Aplicativos JavaScript podem obter tantos tokens de acesso quantos forem necessários, para todas as APIs Web que direcionam, sem restrição quanto aos domíniosJavaScript applications can obtain as many access tokens as they need, for as many Web APIs they target – with no restriction on domains
  • Recursos de HTML5, como armazenamento local ou por sessão, concedem controle total sobre o cache de tokens e o gerenciamento de tempo de vida, enquanto o gerenciamento de cookies é opaco para o aplicativoHTML5 features like session or local storage grant full control over token caching and lifetime management, whereas cookies management is opaque to the app
  • Tokens de acesso não são suscetíveis a ataques de CSRF (solicitação intersite forjada)Access tokens aren’t susceptible to Cross-site request forgery (CSRF) attacks

O fluxo de concessão implícita não emite tokens de atualização, principalmente por motivos de segurança.The implicit grant flow does not issue refresh tokens, mostly for security reasons. Um token de atualização não tem escopo tão restrito quanto tokens de acesso, concedendo muito mais capacidade e, assim, causando muito mais danos caso seja vazado. No fluxo de implícita, os tokens são fornecidos na URL, por isso, o risco de interceptação é maior do que na concessão de código de autorização.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.

No entanto, um aplicativo JavaScript tem outro mecanismo à sua disposição para renovar tokens de acesso sem solicitar repetidamente as credenciais ao usuário.However, a JavaScript application has another mechanism at its disposal for renewing access tokens without repeatedly prompting the user for credentials. O aplicativo pode usar um iframe oculto para executar novas solicitações de token em relação ao ponto de extremidade de autorização do Azure AD: enquanto o navegador ainda tiver uma sessão ativa (ou seja, tiver um cookie de sessão) em relação ao domínio do Azure AD, a solicitação de autenticação poderá ocorrer com êxito sem necessidade de interação do usuário.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.

Esse modelo concede ao aplicativo JavaScript a capacidade de renovar independentemente os tokens de acesso e até mesmo adquirir novos tokens para uma nova API (desde que o usuário os tenha consentido anteriormente).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). Isso evita a sobrecarga adicional de aquisição, manutenção e proteção de um artefato de alto valor, como um token de atualização.This avoids the added burden of acquiring, maintaining, and protecting a high value artifact such as a refresh token. O artefato que possibilita a renovação silenciosa, o cookie de sessão do Azure AD, é gerenciado fora do aplicativo.The artifact that makes the silent renewal possible, the Azure AD session cookie, is managed outside of the application. Outra vantagem dessa abordagem é que um usuário pode sair do Azure AD, usando qualquer um dos aplicativos conectados ao Azure AD, em execução em qualquer uma das guias do navegador.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. Isso resulta na exclusão do cookie de sessão do Azure AD, e o aplicativo JavaScript automaticamente perde a capacidade de renovar tokens para o usuário desconectado.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.

A concessão implícita é adequada para meu aplicativo?Is the implicit grant suitable for my app?

A concessão implícita apresenta mais riscos do que outras concessões, e as áreas que você precisa prestar atenção são bem documentadas (por exemplo, o uso indevido do token de acesso para representar o proprietário do recurso no fluxo implícito e o modelo de ameaça OAuth 2,0 e segurança Considerações).The implicit grant presents more risks than other grants, and the areas you need to pay attention to are well documented (for example, Misuse of Access Token to Impersonate Resource Owner in Implicit Flow and OAuth 2.0 Threat Model and Security Considerations). No entanto, o perfil de risco mais alto é amplamente devido ao fato de que seu objetivo é habilitar aplicativos que executam código ativo, fornecido por um recurso remoto a um navegador.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 você estiver planejando uma arquitetura SPA, não tem um componente de back-end ou pretende invocar uma API Web por meio de JavaScript, é recomendável usar o fluxo implícito para aquisição de 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 o aplicativo é um cliente nativo, o fluxo implícito não é a melhor opção.If your application is a native client, the implicit flow isn’t a great fit. A ausência do cookie de sessão do Azure AD no contexto de um cliente nativo priva o aplicativo dos meios de manter uma sessão com vida útil longa.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. Isso significa que o aplicativo se dirigirá repetidamente ao usuário ao obter tokens de acesso para novos recursos.Which means your application will repeatedly prompt the user when obtaining access tokens for new resources.

Se você está desenvolvendo um aplicativo Web que inclui um back-end e que consome uma API de seu código de back-end, o fluxo implícito também não é uma boa opção.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. Outras concessões oferecem capacidade muito maior.Other grants give you far more power. Por exemplo, a concessão de credenciais de cliente OAuth2 fornece a capacidade de obter tokens que refletem as permissões atribuídas ao próprio aplicativo, em vez de delegações de usuário.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. Isso significa que o cliente tem a capacidade de manter o acesso programático a recursos mesmo quando um usuário não está ativamente envolvido em uma sessão e assim por diante.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. Não apenas isso, mas essas concessões dão garantias de segurança mais alta.Not only that, but such grants give higher security guarantees. Por exemplo, tokens de acesso nunca transitam pelo navegador do usuário, não correm o risco de ser salvos no histórico do navegador e assim por diante.For instance, access tokens never transit through the user browser, they don’t risk being saved in the browser history, and so on. O aplicativo cliente também pode executar a autenticação forte ao solicitar um token.The client application can also perform strong authentication when requesting a token.

Próximas etapasNext steps