J'implémente un service REST qui nécessite une authentification. Je ne peux pas stocker d'état par utilisateur (tel qu'un jeton généré de manière aléatoire) car mon service n'a pas d'accès direct à une base de données, uniquement à un autre service backend.
La solution que j'ai trouvée consiste à créer un jeton Web JSON ( JWT ) lorsque l'utilisateur s'authentifie. L'ensemble de revendications JWT contient l'ID utilisateur dans le champ Objet ("sous"). Le serveur crypte ensuite le jeu de revendications directement ("alg": "dir") en utilisant AES GCM avec une clé de 256 bits ("enc": "A256GCM") créant un JWE . La clé est générée une fois au démarrage du service et stockée en mémoire.
Pour s'authentifier, le client soumet le nom d'utilisateur/mot de passe et le serveur répond avec le jeton décrit ci-dessus. Le client envoie ensuite ce jeton à chaque demande ultérieure.
Lorsque le client soumet le jeton avec les demandes suivantes, le serveur le déchiffre à l'aide de la clé et suppose que l'ID utilisateur dans le champ "sub" est l'ID de l'utilisateur actuel, sans plus vérifications d'authentification. L'expiration du jeton est gérée par le champ "exp" dans le jeu de revendications JWT.
La connexion entre le client et le serveur utilisera SSL/TLS, donc le jeton ne fuira pas.
J'utilise cette bibliothèque pour créer et lire des JWT car je ne me fais pas confiance pour écrire le bon code de cryptographie.
Mes questions:
Votre approche de base est valide: générez le JWT lorsque l'utilisateur se connecte, attendez-vous à ce que les messages suivants portent le JWT, faites confiance au champ sujet du JWT dans ces messages suivants si le JWT est valide. Mais vous devez être conscient de plusieurs choses:
Puisque vous avez dit que votre serveur n'avait pas accès à une base de données, je suppose que la connexion réelle est gérée ailleurs, peut-être le serveur principal que vous avez mentionné. Vous n'avez pas dit comment votre serveur sait que l'utilisateur vient de se connecter. Selon la perception qu'ont les utilisateurs de la relation entre votre service et la chose à laquelle ils savent qu'ils se sont connectés, les deux derniers points ci-dessus peuvent être sans objet.
Si aucune des données n'est sensible, il vous suffit de préserver l'intégrité des données. La signature (JWS) du jeton devrait être suffisante pour cela.
Si vous faites juste une signature, vous devriez être bien avec HMAC SHA-256. N'oubliez pas de définir une expiration du jeton et de vérifier si l'utilisateur s'est déconnecté manuellement (dans ce cas, invalidez le jeton). Une fois que vous prenez en compte l'expiration et la déconnexion, il n'y a pas grand-chose à craindre (en termes d'algorithme). Les chances que quelqu'un craque un SHA-256 au cours d'une seule session (devraient) être relativement faibles (en supposant que vous ayez besoin d'une nouvelle authentification à un intervalle RAISONNABLE).
Comme toujours avec la signature, assurez-vous de fournir le contenu à signer (nom d'utilisateur, type de compte, etc.) ne laissez jamais aucune des données définies par l'utilisateur être signée ou vous pourriez être dans une situation dangereuse.
Avertissement: Ce message est strictement mon avis. Je ne fais aucune réclamation sur la fiabilité ou l'adéquation de mes réponses. Vous devriez toujours consulter un professionnel de la sécurité pour discuter de vos problèmes spécifiques de mise en œuvre de la sécurité. C'est purement éducatif.