Guia OAuth para Iniciantes – Épico!

Atualizado  em 16/04/2017!

Este post é uma tradução livre do artigo original dividido em 3 partes “Beginner’s Guide to OAuth” do antigo site Hueniverse. Ele trata exclusivamente da versão 1.0 do OAuth, embora muitos elementos não tenham mudado e outros tenham sido simplificados (principalmente a parte de segurança). Quem tiver dúvidas sobre OAuth, pode me perguntar, foi meu TCC em Ciência da Computação.

Neste guia você vai ver:

  1. Introdução
    1. Benefícios ao usuário final
    2. Escopo
    3. Definições
    4. Fluxo de trabalho do protocolo
  2. Arquitetura e Segurança
    1. Além do Basic
    2. Acesso direto e delegado
    3. Credenciais
    4. Assinatura e Hash
    5. Limitação do Segredo
    6. Timestamp e Nonce
    7. Métodos de assinatura
    8. Assinatura de Base String

1 Introdução

Este guia foi projetado para público técnico com foco em implementação. Eu dediquei uma seção para a perspectiva do usuário-final que eu espero seja ampliada com projetos de interface de usuário, guias de melhores práticas e é claro, fluxos de trabalho. Para aproveitar ao máximo deste guia, tenha a especificação em mãos para referenciá-la, adicionando cores onde for necessário. Este guia não substitui a especificação e não pode ser usada sozinha para uma implementação pois é incompleto.

Benefícios ao Usuário-Final

OAuth permite que você compartilhe seus recursos privados (fotos, vídeos, lista de contatos, contas de banco) armazenadas em um site com outro site sem ter de dar seu usuário e senha. Há muitas razões pelas quais você não deve compartilhar suas credenciais. Dando a senha de sua conta de e-mail para um site de redes sociais eles podem olhar seus amigos o que é a mesma coisa que depois de um jantar, você dar seu cartão de crédito com sua senha para o garçom ir pagar a conta por você. Qualquer restaurante que peça a senha do seu cartão de crédito não é confiável, embora os usuários de internet acreditem que na web as coisas sejam diferentes. OAuth ao resgate!

[…]As metáforas da chave do manobrista e cartões de créditos são ambas boas metáforas para a perspectiva do usuário quanto ao OAuth. […] Usuários não se preocupam com protocolos e padrões – eles se preocupam com a melhor experiência com privacidade e segurança. Isto é exatamente o que o OAuth pretende atingir. Com os serviços web na moda, as pessoas esperam que seus serviços funcionem juntos para formar algo novo. Ao invés de usar um único site para todas suas necessidades online, usuários usam um site para suas fotos, outro para vídeos, outro para e-mail, e por aí vai. Nenhum site pode ser perfeito em tudo. Para permitir esses tipo de integração, os sites precisam acessar os recursos do usuário de outros sites, e estes muitas vezes são protegidos (fotos privadas de família, documentos do trabalho, registros do banco). Eles necessitam de uma chave para pegá-los.

A chave usada pelos usuários é usualmente a combinação de um nome de usuário e senha. Isto pode ser um OpenID ou qualquer outra credencial de login. Mas esta chave é muito poderosa e irrestrita para compartilhar por aí. Ela também não pode ser descompartilhada uma vez que tenha sido dada, exceto alterando-a e consequentemente privando o funcionamento de todos os demais sites que usavam-na. Ao invés disso, OAuth permite manejar Tokens. Cada token concede acesso a um site específico ( um site de edição de vídeos) para recursos específicos (somente vídeos do último final de semana) e por uma duração definida (as próximas duas horas).

Diferente do OpenID onde os usuários devem fazer algo previamente – dar uma identididade OpenID que eles possam usar para logar-se nos sites – OAuth é completamente transparente para os usuários. Em muitos casos (se foi feito certo), o usuário-final não irá saber nada sobre OAuth, o que ele é ou como funciona. A experiência do usuário será específica para a implementação de ambos os sites requisitando acesso e um armazenando recursos, e ajustado ao dispositivo que estiver sendo usado (navegador web, celular, PDA, set-top box). [… exemplo de fotos.exemplo.com …]

Escopo

O que é publicamente conhecido como OAuth é na verdade a especificação OAuth Core 1.0. A designação Core é utilizada para tensionar que isto é um esqueleto para outras extensões e protocolos serem construídos sobre ele. OAuth Core 1.0 por si só não provê muitas features desejadas como uma descoberta automática de end-points, suprote a linguagens, suporte a XML-RPC e SOAP, definição padrão de acesso a recursos, integração OpenID, a algoritimos de autenticação completos e muitas outras grandes idéias postadas no grupo OAuth.

Isto era intencional e é visto pelos autores como um benefício. Como o nome implica, Core combina com os aspectos mais fundamentais do protocolo:

  • Estabelecer um mecanismo d etroca de nome de usuário e senha para um token com permissões definidas (seção 6).
  • Provê ferramentas para proteger estes Tokens (seção 9).

