Pergunta

Estou tentando me orientar nas especificações do OAuth, seus requisitos e quaisquer implementações que posso encontrar e, até agora, realmente parece mais problema do que vale a pena, porque estou tendo problemas para encontrar um único recurso que reúna tudo .Ou talvez esteja apenas procurando algo mais especializado do que a maioria dos tutoriais.

Tenho um conjunto de APIs existentes – algumas em Java, outras em PHP – que agora preciso proteger e, por vários motivos, o OAuth parece ser o caminho certo a seguir.Infelizmente, minha incapacidade de encontrar os recursos certos para me ajudar a colocar um provedor em funcionamento desafia essa teoria.Como a maior parte disso será o uso da API de sistema para sistema, precisarei implementar um provedor de duas pernas.Com aquilo em mente...

  1. Alguém conhece algum bom tutorial para implementar um provedor OAuth de duas pernas com PHP?
  2. Dado que tenho APIs protegíveis em 2 idiomas, preciso implementar um provedor em ambos ou existe uma maneira de criar o provedor como um "controlador frontal" pelo qual posso canalizar todas as solicitações?
  3. Ao proteger serviços PHP, por exemplo, preciso proteger cada API individualmente, incluindo os recursos necessários do provedor em cada uma?

Obrigado pela ajuda.

Foi útil?

Solução

Eu daria um passo atrás e pensaria sobre o que um cliente adequadamente autenticado enviará você.

Você pode armazenar as chaves e credenciais em um banco de dados comum que é acessível a partir de ambos os conjuntos de serviços e apenas implementar o provedor OAuth em um idioma? Quando o usuário envia uma solicitação para um serviço (php ou java), você verifica a loja comum. Quando o usuário está configurando o cliente OAuth, você faz tudo isso através de um aplicativo PHP ou Java (sua preferência) e armazena as credenciais no banco de dados comum.

Existem alguns provedores de OAuth escritos em outros idiomas que você pode querer dar uma olhada:

Outras dicas

Rob, não tenho certeza de onde você chegou nisso, mas gostaria de acrescentar meus 2 centavos caso alguém mais se deparasse com essa pergunta.

Eu tive mais ou menos a mesma pergunta há alguns meses e ouvi falar de "OAuth" durante quase um ano.Eu estava desenvolvendo uma API REST que precisava proteger, então comecei a ler sobre OAuth...e então meus olhos começaram a rolar para trás na minha cabeça.

Provavelmente dediquei um ou dois dias inteiros folheando e lendo até decidir, assim como você, que o OAuth era um lixo confuso e simplesmente desisti dele.

Então comecei a pesquisar maneiras de proteger APIs em geral e comecei a entender melhor como fazer isso.A forma mais popular parecia ser enviar solicitações à API junto com uma soma de verificação de a mensagem inteira (codificada com um segredo que somente você e o servidor sabem) que o servidor pode usar para decidir se a mensagem foi adulterada no caminho do cliente, assim:

  1. O cliente envia /user.json/123?showFriends=true&showStats=true&checksum=kjDSiuas98SD987ad
  2. O servidor obtém tudo isso, procura o usuário "123" no banco de dados, carrega sua chave secreta e então (usando o mesmo método usado pelo cliente) recalcula sua PRÓPRIA soma de verificação, dados os argumentos da solicitação.
  3. Se a soma de verificação gerada pelo servidor e a soma de verificação enviada pelo cliente corresponderem, a solicitação está OK e é executada; caso contrário, é considerada adulterada e rejeitada.

A soma de verificação é chamada de HMAC e se você quiser um bom exemplo disso, é o que a Amazon Web Services usa (eles chamam o argumento de 'assinatura' e não de 'soma de verificação').

Portanto, dado que um dos principais componentes para que isso funcione é que o cliente e o servidor precisam gerar o HMAC da mesma maneira (caso contrário, eles não corresponderão), deve haver regras sobre COMO combinar todos os argumentos. .então, de repente, entendi toda aquela porcaria de "ordenação natural de bytes de parâmetros" do OAuth ...estava apenas definindo as regras de como gerar a assinatura porque era necessário.

