Compreender o fluxo de concessão implícita OAuth2 no Azure Active Directory (AD)
Aviso
Este conteúdo destina-se ao ponto final Azure AD v1.0 mais antigo. Utilize o plataforma de identidades da Microsoft para novos projetos.
A concessão implícita OAuth2 é notória por ser a concessão com a lista mais longa de preocupações de segurança na especificação OAuth2. No entanto, esta é a abordagem implementada pelo ADAL JS e a que recomendamos ao escrever aplicações SPA. O que dá? É tudo uma questão de compromissos: e, ao que parece, a concessão implícita é a melhor abordagem que pode seguir para aplicações que consomem uma API Web através de JavaScript a partir de um browser.
O que é a concessão implícita do OAuth2?
A concessão de código de autorização OAuth2 quintessencial é a concessão de autorização que utiliza dois pontos finais separados. O ponto final de autorização é utilizado para a fase de interação do utilizador, o que resulta num código de autorização. Em seguida, o ponto final do token é utilizado pelo cliente para trocar o código de um token de acesso e, muitas vezes, também um token de atualização. As aplicações Web são necessárias para apresentar as suas próprias credenciais de aplicação ao ponto final do token, para que o servidor de autorização possa autenticar o cliente.
A concessão implícita OAuth2 é uma variante de outras concessões de autorização. Permite que um cliente obtenha um token de acesso (e id_token, ao utilizar o OpenId Connect) diretamente a partir do ponto final de autorização, sem contactar o ponto final do token nem autenticar o cliente. Esta variante foi concebida para aplicações baseadas em JavaScript em execução num browser: na especificação original do OAuth2, os tokens são devolvidos num fragmento de URI. Isto torna os bits de token disponíveis para o código JavaScript no cliente, mas garante que não serão incluídos em redirecionamentos para o servidor. Na concessão implícita do OAuth2, o ponto final de autorização emite tokens de acesso diretamente ao cliente através de um URI de redirecionamento fornecido anteriormente. Também tem a vantagem de eliminar quaisquer requisitos para chamadas entre origens, que são necessários se a aplicação JavaScript for necessária para contactar o ponto final do token.
Uma característica importante da concessão implícita OAuth2 é o facto de esses fluxos nunca devolverem tokens de atualização ao cliente. A secção seguinte mostra como isto não é necessário e seria, de facto, um problema de segurança.
Cenários adequados para a concessão implícita OAuth2
A especificação OAuth2 declara que a concessão implícita foi concebida para ativar aplicações de agente de utilizador , ou seja, aplicações JavaScript executadas num browser. A característica determinante destas aplicações é que o código JavaScript é utilizado para aceder aos recursos do servidor (normalmente uma API Web) e para atualizar a experiência do utilizador da aplicação em conformidade. Pense em aplicações como o Gmail ou o Outlook Web Access: quando seleciona uma mensagem na sua caixa de entrada, apenas o painel de visualização de mensagens muda para apresentar a nova seleção, enquanto o resto da página permanece não modificado. Esta característica contrasta com as aplicações Web tradicionais baseadas em redirecionamento, em que cada interação de utilizador resulta numa publicação de página inteira e numa composição de página inteira da nova resposta do servidor.
As aplicações que assumem a abordagem baseada em JavaScript ao extremo são denominadas aplicações de página única ou SPAs. A ideia é que estas aplicações servem apenas uma página HTML inicial e javaScript associado, com todas as interações subsequentes a serem impulsionadas por chamadas à API Web realizadas através do JavaScript. No entanto, as abordagens híbridas, em que a aplicação é maioritariamente orientada por pós-retorno, mas efetua chamadas JS ocasionais, não são incomuns– a discussão sobre a utilização implícita do fluxo também é relevante para essas pessoas.
As aplicações baseadas em redirecionamento normalmente protegem os seus pedidos através de cookies, no entanto, essa abordagem não funciona tão bem para aplicações JavaScript. Os cookies só funcionam no domínio para o qual foram gerados, enquanto as chamadas JavaScript podem ser direcionadas para outros domínios. Na verdade, este será frequentemente o caso: pense nas aplicações que invocam o Microsoft Graph API, a API do Office, a API do Azure – todas a residir fora do domínio a partir do qual a aplicação é servida. Uma tendência crescente para as aplicações JavaScript é não ter nenhum back-end, confiando 100% em APIs Web de terceiros para implementar a função empresarial.
Atualmente, o método preferencial para proteger chamadas a uma API Web é utilizar a abordagem do token de portador OAuth2, onde cada chamada é acompanhada por um token de acesso OAuth2. A API Web examina o token de acesso recebido e, se encontrar nos âmbitos necessários, concede acesso à operação pedida. O fluxo implícito fornece um mecanismo conveniente para as aplicações JavaScript obterem tokens de acesso para uma API Web, oferecendo inúmeras vantagens em relação aos cookies:
- Os tokens podem ser obtidos de forma fiável sem necessidade de chamadas entre origens – o registo obrigatório do URI de redirecionamento para o qual os tokens são devolvidos garante que os tokens não são deslocados
- As aplicações JavaScript podem obter o número de tokens de acesso necessários, para o número de APIs Web que visam , sem restrições em domínios
- Funcionalidades HTML5, como sessão ou armazenamento local, concedem controlo total sobre a colocação em cache de tokens e a gestão de duração, enquanto a gestão de cookies é opaca para a aplicação
- Os tokens de acesso não são suscetíveis a ataques de falsificação de pedidos entre sites (CSRF)
O fluxo de concessão implícito não emite tokens de atualização, principalmente por motivos de segurança. Um token de atualização não é tão limitado como tokens de acesso, concedendo muito mais poder, o que causa muito mais danos no caso de ser vazado. No fluxo implícito, os tokens são entregues no URL, pelo que o risco de intercepção é maior do que na concessão do código de autorização.
No entanto, uma aplicação JavaScript tem outro mecanismo à sua disposição para renovar tokens de acesso sem pedir repetidamente credenciais ao utilizador. A aplicação pode utilizar um iframe oculto para realizar novos pedidos de tokens no ponto final de autorização do Azure AD: desde que o browser ainda tenha uma sessão ativa (leia-se: tem um cookie de sessão) no domínio Azure AD, o pedido de autenticação pode ocorrer com êxito sem qualquer necessidade de interação do utilizador.
Este modelo concede à aplicação JavaScript a capacidade de renovar tokens de acesso de forma independente e até adquirir novos para uma nova API (desde que o utilizador tenha consentido anteriormente). Isto evita o encargo adicional de adquirir, manter e proteger um artefacto de valor elevado, como um token de atualização. O artefacto que torna possível a renovação silenciosa, o cookie de sessão Azure AD, é gerido fora da aplicação. Outra vantagem desta abordagem é que um utilizador pode terminar sessão a partir de Azure AD, utilizando qualquer uma das aplicações com sessão iniciada em Azure AD, em execução em qualquer um dos separadores do browser. Isto resulta na eliminação do cookie de sessão Azure AD e a aplicação JavaScript perderá automaticamente a capacidade de renovar tokens para o utilizador com sessão iniciada.
A concessão implícita é adequada para a minha aplicação?
A concessão implícita apresenta mais riscos do que outras subvenções e as áreas às quais precisa de prestar atenção estão bem documentadas (por exemplo, Utilização Indevida do Token de Acesso para Representar Proprietário de Recursos no Fluxo Implícito e Considerações de Segurança e Modelo de Ameaça OAuth 2.0). No entanto, o perfil de maior risco deve-se, em grande parte, ao facto de se destinar a ativar aplicações que executam código ativo, servido por um recurso remoto num browser. Se estiver a planear uma arquitetura SPA, não tiver componentes de back-end ou pretender invocar uma API Web através de JavaScript, recomenda-se a utilização do fluxo implícito para a aquisição de tokens.
Se a sua aplicação for um cliente nativo, o fluxo implícito não será adequado. A ausência do cookie de sessão Azure AD no contexto de um cliente nativo priva a sua aplicação dos meios de manter uma sessão de longa duração. O que significa que a sua aplicação irá pedir repetidamente ao utilizador para obter tokens de acesso para novos recursos.
Se estiver a desenvolver uma aplicação Web que inclua um back-end e a consumir uma API a partir do respetivo código de back-end, o fluxo implícito também não será adequado. Outras subvenções dão-lhe muito mais poder. Por exemplo, a concessão de credenciais de cliente OAuth2 fornece a capacidade de obter tokens que refletem as permissões atribuídas à própria aplicação, em oposição às delegações de utilizadores. Isto significa que o cliente tem a capacidade de manter o acesso programático aos recursos, mesmo quando um utilizador não está ativamente envolvido numa sessão, etc. Não só isso, mas tais subvenções dão garantias de segurança mais elevadas. Por exemplo, os tokens de acesso nunca transitam através do browser de utilizador, não correm o risco de ser guardados no histórico do browser e assim sucessivamente. A aplicação cliente também pode efetuar uma autenticação forte ao pedir um token.
Passos seguintes
- Veja Como integrar uma aplicação com Azure AD para obter mais profundidade no processo de integração de aplicações.