Isto é importante para entender que segurança e privacidade não estão garantidas pelo protocolo. De fato, OAuth por si só provê nenhuma privacidade e depende de outros protocolos para cumprir isso (como SSL). Tendo disto isso, OAuth pode ser implementado de uma maneira muito segura e a especificação inclui um bom montante de considerações de segurança para incluir contas quando trabalha com recursos sensíveis. Somente com o uso de senhas junto de nomes de usuários para ganhara cesso, sites usarão tokens juntos com segredos para acessar recursos. E somente como senhas, segredos devem ser protegidos.

Definições

Devido ao entendimento do OAuth estar relacionado ao entendimento destes termos, vamos dar alguma explanação das definições presentes no protocolo:

Provedor de Serviço (Service provider) – o Provedor de Serviço controla todos os aspectos da implementação OAuth. O Provedor de Serviço é o termo utilizado para descrever o site ou serviço web onde os recursos restritos estão localizados. Ele pode ser um site de compartilhamento de fotos onde os usuários mantém albuns, um serviço bancário online, um site de microblogging, ou qualquer outro serviço onde “coisas privadas do usuário” se encontram. OAuth não determina que o Provedor de Serviço também será o provedor de identidade o que significa que o Provedor de Serviço pode usar seus próprios nomes d eusuário e senha para autenticar usuários, ou usar outros sistemas como OpenID.

Usuário (User) – o usuário é a motivação para a existência do OAuth. Sem ele não há sentido você ler isto aqui. O usuário tem “coisas” que ele não quer tornar públicas no Provedor de Serviço, mas eles querem compartilhar com outros sites. No Oauth, o protocolo para sem interação manual com o usuário a menos uma vez para receber permissão para garantir acesso.

Consumidor (Consumer) – este é o nome dado para a aplicação tentando acessar os recursos do Usuário. Isto pode ser um website, um programa desktop, um dispositivo móvel, uma set-top box, ou qualquer coisa conectada à web. O Consumidor é quem quer a permissão para acessar os recursos e o Consumidor é onde a parte útil do OAuth acontece. OAuth define “Desenvolvedor Consumidor” (Consumer Developer) como a entidade escrevendo código para interagir com o Provedor de Serviço. ‘Chave do Consumidor’ (Consumer Key) e ‘Segredo do Consumidor’ (Consumer Secret) serão explicados mais tarde.

Recursos Protegidos (Protected Resources) – a “coisa” que o OAUth protege e permite acesso. Isto pode ser dados (fotos, documentos, contatos), atividades (postando um item no blog, transferindo fundos) ou qualquer URL que necessitam de restrições de acesso.

Tokens – são usados ao invés de credenciais do Usuário para acessar os recursos. Um token é geralmente uma string randômica de letras e números (mas não limitada a isto) que é única, difícil de adivinhar, e pareada com um Segredo para proteger o Token de sofrer abusos. OAuth define dois tipos diferentes de Tokens: Requisição (Request) e Acesso (Access). Isto será explicado mais tarde em maiores detalhes.

Fluxo de Trabalho do Protocolo

OAuth é melhor explicado com exemplos da vida real.

A especificação inclui um Apêndice A com um exemplo similar mas focado na sintaxe de chamadas HTTP. Este passo-a-passo demonstra uma sessão OAuth típica e inclui as perspectivas do Usuário, Consumidor e Provedor de Serviço. Os websites e pessoas mencionadas são fictícios. As referências escocesas são reais. E então nossa história começa…

“Jane está voltando de suas férias na Escócia. Ela passou duas semanas na ilha de Islay amostrando Scotch. Quando ela voltou para casa, Jane queria compartilhar algumas de suas fotos das férias com seus amigos. Jane usa Faji, um site de compartilhamento de fotos, para compartilhar as fotos da jornada. Ela loga-se em sua conta faji.com, e faz upload de duas fotos que ela marca como privadas.”

Usando terminologia OAuth, Jane é o Usuário e Faji o Provedor de Serviço. As 2 fotos de Jane que foram “upadas” são os Recursos Protegidos.

“Depois de compartilhar suas fotos com uns poucos amigos online, Jane quer também compartilhar com sua avó. Ela não quer compartilhar suas garrafas raras de Scotch com ninguém. Mas vovó não tem conexão com Internet então Jane planeja encomendar revelações e enviar pelo correio para vovó. Sendo uma pessoa responsável, Jane usa Beppa, um ambiente amigável de serviço de impressão de fotos.”

Usando terminologia OAuth, Beppa é o Consumidor. Desde que Jane marcou as fotos como privadas, Beppa deve usar OAuth para ganhar acesso às fotos para poder imprimi-las.

“Jane vista beppa.com e inicia a requisição de impressão. Beppa suporta importação de imagens de muitos sites de compartilhamento de fotos, incluindo Faji. Jane seleciona a fonte de fotos e clica em Continuar.”

Quando Beppa adicionou suporte a importação de fotos do Faji, um desenvolvedor do Beppa chamada no OAuth de Consumidor Desenvolvedor obteve uma Chave de Consumidor e um Segredo de Consumidor de Faji para usar com a API OAuth-Enabled de Faji.

