8
votes

Sécurité du printemps OAuth2 - Obtenir des données personnalisées de l'OAuth2 Principal

J'ai un site qui utilise la sécurité de printemps et possède des utilisateurs (nom d'utilisateur et mot de passe) et authentification de formulaire standard. Je permet aux utilisateurs de générer un ID client et un secret client lié à leur compte pour une utilisation avec une API de repos sécurisé OAuth2.

J'utilise un identifiant et un secret client séparé pour l'API et non le nom d'utilisateur et le mot de passe, de sorte que l'utilisateur puisse modifier leur mot de passe, etc. sans casser les informations d'identification de l'API, définir des étendues spécifiques, désactiver l'accès à l'API, etc.

J'utilise Spring-Security-Oauth2 (fournisseur) pour sécuriser l'API de repos et j'ai permis un flux d'informations d'identification du client. J'ai la configuration de l'authentification du client pour l'API afin que l'ID client et le secret soient vérifiés.

à partir d'une application distincte, j'utilise l'ID client et le secret du client pour récupérer un jeton d'accès et commencer à l'utiliser avec l'API. Pour la plupart, j'utilise des expressions simples @peuthorize simples sur la base des rôles et de la portée des clients et ceux-ci semblent fonctionner correctement.

tout ce qui précède semble fonctionner correctement

Cependant ... J'ai maintenant quelques points de terminaison d'API, mais je dois mettre en œuvre des règles plus complexes basées sur certains détails de l'utilisateur sous-jacent - dans ce cas, l'utilisateur qui a généré l'ID client et le secret.

Comme un exemple simple envisagez une application de messagerie où j'ai un point de terminaison qui permet aux utilisateurs de poster un nouveau "message" d'un type spécifique pouvant varier. J'ai une table des destinataires autorisés pour chaque utilisateur et chaque type et je souhaite vérifier que les destinataires du message affiché correspondent au destinataire autorisé pour le type. (Les données des destinataires autorisés par l'utilisateur ne sont généralement pas importantes et changent rarement, alors je suis heureux de stocker une copie de celui-ci lors de la génération d'un jeton d'accès)

Je reçois le principal sur ces points d'extrémité et je vois que c'est une instance de Oauth2Authentication contenant:

  • UserAuthentication - NULL - Cela semble attendu pour les informations d'identification des clients.
  • La clienttauthentication est peuplée et autorisationParameters contient le type de subvention et client_id

    Je suppose que je puisse utiliser l'identifiant du client à partir de la clienttauthentication.AuthorizeParamètres pour rechercher l'utilisateur et les détails dont j'ai besoin, mais ce serait quelques requêtes chaque appel de l'API qui ne semble pas avoir de sens.

    Je devinerais qu'il y a une belle place / un chemin au printemps Oauth2 libs que tout en accordant le jeton d'accès que je pouvais ajouter des détails supplémentaires afin que, plus tard, je puissiez les obtenir de l'objet Oauth2Authentication (ou quelque chose qui le prolongeait? )

    Alternativement, y a-t-il une meilleure approche entièrement à un tel problème?

    thx!


1 commentaires

Avez-vous regardé JWT (joke JSON WEB)? C'est à peu près un jeton qui a toutes les informations utiles.


3 Réponses :


6
votes

Pourquoi vous n'utilisez pas de scopes pouvant être définis dans les détails du client, puis utilisez SCOPEVOTER pour valider que ce jeton permet d'accéder à cette ressource ou non.

Veuillez vérifier ma démonstration pour plus de détails

https://github.com/bassemzohdy/spring_rest_oauth_demo

mise à jour 1: Je n'ai pas répondu à la partie 2 de votre question "Obtenir des données personnalisées à partir de OATUH2" Vous pouvez ajouter un service de repos sur votre serveur d'autorisation qui est accessible à l'aide de la jeton OAuth pour vous donner des informations requises sur cet utilisateur de jeton. Vous n'avez donc pas besoin de Soin des "Oauth2" Principal "Vous avez affaire à un serveur d'autorisation comme serveur de ressources aussi.


3 commentaires

THX, j'utilise des étendues simples déjà mais évité cette solution, car j'étais inquiet à propos d'une quantité explosive de scopes pour atteindre les règles que je voulais. Je vais mettre à jour la question avec un exemple.


Dans une autre solution, j'utilise une portée par groupe de ressources, je pense qu'il n'y a pas de limitation de la nulle des scopes, vous pouvez également mélanger des champs avec des rôles.


Thx, ouais j'utilise déjà un tel peu. Juste pour le cas, je le mentionne, il serait probablement assez intéressant de former la flexion de l'utilisateur de l'utilisateur, puis de les traiter pour les interpréter :-) J'espérais qu'il y avait une meilleure façon.



5
votes

À mon avis, la bonne approche ici serait d'utiliser le flux de "mot de passe" OAuth2 au lieu des identifiants clients. Vous pouvez créer un code client général et un secret client et leur donner à tous vos utilisateurs. Chaque utilisateur peut demander son propre jeton en utilisant ces détails du client et son propre nom d'utilisateur et mot de passe. De cette façon, chaque jeton serait connecté à un objet userDétails qui résoudra votre problème. Vous pouvez voir comment cela fait ici: https: // lab.hybris.com/2012/06/18/trying-out-oauth2-via-curl/


3 commentaires

Thx pour l'idée, mais le point d'utilisation des informations d'identification du client était de rendre l'API généralement indépendante des utilisateurs. Ce n'est que dans quelques cas (minoritaire), j'ai des règles plus complexes. J'ai mis à jour la question pour donner un raisonnement pour les informations d'identification du client.


Le lien ici est cassé. Pourriez-vous apporter un extrait pertinent de cette réponse particulière?


Le lien est à nouveau cassé.



5
votes

Vous pouvez remplacer la classe de création de jeton afin que le jeton lui-même contiendrait le nom d'utilisateur. (Peut-être crypté à l'aide du client_secret). De cette façon, vous pouvez obtenir l'utilisateur lié à un jeton du jeton lui-même sans accès supplémentaire de base de données. Vous devriez remplacer xxx

avec votre propre classe ou utiliser tokenenhanancer


4 commentaires

Thx sonne initialement prometteur. Je vais vérifier plus et faire des tests le lendemain. Je n'ai pas encore trouvé d'article / post / échantillon, alors si vous êtes au courant d'un s'il vous plaît laissez-moi savoir :)


Bonjour, j'ai vérifié et il semble que le Tokenenhanancer est utile de "améliorer" la réponse de jeton d'accès et / ou ajoutez des informations supplémentaires. Bien que ce n'est pas ce que je veux. Il ne devrait pas y avoir besoin d'envoyer des données supplémentaires au client. Bien que je comprends votre idée d'essayer de tracer le nom d'utilisateur dans le jeton (je n'en ai souvent pas besoin), il me semble qu'il doit y avoir une meilleure façon qui laisse des jetons, etc. inchangés et se produit simplement sur le côté serveur.


Vous pouvez ajouter les informations dont vous avez besoin pour les détails de votre client lorsque vous enregistrez chaque client à l'aide de ClientDétails.addaddAddAditionalInformation que vous ne pouvez revenir à ces informations à l'aide du ClientID que vous avez. (Cela pourrait nécessiter une requête par demande qui semble être raisonnable)


Bon point. Oui, la récupération est une pitié et ce que je voulais éviter. On dirait que les points d'extension / champs ne sont tout simplement pas là. J'ai mon propre IMP. de Tokenstore, ClientDetail, ClientDétails, mais semble que je dois modifier trop de choses pour créer une chaîne complète.