web-dev-qa-db-fra.com

Utilisation d'étendues en tant que rôles dans Spring Security OAuth2 (fournisseur)

Considérons une application hypothétique assez simple où les utilisateurs peuvent lire ou écrire des messages.

Certains utilisateurs peuvent lire et écrire des articles alors que d'autres ne peuvent que les lire. Avec Spring Security (3.2.1), j'ai modélisé cela en ayant 2 rôles:

  • ROLE_WRITE: ce rôle accorde aux utilisateurs l'accès à l'écriture de messages.
  • ROLE_READ: ce rôle permet aux utilisateurs d'accéder aux messages de lecture.

La mise en œuvre de cette sécurité avec Spring est assez simple ...

Maintenant, je souhaite également autoriser les applications tierces à lire et à écrire des publications au nom des utilisateurs en implémentant un fournisseur OAuth2 à l'aide de Spring Security OAuth (version 2.0.0.M3 ATM) .

Au cours de l'étape d'autorisation, l'application demande à l'utilisateur s'il est disposé à accorder le droit de lire et/ou d'écrire des publications en son nom. L'utilisateur accorde ici des étendues (pas des rôles).

Ensuite, lorsque le consommateur OAuth2 appelle mon API REST, Spring Sec OAuth autorise le jeton accordé et crée une authentification contenant l'utilisateur avec tous ses rôles et uniquement les étendues accordées.

Le problème (et la question) est que je dois maintenant écrire une logique de sécurité différente selon que l'API est appelée par un utilisateur normalement authentifié (il suffit de vérifier les rôles) ou qu'elle soit appelée via OAuth2 (contrôle des rôles + étendues).

Est-il possible de "fusionner" les concepts de rôles et d'étendues dans Spring Security OAuth2 afin que, lors de l'étape d'autorisation, l'utilisateur accorde à l'application un sous-ensemble de roles dont il dispose (et que l'authentification OAuth2 ne les signale que les autorités accordées)? Ainsi, lorsque l’application tierce passe un appel API, les rôles de l’authentification sont-ils attribués? De cette façon, je n'ai pas à écrire de logique de sécurité spécifique à OAuth2.

18
Christophe L

Les portées (et les rôles) sont des chaînes arbitraires, il n'y a donc aucun problème si vous voulez créer la même chose. Pour rendre les déclarations de règle d'accès identiques, vous pouvez écrire une ExpressionHandler qui teste des autorités ou des étendues avec les mêmes valeurs en fonction du type de Authentication trouvé.

Une approche différente se suggère après la lecture des commentaires: ajoutez une TokenStore ou une ResourceServerTokenServices personnalisée. Ce sont des points d’extension facilement accessibles et qui permettraient de modifier le OAuth2Authentication afin que ses autorisations accordées soient les mêmes que les étendues.

Ma préférence, toutefois, est de contrôler les portées autorisées à l'aide d'un OAuth2RequestFactory, en les limitant au moment de l'attribution du jeton à des valeurs cohérentes avec les droits de l'utilisateur.

6
Dave Syer

Vous pouvez configurer votre propre AccessTokenConverter (principalement pour JWT), extraire les revendications souhaitées du jeton d'accès JWT et générer un objet Authority. Il suffit de définir une usine de haricots qui renvoie un convertisseur AccessTokenConverter

0
sciack