Depois que Jane clica em Continuar, algo importante acontece no background entre Beppa e Faji. Beppa requisita de Faji um Token de Requisição. Neste ponto, o Token de Requisição (Request Token) não é específica do Usuário, e pode ser usado por Beppa para ganhar aprovação do Usuário de Jane para acessar suas fotos privadas.

“Jane clicou em Continuar e agora aguarda pela mudança de tela. Ela prova seupremiado Black Bowmore enquanto aguarda pela próxima página carregar.”

Quando Beppa recebe o Token de Requisição, ele redireciona Jane para a URL de Autorização de Usuário OAuth do Faji com o token de Requisição e pergunta a Faji para redirecionar Jane de volta uma vez que a aprovação foi garantida para http://beppa.com/order. Jane foi redirecionada para Faji e é requisitado que se logue no site. OAuth requer que o os Provedores de Serviço primeiro autentiquem o usuário, e então questionem para que conceda acesso ao Consumidor.

“Jane nota que agora está na página do Faji olhando a URL, e entra seu nome de usuário e senha.”

OAuth permite que Jane mantenha seu nome de usuário e senha privados e não compartilhe com Beppa ou qualquer outro site. Em nenhum momento Jane entra com suas credenciais em Beppa.com.

Depois de logar com sucesso em Faji, Jane é questionada para garantir acesso a Beppa, o Consumidor. Faji informa de quem é a requisição de acesso (neste caso Beppa) e o tipo de acesso que será permitido. Jane pode aprovar ou negar o acesso.

“Jane confirma que Beppa está recebendo acesso limitado que ele precisa. Ela não quer permitir a Beppa mudar suas fotos ou fazer nada com elas. Ela também nota que um único acesso por uma hora é tempo o bastante para Beppa pegar suas fotos.”

Uma vez que Jane tenha aprovado a requisição, Faji marca o Token de Requisição como Autorizado-Usuário por Jane. O browser de Jane é redirecionado de volta a Beppa, para a URL previamente provida http://beppa.com/order junto com o Token de Requisição. Isto permite a Beppa saber que ele pode continuar a carregar as fotos de Jane.

“Jane aguarda por Beppa para apresentar com suas fotos carregadas da conta do Faji.”

Enquanto Jane aguarda, Beppa usa o Token de Requisição autorizado e negocia por um Token de Acesso (Access Token). Tokens de Requisição são somente bons para obter aprovação do usuário, enquanto Tokens de Acesso são usados para acessar Recursos Protegidos, neste caso as fotos de Jane. Na primeira requisição, Beppa troca o Request Token por um Token de Acesso e no segundo (podem ser múltiplas requisições, uma para a lista de fotos, e umas poucas mais para cada foto) requisição pega as fotos.

Quando Beppa termina, o browser de Jane atualiza e completa o pedido.

Beppa carregou com sucesso a foto de Jane. Elas são apresentadas como miniaturas para ela selecionar para fazer o pedido.

“Jane está muito impressionada como Beppa pegou suas fotos sem lhe perguntar seu nome de usuário e senha. Ela gosta que ela veja a localização do pedido de impressão.”

Arquitetura e Segurança

Como um protocolo de delegação de autorização, OAuth deve ser seguro e permitir ao Service Provider confiar o Consumer e validar a credencial provida para ganhar acesso. Para cumprir isto, OAuth define um método de validação de autenticidade de requisições HTTP. Este método é chamado de Signing Requests (Assinatura de Requisições) e para melhor entender, nós devemos primeiro explorar as características de segurança e arquitetura do protocolo, que será o foco desta parte do Guia para Iniciantes.

Aviso do autor original: este tutorial não é um guia de segurança compreensivo, completo ou preciso. Ele pode não ser utilizado para fazer qualquer decisões relacionadas a segurança, e qualquer implementação deve ser revisada por peritos em segurança para garantir a mesma. A especificação do OAuth provê um bom ponto de início para considerarmos a ramificação de segurança de qualquer implementação, mas é comum o caso quando chegamos na quetsão de segurança, a especificação deve não deve ser entendida como completa. O guia toma algumas liberdades de explicar conceitos complexos de segurança para o propósito de fazer ele mais acessível, mas inclui referências de leituras de aprofundamento.

Além do Basic

HTTP define um método de autorização chamado “Basic” que comumente é utilizado por muitos sites e APIs. A maneira como o “Basic” funciona é enviando o usuário e senha em texto plano com cada requisição. Quando não utilizado sobre HTTPS, “Basic” sofre de uma falha de segurança significante e limitações, mas para esta discussão nossos focos serão três. Primeiro, ele transmite senhas descriptografadas o que permite a qualquer um ficar ouvindo para capturar e reusar estas credenciais. Segundo, não há nada ligando as credenciais à requisição, o que significa uma vez comprometida, ela pode ser usada com qualquer requisição sem limitações. Terceiro, “Basic” não provê um placeholder para delegação de credenciais e somente suporta um par simples de usuário-senha. Delegação requer ser apto a enviar ambas credenciais do requisitante (consumer) e daquelas da parte de delegação o acesso (User). A arquitetura do OAuth explicitamente endereça estas três limitações.

