web-dev-qa-db-fra.com

Comment puis-je révoquer un jeton JWT?

J'utilise Spring oauth2 et le jeton JWT. Quelqu'un peut-il m'aider s'il vous plaît, comment puis-je révoquer un jeton JWT?

Comme mentionné ici http://projects.spring.io/spring-security-oauth/docs/oauth2.html , la révocation est effectuée par jeton d'actualisation. Mais cela ne semble pas fonctionner. 

40
sabu

En général, la la réponse la plus simple serait de dire que vous ne pouvez pas révoquer un jeton JWT, mais que ce n'est tout simplement pas vrai}. La réponse honnête est que le coût du support de la révocation de JWT est suffisamment élevé pour ne pas valoir la plupart du temps ou tout simplement repenser une alternative à JWT.

Cela dit, dans certains scénarios, vous aurez peut-être besoin à la fois de JWT et de la révocation immédiate des jetons. Voyons donc ce qu'il faudrait, mais abordons d'abord certains concepts.

JWT ( Apprendre les jetons Web JSON ) spécifie simplement un format de jeton. Ce problème de révocation s’appliquerait également à tout format utilisé dans ce que l’on appelle habituellement un jeton autonome ou à valeur. J'aime cette dernière terminologie, car elle contraste bien avec les jetons de référence.

par jeton de valeur - les informations associées, y compris la durée de vie du jeton, sont contenues dans le jeton lui-même et les informations peuvent être vérifiées comme provenant d'une source fiable (signatures numériques au secours)

jeton de référence - les informations associées sont conservées sur la mémoire côté serveur, puis obtenues en utilisant la valeur du jeton comme clé; en tant que stockage côté serveur, les informations associées sont implicitement protégées

Avant le Big Bang JWT, nous avions déjà traité les jetons dans nos systèmes d’authentification; il était courant pour une application de créer un identifiant de session lors de la connexion de l'utilisateur, qui serait ensuite utilisée de sorte que l'utilisateur ne soit pas obligé de répéter le processus de connexion à chaque fois. Ces identifiants de session ont été utilisés comme index de clé pour le stockage côté serveur et si cela ressemble à quelque chose que vous avez lu récemment, vous avez raison, cela est en fait classé comme un jeton de référence.

En utilisant la même analogie, la compréhension de la révocation pour les jetons de référence est triviale; nous supprimons simplement le stockage côté serveur mappé sur cette clé et la prochaine fois que la clé sera fournie, elle sera invalide.

Pour les jetons de valeur secondaire, nous devons simplement implémenter le contraire. Lorsque vous demandez la révocation du jeton, vous stockez quelque chose qui vous permet d'identifier ce jeton de manière unique, de sorte que vous puissiez également vérifier s'il a été révoqué lors de sa prochaine réception. Si vous pensez déjà que quelque chose comme ce ne sera pas évolutif, gardez à l'esprit qu'il vous suffit de stocker les données jusqu'à l'expiration du jeton. Dans la plupart des cas, vous pouvez probablement simplement stocker un hachage du jeton pour qu'il soit toujours actif. être quelque chose d'une taille connue.

En guise de dernière remarque et pour en revenir à OAuth 2.0, la révocation des jetons d'accès par valeur n'est actuellement pas normalisée. Néanmoins, la révocation de jeton OAuth 2.0 indique spécifiquement que cela peut toujours être réalisé tant que le serveur d'autorisation et le serveur de ressources conviennent d'un moyen personnalisé de gérer ceci:

Dans le premier cas (jetons autonomes), certaines interactions dorsales (actuellement non normalisées) entre le serveur d'autorisation et le serveur de ressources peuvent être utilisées lorsqu'une révocation de jeton d'accès immédiat est souhaitée.

Si vous contrôlez à la fois le serveur d'autorisation et le serveur de ressources, cela est très facile à réaliser. D'autre part, si vous déléguez le rôle de serveur d'autorisations à un fournisseur de cloud, tel que Auth0, ou à un composant tiers, tel que Spring OAuth 2.0, vous devrez probablement adopter une approche différente, car vous n'obtiendrez que ce qui est déjà normalisé.

_ {Une référence intéressante} _

Cet article explique une autre façon de procéder: La liste noire JWT Elle contient des pratiques et des motifs intéressants suivis de RFC7523

50
João Angelo

Voici la solution appelée JWT old pour le nouveau schéma d’échange.

Comme nous ne pouvons pas invalider le jeton émis avant le délai d’expiration, nous utilisons toujours des jetons à court terme, tels que 30 minutes . Lorsque le jeton a expiré, nous utilisons l’ancien jeton pour échanger un nouveau jeton. Le point critique est qu'un ancien jeton peut échanger un nouveau jeton uniquement.

