OAuth para Curiosos*
Todos os dias, ao tentar acessar sistemas informatizados, nos deparamos com telas como a que aparece na figura 1, abaixo, solicitando credenciais que permitem a decisão sobre se o acesso deve ou não ser autorizado. Existe uma grande possibilidade de que por trás dessa tela, o processo de autorização seja realizado seguindo um protocolo conhecido por OAuth 2.0. Este artigo é uma introdução a esse protocolo, voltada para curiosos em geral.
O artigo não tem a pretensão de dar a última palavra sobre o assunto e nem é voltado para pessoal de grande conhecimento técnico sobre o protocolo.¹ O objetivo aqui é permitir que o leitor possa conversar coerentemente e entender o que está em jogo quando se fala de autorização de usuários para acessar sistemas. A pergunta que o artigo quer responder é o que o OAuth determina que deve ser feito entre o momento em que alguém digita suas credenciais em uma tela como a da figura 1 e o momento em que essa mesma pessoa, devidamente autorizada, é direcionada para o produto e para as informações privadas que quer acessar. A discussão está organizada em três tópicos, o primeiro explicando o que é o OAuth, o segundo mostrando os problemas que ele pretende resolver e o terceiro explicando como ele propõe resolvê-los.
* Agradeço aos amigos Karina Tanada, Letícia Silva e Guilherme Ferreira pela leitura cuidadosa dos rascunhos deste artigo e pelas sugestões valiosas. É claro que qualquer bobagem contida no texto é de minha exclusiva responsabilidade.
¹ Os que queiram se aprofundar no assunto têm acesso a um vasto número de artigos a respeito do protocolo na internet. É só fazer uma busca no Google. Em particular o documento autoritativo a respeito do OAuth 2.0 (a norma RFC 6749 IETF — Internet Engineering Task Force) está disponível em: https://tools.ietf.org/html/rfc6749.
Em termos formais, o que é o OAuth?
Antes de discutir aquilo de que trata o OAuth, cabe explicar brevemente do que estamos falando em termos formais. Todos usamos a internet, para mais e mais coisas, sem pensar muito como é possível tudo isso funcionar. Um dos motivos para toda essa facilidade é a existência de padrões que permitem a colaboração entre sistemas, de modo a prover uma experiência rica e uniforme para os usuários. A aderência àquilo que esses padrões determinam torna possível, por exemplo, que através de um mesmo browser (o Chrome, o Internet Explorer, o Safari, etc.) possamos acessar coisas tão diferentes como o Gmail, o Facebook, o Whatsapp e o Safedoc². Esses padrões estabelecem coisas tão diversas como o formato das mensagens trocadas entre os diversos sistemas, os modos de indicar ao browser como a informação deve ser mostrada (qual a cor e o formato das letras, em que lugar da tela os textos e figuras devem ser posicionados e assim por diante), e como as mensagens devem ser criptografadas e descriptografadas para transmissão segura, entre muitas outras coisas. O OAuth, objeto deste artigo, é um desses padrões. Um padrão que trata da troca de mensagens entre sistemas para estabelecer autorizações de acesso a informação privativa de alguém.
Rigorosamente falando, o OAuth não é oficialmente um padrão. É que ele ainda não passou por todas as etapas para se transformar em padrão de verdade. No estágio atual, o OAuth é um “pedido de comentários” (em inglês “request for comments” ou RFC), o RFC 6749. Se algum dia ele for oficialmente transformado em padrão, ganhará um novo número precedido pela sigla STD, a sigla dos padrões oficiais. Seja em sua forma RFC, seja em uma futura forma STD, o OAuth é administrado pela Internet Engineering Task Force (IETF), organização aberta (as propostas podem ser submetidas por qualquer especialista e as discussões sobre elas são abertas a todos os interessados) reconhecida como a mais importante no campo da padronização da internet.
Mesmo ainda não sendo um padrão oficial, o OAuth é aceito e implementado por uma enorme quantidade de empresas. Para se ter uma ideia, a adoção do que determina o OAuth é tamanha que se criou um mercado bilionário ao redor dele, composto por empresas que oferecem software de autorização de acesso a sistemas como um serviço (dois exemplos são a Okta e a Auth0).
Em termos históricos, a especificação do OAuth (OAuth 1.0) foi inicialmente submetida ao IETF em abril de 2010. Era a RFC 5849 que, em essência, reconhecia que havia um problema com a autorização de usuários e iniciava o debate a respeito. A RFC 5849 foi superada pela RFC 6749 (OAuth 2.0) em outubro de 2012 e é essa RFC que continua em discussão, sendo desde já o padrão geralmente aceito para autorização de usuários na internet.
² Safedoc é um produto da Acesso Digital. Trata-se de um sistema bastante sofisticado para captura e administração de documentos de negócio (normalmente documentos digitalizados), através da web.
Que problemas o OAuth resolve?
Desde que passaram a existir sistemas computacionais que podiam ser acessados por vários usuários (década de 1960, por aí) surgiu o problema de se saber se determinada pessoa deve ou não ser autorizada a acessar o sistema. A solução que imediatamente se tornou preponderante para resolver esse problema foi a da verificação de um identificador de usuário (daqui em diante referenciado pela palavra login) e de uma senha. Quem fazia a verificação era o próprio sistema que o usuário queria acessar. Se o identificador e a senha “batessem”, o usuário estava autorizado a acessar o sistema. O que se deve destacar nesse cenário é que o próprio sistema que se queria acessar guardava as credenciais do usuário (o login e a senha) e decidia se devia permitir ou não o acesso. Antecipando um pouco a discussão que segue, por exemplo, era o sistema de folha de pagamento ou o sistema de contabilidade, que além de cuidar da folha de pagamento ou da contabilidade tinha também que cuidar da autorização de acesso de seus usuários. Obviamente um desperdício de esforço dos desenvolvedores. Mas um mal necessário.
Antes de continuar, deve-se destacar que o problema que o OAuth resolve não tem nada a ver com a forma como o usuário se autentica, ou como prova que ele é ele mesmo. Autenticação e autorização são tarefas distintas que não devem ser confundidas. O OAuth trata de autorização e não de autenticação. Até hoje, o modo mais comum de autenticação é a captura do login e senha do usuário. E o OAuth simplesmente não trata disso.
Por isso, foge ao escopo deste artigo discutir o quão seguro é essa combinação de login e senha, embora seja fácil perceber que ela não é muito segura. Basta prestar atenção em diversos artifícios, inventados nos últimos tempos, que visam a tornar mais robusto o uso do login e da senha. Por exemplo, a exigência de senhas complexas que têm que ser trocadas com frequência. Por exemplo, ainda, os “captcha” em que você tem que desesperadamente procurar todas as figurinhas em que aparecem carros, pontes e outras coisas desse tipo. Por exemplo, também, os segundos fatores de autenticação, como aqueles “chaveirinhos” que os bancos distribuem a seus clientes, ou ainda os códigos que recebemos por e-mail ou SMS, para digitar na tela do aplicativo. Basta prestar atenção também aos ataques de phishing que visam exatamente a fazer com que você digite a sua senha em uma tela controlada por um sistema clandestino. Mas não é aí que o OAuth atua, pelo menos não diretamente. O problema da autenticação do usuário exige outras soluções.³
Mas então, o que o OAuth resolve?
O OAuth foi projetado para resolver o problema de compartilhamento de informações entre sistemas. Um exemplo pode ajudar a ilustrar essa questão. Suponha que o sistema de folha de pagamento e o de contabilidade estejam em infraestruturas diferentes (por exemplo, são operados por dois escritórios de contabilidade diferentes) e que o sistema de folha precise fazer lançamentos no sistema de contabilidade. O jeito mais coerente de fazer isso é entregar ao sistema de folha um login e senha para que ele acesse o sistema de contabilidade. Normalmente esse login e senha sistêmicos têm características especiais, como senhas que não expiram, isenção das restrições de horário e acesso mais amplo a recursos do que um usuário comum. O sistema de folha é obrigado a armazenar esse login e senha sistêmicos em algum lugar, o que representa mais um risco de segurança. Se o sistema de folha sofrer um ataque bem sucedido, além do acesso às informações de folha de pagamento, de bônus o hacker leva a autorização para acessar o sistema de contabilidade com altos privilégios. Complicador dessa situação é que a empresa que fornece o serviço de contabilidade (e isso supondo que a fraude seja descoberta) vai ter que tomar providências para desabilitar o login e senha roubados. Mas, ao fazer isso, pode estar desabilitando a autorização de vários outros sistemas de folha de outras empresas que usam o mesmo login e senha. Todos terão que ser reconfigurados para usar um novo login e senha.
O OAuth resolve ainda, mesmo que não intencionalmente, um outro problema que diz respeito às consequências de algo que já foi dito. Já sabemos que todo o problema de autorização de usuários para acesso a sistemas era resolvido pelo próprio sistema, através da administração interna de login e senha. Em nosso exemplo, o sistema de folha de pagamento tem que resolver os problemas associados ao controle da folha, mas tem também que resolver o problema de autorização de acesso de usuários. O sistema de contabilidade tem que resolver os problemas associados à contabilidade, mas tem também que resolver o problema de autorização de acesso de usuários. Isso significa que cada sistema tem que implementar um subsistema de autorização de acesso que nada têm a ver com o problema principal que pretende resolver. É um volume imenso de horas de desenvolvimento de software que custa caro e gera um passivo tecnológico difícil de administrar. Na falta de alternativa, isso é um problema que aflige cada sistema desenvolvido em qualquer lugar do mundo.
O OAuth resolve esses dois problemas e, indiretamente, toca na questão de autenticação de usuários. A próxima seção trata de como isso tudo acontece.
³ Leitura interessante sobre esse assunto é a ideia de “Zero Trust Network”. Para os interessados, recomendo a documentação disponível em https://cloud.google.com/beyondcorp. Pergunta interessante que merece pesquisa é se já não passou da hora de abandonar o esquema de login e senha por algum outro método de autenticação, como a autenticação biométrica. Mas isso foge ao escopo deste artigo.
Como o OAuth resolve os problemas identificados?
Em poucas palavras, o OAuth propõe que as credenciais do usuário (os velhos login e senha)⁴ sejam trocadas por um token de acesso. A ideia é que as credenciais do usuário sejam de conhecimento do mínimo possível de entidades, de preferência somente do próprio usuário e do serviço responsável pela autorização, o que dificulta a apropriação das mesmas por um terceiro. Sistemas que usam o OAuth não permitem que credenciais trafeguem mais do que o necessário. Sistemas de negócio reconhecem a autorização através dos tokens de acesso.
Resumidamente, o OAuth 2.0 define duas coisas:
- primeiro: as várias entidades envolvidas na autorização de acesso à informação privada de alguém; e,
- segundo: como essas entidades devem se comunicar para evitar que, uma vez autenticado o dono da informação privada, um terceiro (provavelmente mal intencionado) ganhe autorização indevida a essa informação.
As entidades envolvidas na autorização, segundo o OAuth 2.0 são:
- o dono do recurso que se pretende acessar — por exemplo, a pessoa que é dona de uma conta de e-mail, a empresa que é dona dos dados guardados no sistema de folha de pagamento;
- o servidor do recurso — seguindo o exemplo do item anterior, o sistema que cuida dos e-mails e o sistema de folha de pagamento;
- o cliente — cliente é o nome dado ao software que quer, em nome do dono do recurso, acessá-lo — por exemplo, o aplicativo de e-mail instalado no celular do dono do recurso, ou o aplicativo web, apresentado no browser, que permite acesso ao sistema de folha de pagamento; e
- o servidor de autorização, software que cuida de tentar garantir a autenticação do dono do recurso (garantir que o usuário é quem diz ser) e autoriza o acesso ao recurso pelo cliente — por exemplo, nessa categoria é muito conhecido o software do Google que cuida do login e senha do usuário, valida o segundo fator de autenticação e identifica tentativas suspeitas de uso da conta.
Dissemos anteriormente que para resolver os problemas de segurança elencados, o OAuth propõe a transformação das credenciais de usuário em um token de acesso. Dessa maneira reduz-se drasticamente a possibilidade de um terceiro se apropriar das credenciais. Como assim? É que o OAuth, embora não diga nada sobre como a autenticação do usuário deva ser tratada, recomenda com veemência que as credenciais de usuário só devam fluir entre o próprio dono do recurso e o servidor de autorização.⁵ Nem o cliente, nem o servidor de recurso devem ter acesso às credenciais. Eles só conhecem o token de acesso fornecido pelo servidor de autorização após a autenticação do dono do recurso.
Antes de continuar a discussão do OAuth, é necessário enfatizar a importância dessa recomendação de restringir o tráfego das credenciais somente entre o dono do recurso e o servidor de autorização. Primeiro tem-se que reconhecer que o dono do recurso é o portador de suas credenciais. É impossível evitar que ele participe do ciclo de autenticação. É claro que, em se tratando de credenciais que são conhecidas de uma pessoa, elas podem ser roubadas. Mas já sabemos que resolver a vulnerabilidade das credenciais foge ao escopo do OAuth. Mesmo assim, deve-se reconhecer que o OAuth, indiretamente, serve para mitigar o problema. Afinal, a concentração do envio de credenciais de usuário para um ponto único que é o servidor de autorização ajuda a minimizar as possibilidades de autorização indevida de acesso. Cabe lembrar que a chegada do OAuth permitiu que o servidor de autorização se tornasse um sistema especializado em autorização de acesso.
A recomendação de que só ele e o dono do recurso tenham acesso às credenciais de usuário, permite que o servidor de autorização se torne também um sistema especializado na autenticação de usuários. Sendo responsabilidade de uma equipe especializada o servidor de autorização pode incluir a última palavra em tudo que há de melhor para evitar fraudes de autenticação. Além dos recursos já citados (captcha, segundo fator, restrições de horário etc.), empresas como a Okta e a Auth0, especializadas em prover autorização de usuários, possuem sistemas de inteligência artificial que identificam comportamentos estranhos e tomam providências para evitar a autenticação fraudulenta (perguntando ao usuário, através de informações de contato cadastradas, se ele reconhece o acesso, ou, eventualmente, bloqueando as credenciais).
Voltando ao assunto principal deste artigo, definidas as quatro entidades, cabe uma breve explicação do que o OAuth 2.0 determina sobre a comunicação entre elas. O padrão apresenta vários tipos de interação entre as entidades para autorização de acesso a um recurso, os chamados fluxos de autorização. O fluxo de autorização varia de acordo com o tipo do cliente (isso acontece porque tipos diferentes de clientes, como, por exemplo, um aplicativo web, em que as telas que o usuário vê são todas montadas pelo servidor, e um aplicativo instalado em um celular têm características de segurança bastante diferentes). No fluxo mais completo e seguro, o cliente não se comunica com o dono do recurso. Ele pede que o servidor de autorização interaja com o dono do recurso explicando quem é o cliente e a que recursos ele quer ter acesso. É o servidor de autorização que se comunica com o dono do recurso para obter as credenciais que significam que ele autorizou o acesso ao recurso protegido. Note bem: no cenário recomendado, é somente o servidor de autenticação que obtém o login e a senha do usuário. Se o dono do recurso autorizar o acesso, o servidor de autenticação envia ao cliente um código de autorização. Na sequência, o fluxo envolve uma interação complexa entre o cliente e o servidor de autorização em que o cliente se identifica e envia o código de autorização. A identificação do cliente pode assumir várias formas, mas em suas versões mais sofisticadas envolve o cadastro prévio do cliente junto ao servidor de autorização, o que inclui a criação de um código secreto que o cliente tem que apresentar seguindo estritas regras de segurança. Identificado o cliente e apresentado o código de autorização, o servidor de autorização entrega ao cliente um token de acesso e, opcionalmente (isso depende do nível de segurança estabelecido pela forma de identificação que o cliente usou na interação inicial com o servidor de autorização), um token de refresh. Os tokens são criptografados e recomenda-se que o cliente não tenha acesso ao seu conteúdo. O OAuth 2.0 não especifica o conteúdo do token. Isso é uma decisão de quem implementa o servidor de autorização. O token pode, inclusive, não ter conteúdo algum e ser usado pelo servidor do recurso para obter mais informações junto ao servidor de autorização, mas isso foge ao escopo do OAuth 2.0.
Quando precisar de acesso ao recurso protegido, o cliente entrega o token de acesso ao servidor do recurso, esse sim capaz de descriptografá-lo e garantir sua autenticidade. Autenticado o token de acesso, o servidor do recurso fica autorizado a permitir que o cliente receba as informações protegidas.
Para reforçar a segurança do esquema, o token de acesso normalmente tem um prazo de validade pequeno (poucos minutos). Daí a ideia do token de refresh, mencionado acima. O token de refresh serve para que o cliente obtenha um token de acesso renovado sem a necessidade de que o servidor de autorização tenha novamente que pedir credenciais ao dono do recurso. O token de refresh tem duração mais longa do que o token de acesso (talvez dias ou até meses). Porém ele é associado ao cliente autenticado. Isto é, não é possível que um software qualquer use o token de refresh para obter um token de acesso. Só o cliente que passou pelo ciclo de autenticação forte recebe e é capaz de usar o token de refresh. Além disso, o OAuth 2.0 recomenda que toda vez que o token de refresh for usado ele seja trocado por um novo, sendo o antigo inativado.
Todas as trocas de informação entre as entidades definidas na especificação OAuth 2.0 são necessariamente executadas de modo seguro (criptografia forte) segundo padrões de mercado (HTTPS e TLS).
A essa altura, já deve estar claro como o OAuth 2.0 resolve os dois problemas elencados no final da seção anterior.
Primeiro, tratemos a questão do compartilhamento de recursos entre sistemas. Relembrando, sem o OAuth, um sistema que precisa acessar recursos protegidos de outro sistema (o exemplo era o sistema de folha de pagamento de uma empresa de contabilidade acessando o sistema de contabilidade oferecido por outra empresa) precisaria, de alguma maneira, apresentar credenciais como se fosse um usuário comum. Com o OAuth 2.0, as credenciais não são mais necessárias. Digamos que o sistema A quer acessar recurso protegido no sistema B. O cliente do sistema A se autentica com o servidor de autorização informando que necessita acesso a um recurso protegido no sistema B. O servidor de autorização informa essa intenção ao dono do recurso (um usuário, ou o próprio sistema B) e pede que ele se autentique se quiser permitir o acesso. Se o dono do recurso aceitar o pedido, o servidor de autorização emite um token de acesso bem específico que permite acesso somente ao recurso para o qual recebeu autorização do dono do recurso. De posse do token de acesso, o sistema A fica capacitado a acessar o recurso protegido.
O segundo problema elencado é o desperdício do tempo de desenvolvedores, cuidando da autorização de acesso. Já deve estar claro que a introdução do conceito de servidor de autorização resolve esse problema. Com a chegada dos sistemas de autorização, desenvolvedores não precisam mais se preocupar com embutir, em cada sistema que desenvolvem, o software de autenticação e autorização de usuários. Eles ficam livres para gastar seu tempo resolvendo o problema que o sistema que desenvolvem se propõe a resolver.
⁵ Isso é apenas uma recomendação. O OAuth 2.0 admite que, se absolutamente necessário por questões, por exemplo, de uniformidade da experiência do usuário, o cliente capture as credenciais e as transmita ao servidor de autenticação, mas isso é uma prática considerada menos segura.
Conclusão
Este artigo apresentou uma visão geral (voltada para curiosos e não para especialistas) daquilo de que trata o protocolo OAuth, particularmente em sua versão 2.0. Ele procurou esclarecer o que é o protocolo, quais problemas ele endereça e como ele resolve esses problemas. Espero que a leitura tenha sido útil.
Luciano Medeiros — Head de um dos times de desenvolvimento de software na Acesso Digital