O método de assinatura do OAuth foi primariamente designado para comunicações inseguras – principalmente não-HTTPS. HTTPS é a solução recomendada para prevenir ataque do homem-do-meio (MITM – man-in-the-middle attack), eavesdropping, e outros riscos de segurança. Entretanto, HTTPS é por vezes muito caro para muitas aplicações, tanto para instalar quanto para manter. Quando OAuth é utilizado sobre HTTPS, ele oferece um simples método para uma implementação mais eficiente chamada textoplano (plaintext) que descarrega a maioria dos requisitos da camada HTTPS. É importante entender que textoplano não pode ser utilizado sobre um canal inseguro. Este tutorial irá focar nos métodos designados para trabalhar sobre um canal inseguro: HMAC-SHA1 e RSA-SHA1.

Acesso direto e delegado

O objetivo principal do OAuth é criar um “protocolo de delegação de acesso”. Permitindo uma parte acessar recursos de alguém em seu nome é o núcleo do protocolo OAuth e o vazio que procura preencher. Em seu cenário de acesso delegado, também conhecido como o cenário dos 3-passos, as três partes (passos) envolvidas são o Service Provider, Consumer e User. Desde que as requisições são somente feitas pelo Consumer, ele necessita de uma maneira de se autenticar a si mesmo com o Service Provider, mas também para autenticar a autorização para acessar os dados do User. Isto requer que OAuth suporte requisições HTTP com dois conjuuntos de credenciais.

OAuth pode fazer um trabalho igualmente bom ao endereçar o cenário de acesso direto, também conhecido como cenário de 2-passos. Este é o caso que a maioria das pessoas é familiar onde um lado autentica-se com o outro, por exemplo, uma pessoa se autenticando em um site usando um nome de usuário e senha. Neste cenário, nenhuma condição está envolvida e nenhum acesso está sendo delegado. O Consumer está acessando os recursos no nome por si mesmo, fazendo o Consumer e o User a mesma entidade.

Isto pode ser um pouco confuso quando um Consumer está fazendo requisições separadas, ambas requisições 2-passos em nome próprio, e requisições 3-passos em nome do User. Quando pensamos sobre o fluxo de assinatura, ele ajuda a entender como cada credencial é designada para realizar. Desde as credenciais do Consumer são usadas para autenticar a parte fazendo a requisição, se aquela parte está fazendo a requisição em seu próprio nome, ela também é a usuária-final da requisição. Aplicações desejando usar OAuth como uma alternativa ao “Basic” do HTTP, pode usar a Consumer Key e Consumer Secret para esconder o usuário e senha, e deixar o Token e Token Secret vazio. Isto, é claro, requer suporte direto na aplicação e não somente clientes podem somente tentar usar onde o “Basic” do HTTP seria aceito.

Uma vez que o guia é focado no caso de uso primário do OAuth que é a delegação de acesso, o resto deste tutorial irá focar no cenário de 3-passos (a menos que se diga o contrário).

Credenciais

Em todas transações web, a credencial comumente utilizada é a combinação usuário-senha. O objetivo primário do OAuth é permitir o acesso delegado a recursos privados. Isto é feito utilizando dois grupos de credenciais: o Consumer identifica a si memso usando sua Consumer Key e Consumer Secret, enquanto o usuário é identificado por um Token e Token Secret. Cada grupo – Consumer Key-Secret e Token-Secret – pode ser entendido como um par de usuário-senha (um para a aplicação e um para o usuário-final). Mas enquanto as credenciais do Consumer trabalham muito como um usuário e senha, o User é representado por um Token cque é diferente do que seu usual nome de usuário e senha. Isto permite ao Service Provider e User maior controle e flexibilidade, garantindo acesso ao Consumer. Por exemplo, o User pode revogar um Token sem ter de trocar senhas e quebrar outras aplicações. O desacoplamento do nome de usuário do User e a senha no Token é um dos aspectos mais fundamentais da arquitetura OAuth.

OAuth inclui dois tipos de Tokens: Request Token e Access Token. Cada Token tem um papel muito específico no fluxo de delegação do OAuth. Enquanto na maior parte um artefato de como a especificação do OAuth evoluiu, a arquitetura 2-Tokens oferece algumas características de usabilidade e segurança que valeram a pena ficar na especificação. OAuth opera em dois canais: um canal de frente que é usado para engajar o User e requisitar a autorização, e um canal de trás usado pelo Consumer para interagir diretamente com o Service Provider. Pela limitação o Access Token para o canal de trás, o Token por si mesmo mantém escondido do User. Isto permite o Access Token cuidar de significados especiais e ter uma tamanho maior do que o Request Token do canal-frontal que é exposto para o User quando requisitando autorização, e em alguns casos necessita de ser manualmente entrado (dispositivos móveis ou set-top boxes).