Dans le centre serveur d'authentification, nous maintenons une table comme celle-ci:

table auth_tokens(
    user_id,
    jwt_hash,
    expire
)

id_utilisateur contenu dans la chaîne JWT . jwt_hash est une valeur de hachage de la chaîne JWT entière. Par exemple, le champ SHA256 . expire est facultatif.

Le flux de travail est le suivant:

  1. L'utilisateur demande l'API de connexion avec le nom d'utilisateur et le mot de passe, le serveur d'authentification émet un jeton et enregistre le jeton (ajoute une ligne dans la table.)
  2. Lorsque le jeton a expiré, l'utilisateur demande à l'API de l'échange avec l'ancien jeton. Tout d’abord, le serveur d’authentification valide l’ancien jeton comme étant normal, à l’exception de la vérification de l’expiration, puis crée la valeur de hachage du jeton, puis examine le tableau ci-dessus à l’aide de l’ID utilisateur:
    • Si trouvé, et que user_id et jwt_hash correspondent, émettez un nouveau jeton et mettez à jour la table.
    • Si trouvé, mais que id_utilisateur et jwt_hash ne correspondent pas, cela signifie que quelqu'un a déjà utilisé le jeton échangé avec le nouveau. Le jeton doit être piraté, supprimer des enregistrements par user_id et répondre avec des informations d'alerte.
    • si aucun enregistrement n’est trouvé, l’utilisateur doit se reconnecter ou ne saisir que le mot de passe.
  3. lorsque l’utilisation change le mot de passe ou que vous vous déconnectez, supprimez l’enregistrement par ID utilisateur.

Pour utiliser le jeton de manière continue, l'utilisateur légal et le pirate doivent échanger un nouveau jeton de manière continue, mais un seul peut réussir. En cas d'échec, les deux doivent se reconnecter au prochain échange.

Ainsi, si un pirate reçoit le jeton, celui-ci peut être utilisé pendant une courte période, mais ne peut pas en échanger un nouveau si un utilisateur légal en échange un nouveau, car la période de validité du jeton est courte. C'est plus sécurisé de cette façon.

S'il n'y a pas de pirate informatique, l'utilisateur normal doit également échanger périodiquement un nouveau jeton, par exemple toutes les 30 minutes. Cela revient à se connecter automatiquement. La charge supplémentaire n’est pas élevée et nous pouvons régler le délai d’expiration pour notre application.

source: http://www.jianshu.com/p/b11accc40ba7

13
Huanghq

Cela ne répond pas exactement à votre question concernant le cadre Spring, mais voici un article expliquant pourquoi, si vous avez besoin de la capacité de révoquer JWT, vous ne voudrez peut-être pas utiliser JWT en premier lieu, mais utiliser régulièrement Jetons porteurs opaques.

https://www.dinochiesa.net/?p=1388

9
Ian Storm Taylor

Un moyen de révoquer un fichier JWT consiste à exploiter un système d'événements distribués qui avise les services lorsque les jetons d'actualisation ont été révoqués. Le fournisseur d'identité diffuse un événement lorsqu'un jeton d'actualisation est révoqué et que d'autres serveurs/services l'écoutent. Lorsqu'un événement est reçu, les services/systèmes mettent à jour un cache local qui gère un ensemble d'utilisateurs dont les jetons d'actualisation ont été révoqués. 

Ce cache est ensuite vérifié chaque fois qu'un JWT est vérifié pour déterminer si le JWT doit être révoqué ou non. Tout est basé sur la durée des JWT et l’expiration des JWT individuels.

Cet article, Révocation de JWTs , illustre ce concept et propose un exemple d’application sur Github. 

6
kstra

Voici les étapes à suivre pour révoquer votre jeton d'accès JWT :

  1. Lorsque vous vous connectez, envoyez 2 jetons (jeton d'accès, jeton d'actualisation) dans Réponse au client.
  2. Le jeton d'accès aura moins de temps d'expiration et Refresh aura un délai d'expiration long.
  3. Le client (frontal) stockera le jeton d'actualisation dans son stockage local et jeton d'accès dans les cookies.
  4. Le client utilisera un jeton d'accès pour appeler des apis. Mais quand il expire, choisissez le jeton d'actualisation à partir du stockage local et appelez auth Server api pour obtenir le nouveau jeton.
  5. Votre serveur d'authentification disposera d'une API qui acceptera le jeton Refresh, en vérifiera la validité et renverra un nouveau jeton d'accès
  6. Une fois le jeton d'actualisation expiré, l'utilisateur sera déconnecté.

S'il vous plaît laissez-moi savoir si vous avez besoin de plus de détails, je peux partager le code aussi.

0
Bhupinder Singh