2017-10-02 2 views
0

Je développe actuellement un service web avec Spring. Je souhaite offrir aux utilisateurs la possibilité de se connecter via des services OAuth externes, par ex. google, github, ... ainsi qu'un nom d'utilisateur/mot de passe traditionnel. POJO sage, j'ai la configuration suivante:Spring OAuth2 + JWT, comment mapper un jeton d'accès externe à un utilisateur local

  • Chaque User a une relation un-à-plusieurs à AuthenticationMethod s
  • Chaque AuthenticationMethod a exactement un AuthenticationProvider (par exemple google, github, local) et stocke le sub de cette méthode d'authentification et le User correspondant. Dans le cas d'une authentification locale, il s'agit de l'identifiant de l'utilisateur.
  • Chaque AuthenticationMethod avec AuthenticationProvider == local stocke en outre un mot de passe.

Ce qui fonctionne déjà

authentification locale (nom d'utilisateur/mot de passe) se fait par un propre serveur d'authentification OAuth2 (partie de l'application de printemps) et retourne un JWTAccessToken, contenant le nom d'utilisateur (le frontend ne voit jamais le client_secret, ainsi une concession password est acceptable dans cette situation).

Je suis également en mesure de récupérer des jetons d'accès auprès des fournisseurs OAuth externes (google, github, ...) via le processus de subvention authorization_request contenant leur utilisateur sup dudit fournisseur.

Problème

J'ai besoin de cartographier la sub externe à un objet User. Puisque, en théorie, deux utilisateurs différents pourraient avoir le même sub chez deux fournisseurs externes différents, je devrais aussi vérifier l'émetteur, ce qui donnerait une construction if-else désagréable. De plus, cette traduction du jeton JWT vers un User doit être effectuée à chaque accès où une autorisation est requise.

Des idées pour des solutions

Ce que je voudrais faire est d'ajouter des informations à l'extérieur JWT généré. Cela n'est pas possible puisque je ne peux pas "re-signer" le JWT externe. Mon idée est d'intercepter le JWT externe et d'émettre un JWT local, contenant le nom d'utilisateur, utilisant ainsi le JWT externe uniquement pour l'authentification initiale.

Y at-il une possibilité intégrée au printemps pour accomplir ce que je veux? Ou existe-t-il une «meilleure pratique» pour résoudre ce problème?

Répondre

0

La meilleure pratique consiste à utiliser un serveur OAuth2 pour ajouter un nom d'utilisateur en tant que revendication supplémentaire à JWT. Spring a déjà un handle qui prend la revendication "user_name" de JWT et l'utilise comme objet Principal.

+0

Le problème est: Je ne peux pas changer les jetons d'accès externes, donc je ne peux pas ajouter d'autres revendications. – Turing85

+0

Je ne pense pas que le printemps a quelque chose de construit pour vous aider dans votre cas. Avez-vous vérifié le jeton JWT des serveurs OAuth2? Peut-être qu'ils ont des revendications supplémentaires que vous pourriez utiliser pour obtenir le nom d'utilisateur. – tsolakp

+0

Les jetons ne sont pas le problème. Je peux trouver un 'Utilisateur' correspondant à un jeton. Le problème est l'interception de jeton. Je ne veux pas que le frontal voit le jeton externe. – Turing85