O fluxo de assinatura de requisição trata todos os Tokens do mesmo jeito e o fluxo é idêntico. Os dois Tokens são específicos para o fluxo de autorização, não o fluxo de assinatura que usa o Token igualmente. Isto não significa que os dois tipos de Tokens são intercambiáveis, somente que eles provêem a mesmas função de segurança quando assinando requisições.

Assinatura e Hash

OAuth usa assinaturas digitais ao invés de enviar as credenciais completas (especialmente, senhas) com cada requisição. Similar à maneira como as pessoas assinam documentos para indicar seu acordo com um texto específico, assinaturas digitais permitem o recipiente verificar que o conteúdo da requisição não mudou na transição. Para fazer isto, o emissor usa um algoritmo matemático para calcular a assinatura e incluir com a requisição.

Por outro lado, o recipiente realiza o mesmo fluxo para a calcular a assinatura da requisição e compara para o valor da assinatura provida. Se os dois baterem,, o recipiente pode ser confidente que as requisições não foram modificadas na transição. O nível de confiança depende das propriedades do algoritmo de assinatura utilizado (alguns são mais fortes que outros). Este mecanismo requer que ambos os lados usem o mesmo algoritmo de assinatura e apliquem-no da mesma maneira.

Uma maneira comum de verificar o conteúdo por assinatura digital é utilizando algoritmos de hash. Geralmente, hashing é o processo de tomar dados (de qualquer tamanho) e condensá-los em um valor muito pequeno (digest) em uma maneira totalmente reproduzível (via-única). isto significa que usando o mesmo algoritmo de hash sobre os mesmos dados irá produzir o mesmo pequeno valor. Diferente da compressão que tenta preservar muitos dos dados originais, hashing usualmente não permite que os dados popssam ser retornados ao valor original. Por exemplo, o conteúdo: “teste de hash” produz um valor de hash (em base64 usando o algoritmo SHA-1) de “ORpa0WkdH1oMtZiCGjv8IlEx0N0=”. Não importa quão longo seja o conteúdo, o resultado será sempre do mesmo tamanho.

Por si só, hashing não verifica a identidade do emissor, somente integridade dos dados. Para permitir ao recipiente verificar que a requisição veio de um emissor alegado, o algoritmo de hash é combinado com um shared secret (segredo compartilhado). Se ambos os lados concordam  em algum segredo compartilhado conhecido somente por eles, eles podem adicioná-lo ao conteúdo que será hasheado. Isto pode ser feito simplesmente concatenando o segredo ao conteúdo, ou usando um algoritmo mais sofisticado com um mecanismo interno para segredos como o HMAC. De qualquer maneira, produzindo e verificando a assinatura requer acesso ao segredo compartilhado, que previne atacntes de se tornarem aptor a forjar requisições.

Neste exemplo, o conteúdo: “teste de hash” e o segredo compartilhado “segredo” produzem um valor digerido (em base64 usando o algoritmo HMAC-SHA1) de “K3Vo6oXbevfHBBWoLCErKxr87M4=”. Note como qualquer alteração no conteúdo ou segredo muda inteiramente o resultado, que faz o mecanismo difícil de forjar.

O benefício desta abordagem comparado ao esquema de autorização “Basic” do HTTP é que o segredo atual nunca será enviado junto da requisição. O segredo é usado para assinar a requisição mas não é parte dela, não pode ser extraído (quando implementado corretamente). Assinaturas são o meio mais seguro de comprir a mesma fucnionalidade de enviar um segredo compartilhado com a requisição sobre um canal inseguro.

Limitação do Segredo

Em OAuth, o segredo compartilhado depende do método de assinatura utilizado. Nos métodos PLAINTEXT e HMAC-SHA1, o segredo compartilhado é uma combinação do Consumer Secret e Token Secret. No método RSA-SHA1, o Consumer Private Key é usado exclusivamente para assinar requisições e serve como um segredo compartilhado assimétrico (chave pública). o modo como trabalha os pares de chaves assimétricas, é que cada lado – o Consumer e Service provider – usa uma chave para assinar a requisição e outra chave para verificar a requisição. As chaves – Private Key para o Consumer e Public Key para o Service Provider – devem bater, e somente o par certo pode assinar com sucesso e verificar a requisição. A vantagem de usar segredos compartilhados assimétricos é que igualmente o Service provider não ter acesso a Private Key do Consumer que reduz a probabilidade do segredo ser quebrado.

Entretanto, desde que o método RSA-SHA1 não use o Token Secret (ele não use o Consumer Secret ao invés mas que é adequadamente substituído pelo Consumer Private Key), a Private Key é única proteção contra ataques e se comprometida, põe todos os Tokens em risco. Isto não é só o caso com os outros métodos onde um Token Secret comprometido (ou mesmo Consumer Secret) não permite acesso aos outros recursos protegidos por outros Tokens (e seus segredos).

