Padrões corporativos para autenticação JWT para aplicativos baseados em REST?

9

A especificação JWT descreve apenas a carga útil e como ela é enviada, mas deixa o protocolo de autenticação aberto, o que permite a flexibilidade, mas, infelizmente, a flexibilidade pode levar a antipadrões e erros de design.

Estou procurando um padrão empresarial bem pensado e testado para autenticação JWT, que eu poderia usar ou adaptar, mas não encontrei algo completo.

O que eu estava pensando é:

  • quando nenhum cabeçalho de Autorização for atendido ou o token JWT for inválido ou expirar, envie HTTP 401
  • para autenticar, use / faça login no canal REST, envie nome de usuário e senha como objeto JSON
  • para manter o token ativo, use / mantenha o canal REST ativo, chame-o a cada N (5) minutos, receba um novo token JWT e substitua o existente após cada chamada (o token expira após M (15) minutos)

No entanto, o que me perturba é a necessidade desse canal / keepalive. Por outro lado, me obriga a impedir que a autenticação expire, mesmo se o usuário estiver ausente (a decisão, se desejarmos manter a vida ainda não foi cumprida) e, é claro, essas são chamadas extras e complicações adicionais ao protocolo. O que seria interessante, é que o servidor prolonga automaticamente o token. No ambiente baseado em sessão, isso ocorre redefinindo o registro de data e hora; no entanto, aqui, o servidor precisará enviar um novo token, talvez não a cada vez, mas assim que o token expirar em R (por exemplo, 10) minutos. Mas colocá-lo no corpo da resposta significaria modificar o protocolo de resposta JSON (portanto, a solução é invasiva e não transparente) e colocar um cabeçalho HTTP extra que o cliente pudesse processar não seria necessariamente um bom padrão. EU'

Existem padrões empresariais prontos que respondam aos meus pontos em aberto? O rascunho do meu protocolo é uma ideia confiável? Eu preferiria usar algo pronto do que projetar do zero.


fonte
11
Sim. O JWT levou muitas pessoas a implementar 'protocolos' caseiros e deixar de lado o código de estrutura comprovado. Para obter a solução certa, será importante esclarecer os requisitos. Parece que a expiração da 'sessão' é um requisito. O logout forçado é um requisito? ou seja, onde alguém do lado do servidor pode dizer, desconectar esse usuário ou um usuário pode dizer desconectar todas as minhas sessões.
Joshp

Respostas:

4

O JWT ( Introdução ao JSON Web Token ) é apenas um formato de token, autenticação é algo completamente fora do escopo para essa especificação. Na verdade, é comumente usado em sistemas de autenticação, mas você também pode usá-lo para cenários completamente diferentes, portanto, faz sentido não incluir restrições específicas de autenticação nessa especificação.

Se você estiver procurando orientação sobre autenticação, consulte a família de especificações OpenID Connect . Além disso, se seu sistema é composto por APIs HTTP e você está interessado em fornecer acesso delegado a essas APIs para o seu próprio ou para aplicativo cliente de terceiros, consulte a especificação OAuth 2.0 .

Existem protocolos adicionais relacionados à autenticação, como SAML e WS-Federation, que ainda são amplamente utilizados em cenários corporativos, mas são significativamente mais complexos de implementar.

Sobre seus pontos em aberto específicos:

  • O esquema de autenticação de token do portador é definido em RFC 6750, que contém instruções sobre como executar solicitações e os possíveis códigos de erro .
  • OAuth2 e OpenID Connect contemplam a possibilidade e definem a maneira de trocar um nome de usuário / senha por um token.
  • O problema de estender a vida útil do JWT ( token de valor próprio / por valor ) é resolvido no OpenID Connect e no OAuth2 por meio do tokens atualização .

Embora o OAuth2 e o OpenID Connect possam ser vistos como mais fáceis de implementar do que alguns de seus antecessores, eles ainda são complexos o suficiente para garantir alguma cautela e somente implementá-los se você estiver disposto a gastar uma quantidade considerável de tempo e recursos. Geralmente, é uma opção melhor usar bibliotecas ou serviços de terceiros que fazem esse trabalho pesado para você.

Por fim, esses protocolos abrangem muitos cenários e, portanto, podem ser um exagero em algumas situações.

João Angelo
fonte
2
+1 por justificativa e uma resposta completa à pergunta implícita, e não à escrita.
Paul Paul
3

Eu não acho que você precise de um canal de keepalive. Sua carga útil pode (e é recomendável) conter informações de expiração fornecidas pelo servidor (na expchave, de acordo com o padrão ) quando o token é gerado no login. Se um token expirado for usado (que, obviamente, é determinado pelo servidor, que só confia no conteúdo do token se a assinatura for validada), o servidor simplesmente o rejeita com HTTP 401, solicitando que o cliente se autentique novamente.

Enquanto isso, os clientes podem ser proativos. A seção de carga útil não é criptografada e, como o cliente pode lê-lo, pode verificar quando uma solicitação será enviada com um token expirado e, portanto, chamar/login novamente se o token expirar.

Como alternativa, o REST permite que as informações da hipermídia sejam enviadas como 'um mecanismo de estado'; portanto, se você quiser, pode realmente fazer apenas o uso único do seu JWT e com uma expiração. Cada solicitação, então, geraria um novo JWT que é retornado na resposta ao cliente, no conteúdo ou mais provavelmente em um cabeçalho de resposta, como acontece no hapi-auth-jwt2 .

Paulo
fonte