Outro ponto é que cada parâmetro incluído na geração do HMAC é um valor que não pode ser alterado quando você envia a solicitação.

Então, se você apenas codificar o radical URI como assinatura, por exemplo:

  • /user.json == askJdla9/kjdas+Askj2l8add

então a única coisa na sua mensagem que não pode ser adulterada é o URI, todos os argumentos podem ser adulterados porque não fazem parte do valor de "soma de verificação" que o servidor irá recalcular.

Alternativamente, mesmo se você incluir TODOS os parâmetros no cálculo, você ainda corre o risco de "ataques de repetição", onde um intermediário mal-intencionado ou interceptado pode interceptar uma chamada de API e continuar reenviando-a para o servidor repetidamente.

Você pode corrigir isso adicionando um carimbo de data/hora (sempre use UTC) no cálculo do HMAC também.

LEMBRETE:Como o servidor precisa calcular o mesmo HMAC, você deve enviar qualquer valor usado no cálculo, EXCETO SUA CHAVE SECRETA (o OAuth chama isso de consumer_secret, eu acho).Portanto, se você adicionar carimbo de data/hora, certifique-se de enviar um parâmetro de carimbo de data/hora junto com sua solicitação.

Se você quiser tornar a API segura contra ataques de repetição, você pode usar um valor nonce (é um valor de uso único que o servidor gera, dá ao cliente, o cliente usa no HMAC, envia de volta a solicitação, o servidor confirma e marca esse valor nonce como "usado" no banco de dados e nunca permite que outra solicitação o use novamente).

OBSERVAÇÃO:'nonce' é uma maneira realmente exata de resolver o problema do "ataque de repetição" - os carimbos de data e hora são ótimos, mas como os computadores nem sempre têm valores de carimbo de data e hora sincronizados, você deve permitir uma janela aceitável no lado do servidor de como " antigo" uma solicitação pode ser (digamos 10 minutos, 30 minutos, 1 hora....A Amazon usa 15 minutos) antes de aceitá-la ou rejeitá-la.Neste cenário, sua API fica tecnicamente vulnerável durante todo o período.

Acho que os valores nonce são ótimos, mas só precisam ser usados ​​em APIs que são críticas para manter sua integridade.Na minha API, eu não precisava disso, mas seria trivial adicionar mais tarde se os usuários exigissem...Eu literalmente só precisaria adicionar uma tabela "nonce" em meu banco de dados e expor uma nova API para clientes como:

  • /nonce.json

e então, quando eles me enviarem isso de volta no cálculo do HMAC, eu precisaria verificar o banco de dados para ter certeza de que ele nunca havia sido usado antes e uma vez usado, marque-o como tal no banco de dados para que, se uma solicitação NUNCA chegasse novamente com o mesmo, uma vez que eu o rejeitaria.

Resumo

De qualquer forma, para encurtar a história, tudo o que acabei de descrever é basicamente o que é conhecido como "OAuth de duas pernas".Não há essa etapa adicional de fluxo para a autoridade (Twitter, Facebook, Google, qualquer que seja) para autorizar o cliente, essa etapa é removida e, em vez disso, o servidor confia implicitamente no cliente SE os HMACs que eles estão enviando corresponderem.Isso significa que o cliente tem a secret_key correta e está assinando suas mensagens com ela, então o servidor confia nela.

Se você começar a pesquisar online, este parece ser o método preferido para proteger métodos de API atualmente, ou algo parecido.A Amazon usa quase exatamente esse método, exceto que eles usam um método de combinação ligeiramente diferente para seus parâmetros antes de assinar tudo para gerar o HMAC.

Se você estiver interessado eu escreveu toda essa jornada e processo de pensamento enquanto eu estava aprendendo.Isso pode ajudar a fornecer uma visão guiada deste processo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top