Quando implementando OAuth, é crítico o entendimento das limitações dos segredos compartilhados, simétricos ou assimétricos. O Consumer Secret (ou chave privada) é usado para verificar a identidade do Consumer pelo Service Provider. No caso de um Consumer web-based como um webserver, isto é relativamente fácil manter o Consumer Secret (ou chave privada) seguro. Entretanto, quando o Consumer é uma aplicação desktop, uma aplicação mobile, ou qualquer outro software lado-cliente como applets no browser (Flash, Java, Silverlight) e scripts (Javascript), as credenciais do Consumer devem ser incluídas em cada cópia da aplicação. isto significa que o Consumer Secret (ou chave privada) deve ser distribuido com a aplicação, o que compromete a mesma.

Isto não previne usar OAuth dentro destas aplicações, mas isto limita a quantidade de confiança que o Service Provider pode ter em seus segredos públicos. Desde que segredos não podem ser confiados, o Service Provider deve tratar cada aplicação como entidades desconhecidas e usar a identidade do Consumer somente para atividades que não requerem nenhum nível de confiança, como coletar estatísticas sobre aplicações. Alguns Service provider podem optar por banir estas aplicações ou oferecer protocolos diferentes ou extensões. Entretanto, neste ponto não há nenhuma solução simples conhecida para esta limitação.

É importante notar, que mesmo através das credenciais do Consumer são quebradas nestas aplicações, as credenciais do User (Token e segredo) são específicas para cada instância do Consumer cujo protege suas propriedades de segurança. Isto é claro depende da implementação do Consumer e como ela armazena as informações dos Token no lado do cliente.

Isto é um pouco diferente do cenário 2-passos desde que as credenciais do usuário são basicamente somente usuário e senha e não há nenhum Token ou Token secret. Quando OAuth é utilizado como um substituidor direto do HTTP Basic fazendo o Consumer e User a mesma entidade, a aplicação pode ser escrita para Users entrarem suas credenciais em um prompt, portanto removendo a necessidade de então, colocar hard-code na aplicação. Usando OAuth para uma simples assinatura tem a mesma experiência do usuáro do Basic HTTP, mas quando usado sobre um canal inseguro OAuth provê uma segurança muito maior.

Timestamp e Nonce

A assinatura e segredo protegido provêem algum nível de segurança mas são vulneráveis a ataques. A assinatura protege o conteúdo da requisição ser alterada enquanto o segredo compartilhado garante que as requisições somente podem ser feitas (e assinadas) por um Consumer autorizado. O que está perdendo é algo para prevenir requisições interceptadas por um Consumer não-autorizado, usualmente por sniffamento de rede, de ser reutilizado. Isto é conhecido como um ataque replay. Tanto quanto os segredos compartilhados permanecerem protegidos, qualquer um escutando na rede não estará apto a forjar novas requisições como requerer uso do segredo compartilhado. Eles irão, entretanto, estar aptos a fazer a mesma requisição de assinatura novamente e novamente. Se a requisição interceptada provêr acesso a dados protegidos, isto pode ser um risco significante de segurança.

Para prevenir requisições comprometidas e serem utilizadas de novo, OAuth usa um nonce e timestamp. O termo nonce significa “número usado uma vez” (number used once) e é um única e normalmente aleatória string que é utilizada para unicamente identificar cada requisição assinada. Tendo um identificador único para cada requisição, o Service Provider está apto a prevenir requisições de serem usadas mais de uuma vez. Isto significa que o Consumer gera uma string única para cada requisição enviada ao Service provider, e o Service Provider mantém registro de todos os nonces usados para prevenir que sejam usados uma segunda vez. Uma vez que o valor do nonce está incluindo na assinatura, ele não pode ser alterado por um atacante sem conhecer o segredo compartilhado.

Usar nonces pode ser muito custoso para Service Providers e eles demandam armazenamento persistente de todos os valores nonce recebidos, eternamente. Para tornar a implementação mais fácil, OAuth adiciona um valor timestamp para cada requisição que permite ao Service Provider manter somente valores de nonce por um tempo limitado. Quando uma requisição chega com um timestamp mais velho do que a janela de tempo, ele é rejeitado porque o Service Provider não tem mais nonces daquele período. É seguro assumir que a requisição enviada depois que o limite de tempo permitido é um ataque de replay. OAuth provê um mecanismo genérico para implementação de timestamps mas deixa a implementação atual acima de cada Service Provider (uma área que muitos acreditam que possa ser revisitada na especificação). De um ponto de vista de segurança, o nonce real é uma combinação de valor de timestamp e string nonce. Somente juntos eles provêem um valor perpétuo e único que nunca pode ser usado novamente por um atacante.

Métodos de Assinatura

OAuth define 3 métodos de assinatura usados para assinar e verificar requisições: PLAINTEXT, HMAC-SHA1 e RSA-SHA1. PLAINTEXT destina-se para trabalhar sobre HTTPS e é um costume similar de como o Basic HTTPS transmite as credenciais em texto puro. Diferente do Basic, PLAINTEXT suporta delegação. Os outros dois métodos usam os algoritmos de assinatura HMAC e RSA combinados como o método de hash SHA1. Desde que estes métodos são muito complexos para explicar neste guia, implementadores são encorajados a ler outros guias específicos para eles, e não escrever suas próprias implementações, mas ao invés disso acreditar em soluções open-source disponíveis para a maioria das linguagens.

