Nous implémentons un service REST qui nécessite une authentification et une autorisation. En raison de la nature sans état des API REST, nous voulons utiliser JWT pour effectuer des appels authentifiés vers le API via un jeton, sans avoir besoin de frapper une base de données pour chaque appel d'API.
Après avoir évalué le JWT, nous avions quelques questions:
Détail du contexte: nous utiliserons ce flux entre une application iOS et un backend Node.js.
Pour répondre à tes questions:
1) Comment gérez-vous une situation avec un secret de jeton compromis qui est partagé entre un client et le serveur?
Ajoutez une date d'expiration à votre jeton. Assurez-vous que le jeton ne peut pas être utilisé après l'heure d'expiration. Mais cela n'empêche pas l'accès non autorisé pendant la période d'expiration du jeton.
Ainsi, pour surmonter ce problème, vous pouvez intégrer l'adresse IP du client ou d'autres informations de ce type dans le jeton. Et assurez-vous que la demande entrante avec le jeton est utilisée à partir de la même adresse IP vers laquelle elle a été émise.
2) Déconnectez-vous tous vos clients et définissez-vous un nouveau secret de jeton pour les demandes futures? (ce serait une mauvaise expérience)
Si vous voulez vous déconnecter de tous les clients qui utilisent plusieurs jetons de manière autorisée, alors non. Vous pouvez continuer à utiliser plusieurs jetons en même temps, à condition que vous ayez une période d'expiration limitée pour les jetons. Cela garantit que votre jeton est utilisé dans la fenêtre de temps prévue.
Mais, si vous voulez dire quand le jeton est volé et que vous l'avez compris. Il vaut mieux invalider tous les jetons de cet utilisateur.
Cependant, vous voudrez peut-être avoir un mécanisme qui révoquera explicitement tous les jetons dans des cas spéciaux. Cela peut être comme lorsque l'utilisateur réinitialise son mot de passe car il pense que son mot de passe peut être compromis.
) Existe-t-il un moyen de simplement déconnecter le client compromis?
Peut-être, dépend de votre capacité à identifier précisément quel jeton a été compromis. Ce qui peut entraîner la perte d'accès pour tous les clients utilisant ce jeton. Mais je ne le recommanderais pas. Mais, vous pouvez toujours écrire du code qui se ré-authentifiera dynamiquement et obtiendra un nouveau jeton d'accès lorsque l'ancien client ne pourra plus utiliser le jeton. :-)
N'ayez pas peur d'invalider un jeton si nécessaire. Si vous perdez un jeton, écrivez un script dynamique pour vous ré-authentifier. Si vous pensez que vous risquez de perdre les détails de la session lorsque vous utilisez un nouveau jeton, renvoyez le jeton expiré au serveur lors de la réauthentification. En utilisant ce jeton expiré, vous pouvez reconstruire un nouveau jeton avec les détails de session de l'ancien jeton. À condition que vous ayez intégré les détails de la session dans le jeton expiré.
Si vous souhaitez pouvoir révoquer des jetons précédemment accordés avant leur date d'expiration (un problème de sécurité valide), vous devrez inclure une recherche dans la base de données, ce qui annule l'un des principaux avantages des JWT, vous pouvez donc décider de ne pas utilisez-les en premier lieu.
Voici un article qui parle de ce cas: https://www.dinochiesa.net/?p=1388
Dans mon cas, je stocke également les jetons dans ma base de données.
Lors de l'authentification initiale, l'utilisateur envoie le mot de passe du nom d'utilisateur. Les informations d'identification sont vérifiées, puis je génère un jeton qui est également stocké dans la base de données et envoie également le jeton au client. À chaque demande du client, je vérifie si le jeton existe également pour cet utilisateur dans ma base de données.
Si le client se déconnecte et souhaite révoquer le jeton, je supprime simplement le jeton de la table des identités.
Les jetons JWT peuvent être décodés et toutes les informations peuvent être lues au format json, par exemple:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
La première partie est l'en-tête: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{
"alg": "HS256",
"typ": "JWT"
}
La deuxième partie est la charge utile: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
La dernière partie est la signature créée comme:
//In our example, the algorithm is (HS256)
signature = algorithm(hash of (header + payload), secret)
Maintenant, c'est la clé qui ne se cache que dans la signature du jeton, alors, nous arrivons à la conclusion que:
signature
validation avec clé secrète.akajas
1) Comment gérez-vous une situation avec un secret de jeton compromis qui est partagé entre un client et le serveur?
utilisez SSL/TLS (connexion sécurisée) et expirez chaque jeton en fonction de votre système de connexion. Le jeton JWT doit être utilisé comme permanent, chaque fois que l'utilisateur connecté se crée un jeton JWT.
2) Déconnectez-vous tous vos clients et définissez-vous un nouveau secret de jeton pour les demandes futures? (ce serait une mauvaise expérience)
SI votre clé secrète est compromise, vous devez créer définitivement une nouvelle clé secrète et renouveler les sessions actives en émettant une déconnexion et forcer le système à ré-authentifier tous les utilisateurs actifs.