Quando assinando requisições, é necessário especificar que método de assinatura está sendo usada para permitir o recipiente produzir a assinatura para verificação. A decisão de qual método de assinatura usar depende dos requisitos de segurança de cada aplicação. Cada método vem com um grupo de vantagens e limitações. PLAINTEXT é trivial para uso e toma significativamente menos tempo para calcular, mas somente é seguro sobre HTTPS ou canais de segurança similares. HMAC-SHA1 oferece um simpels e comum algoritmo e está disponível na maioria das plataformas mas não em dispositivos legados e usa um segredo compartilhado simétrico. RSA-SHA1 provê segurança aprimorada usados pares de chave mas é mais complexo e requer geração de chave e uma longa curva de aprendizado.

Assinatura de base String

Como explicado acima, ambos os lados devem executar o processo de assinatura de uma maneira idêntica a fim de produzir o mesmo resultado. Não somente devem ambos usar o mesmo algoritmo e segredo compartilhado, mas eles devem assinar o mesmo conteúdo. Isto requer um método consistente para converter requisições HTTPS em uma string simples que é usada para assinar o conteúdo – a Assinatura String Base. Criar a String Base é onde a maioria dos desenvolvedores debatem-se com a especificação. A próxima parte do Guia para Iniciantes provê um exemplo completo de assinatura de uma requisição OAuth incluindo a criação da Assinatura String Base.

 

OAuth (nem) sempre é a solução!

Este post é uma tradução livre do original “OAuth isn’t (Always) the solution” disponível no antigo site do Hueniverse. Ele compreende mais um de meus posts com o protocolo de delegação de acesso que foi tema de meu TCC. Conforme for encontrando os artigos e posts que escrevi ou traduzi, vou postando aqui pro pessoal conhecer o protocolo que é usado por gigantes da Internet como Google e Yahoo. Neste post, é abordada a questão de como o pessoal que curte o OAuth acaba muitas vezes usando o protocolo até mesmo em situações em que não deveriam. Saber quando usar ou não usar tecnologias específicas em situações específicas é o que costumo dizer que diferencia os bons desenvolvedores dos xiitas da linguagem X ou do protocolo Y. Enjoy it!


Não entenda errado, OAuth é grande, ou ao menos eu espero estar considerando o número de horas que eu pus esta semana deixando as especificações prontas. Mas eu tenho ouvido um monte de conversas sobre no que OAuth é bom e algumas fazem algum sentido para mim. Eu não quero apontar exemplos específicos como algumas pessoas que eu admiro fizeram, mas eles estão aqui. No Data Sharing Summit, OAuth foi jogado dentro de um conjunto de soluções para os problemas que ele nada podia fazer.

OAuth é perfeito para qualquer caso onde você não quer dar seu nome de usuário e senha, mas ao invés disso quer dar algo que você pode revogar a qualquer momento, dando acesso limitado a outro site sobre suas coisas. Eu tenho estado ocupado nas últimas noites escrevendo um novo exemplo completo para a especificação do OAuth. Ele começa mais ou menos assim:

“Neste exemplo, o Provedor de Serviço fotos.exemplo.com é um site de compartilhamento de fotos, e o Consumidor impressao.exemplo.com é um site de impressão de fotos. Jane, a Usuária, gostaria que impressao.exemplo.com imprimisse sua foto privada ‘férias.jpg’ armazenada em fotos.exemplo.com.

Quando Jane autentica-se em fotos.exemplo.com usando seu nome de usuário e senha, ela pode acessar a foto através da URL ‘http://fotos.exemplo.com/arquivo=férias.jpg’. Outros Usuários não podem acessar aquela foto, e Jane não quer compartilhar seu nome de usuário e senha com impressao.exemplo.com.”

Para mim, este é o melhor exemplo. Onde estão alguns lugares que OAuth não está? Iniciamos com o Provedor de Serviço. Isto deve soar óbvio mas não é (para algumas pessoas). Outro teste é se o OAuth torna a vida mais difícil. Se você atualmente somente entra seu nome de usuário e senha em alguma aplicação, mas terá que atravessar vários passos, telas e formulários, isto provavelmente significa que você não deveria ter usado OAuth.

OAuth substitui um diálogo para nome de usuário e senha (tipicamente um formulário de login – OAuth não menciona nomes de usuário e senhas especificamente) com dois diálogos: um para o nome de usuário e senha, e outro para lhe perguntar se você quer dar algum acesso ao site às suas coisas privadas. Isto é tudo. Se você leu OAuth e pensou que ele é perfeito para o que você está fazendo, pergunte a si mesmo se você está apto a manter este fluxo simples – se você não puder, é porque está usando a ferramenta errada.

OAuth e Phishing

Este post é uma tradução livre, feita por mim em 2009, do original “Would you like Quechup with your Phish & Chips?” (algo como “gostaria de catchup com seu peixe e fritas?”, trocadilho com a técnica de Phishing usada para enganar tontos na Internet e com o site Quechup que pegava os emails dos seus contatos para fazer spam). Artigo original disponível no antigo site do Hueniverse. Para quem não leu o meu primeiro post sobre OAuth, o protocolo aberto foi tema de meu TCC, defendido em 2010 em minha monografia de bacharelado.

A idéia de disponibilizar este post é para corrigir alguns erros comuns e preconceitos infundados que o pessoal tem com relação ao OAuth. Os gigantes Google, Facebook e Twitter usam OAuth. Por que VOCÊ não usaria?


Comentários públicos sobre OAuth são uma grande oportunidade para explicar a idéia e objetivos por trás do protocolo. Rob Sayre perguntou sobre usar o protocolo de redirecionamento para obter a permissão de acesso:

“Talvez eu esteja esquecendo algo, mas os usuários não são treinados para não colocarem suas credenciais em sites que foram redirecionados?”

Primeiramente, você está certo.

Redirecionamento leva o risco de usuários treinados seguirem um padrão de chegar a uma tela de login sem explicitamente entrarem a URL na barra de endereços do navegador. A idéia básica por trás do phishing é levar o usuário a uma página que ele pensa ser uma coisa mas na verdade é outra. Como um link em um e-mail feito para parecer do seu banco, mas que na verdade é uma página falsa pedindo seu nome de usuário e senha. Quando você digita suas credenciais, ela normalmente redireciona você de volta à página real do banco para que entre novamente (fazendo você achar que errou na hora de digitar algo).

O objetivo primário do OAuth é prevenir que você necessite compartilhar sua senha com aplicações legítimas que você realmente deseja usar. Muitos sites hoje em dia não providenciam uma API porque eles não querem as senhas dos seus usuários compartilhadas com ninguém. Mas como o Twitter prova, provendo uma API que pode ser o que o coloca à frente dos outros, e provendo uma API é tornar-se mais e mais essencial para rodar um negócio de internet. Com isto em mente, ter uma maneira consistente de delegar acesso é crítico.

A melhor solução para ataques de phishing é nunca entrar com sua senha em páginas da internet que você não entrou digitando o endereço no navegador (ou que não foi a partir dos seus favoritos). OAuth pode não ajudar usuários cuidadosos, e phishing é muito sobre não prestar atenção no que se está fazendo. Há uma discussão interessante sobre phishing no grupo de OAuth, embora isto seja além do escopo do protocolo. Guy Huntington faz alguns apontamentos muito bons sobre o assunto.

Para que o OAuth funcione, o Consumidor (site ou aplicação) tem de “pedir que o usuário conceda acesso” para poder pegar os Recursos Protegidos do Usuário. OAuth não diz como o Provedor de Serviço deve fazer isso. Alguns vendedores do OpenID não permitem que você assine a partir de um redirecionamento, ao invés disso eles pedem que você abra um novo navegador, vá até a tela de login e autentique-se manualmente. Eles somente permitem que você conceda acesso via redirecionamento uma vez que você já esteja logado. Provedores de Serviço OAuth podem implementar a mesma lógica que os ajudará a quebrar maus hábitos. Eles também podem usar OpenID para reduzir a quantidade de nomes de usuário e senhas que o usuário precisa cuidar.

Um ponto importante de ter em mente é que um dos objetivos do projeto OAuth é se manter o mais simples possível e fácil de implementar. Se você torná-lo muito difícil, aquelas aplicações de terceiros usarão o método tradicional de pedir o usuário e senha e postar os seus dados como já se faz hoje em dia. Google é um exemplo de companhia que conscientemente faz seu protocolo AuthSub perder apelo para os desenvolvedores adotarem-no (e pararem de fazer “screen scraping”).

Google AuthSub é perfeitamente seguro quando utilizado sobre HTTPS mas não muito quando utilizado sobre HTTP. A solução do Google é mostrar um aviso grande e vermelho quando você deseja dar acesso à outra aplicação em um canal não seguro. Todo mundo tem um compromisso em algum lugar. OAuth deixa para o Provedor de Serviço decidir o quão seguros seus recursos serão, enquanto estabelece um framework que os desenvolvedores podem usar através dos sites.

E por fim, não se esqueça do infame Quechup que não usa phishing para manipular os usuários visando obter acesso aos seus contatos do Google e fazer spamming para os e-mails da lista. Ele somente pede gentilmente por sua senha e então abusa dela. Eles teriam trocado facilmente umas poucas cargas na sua conta do Google Checkout enquando os usuários tem sorte deles não fazerem.

Um Provedor de Serviços OAuth bem implementado dá aos usuários grande controle sobre o que estão expondo e por quanto tempo. Enquanto OAuth não impede que o Quechup use seus contatos de maneiras que você não permite, ele tornou fácil para o Google simplesmente bloquear as Consumer Keys do Quechup tão logo quanto os reportes de abuso foram chegando, e preveniu assim de mais abusos de API.

Então minha resposta é: “OAuth não treina usuários para permitir phishing – ele treina-os para que não compartilhem seus nomes de usuário e senha com ninguém. E eles nunca devem fazê-lo.”