Différence entre le rôle et l’autorité accordée dans la sécurité de spring

Il y a des concepts et des implémentations dans Spring Security, tels que l’interface GrantedAuthority pour obtenir une autorisation pour autoriser / contrôler un access.

Je voudrais cela aux opérations autorisées, telles que createSubUsers ou deleteAccounts , que j’autoriserais à un administrateur (avec le rôle ROLE_ADMIN ).

Je suis confus comme les tutoriels / démos que je vois en ligne. J’essaie de relier ce que je lis, mais je pense que nous traitons les deux de manière interchangeable.

Je vois hasRole consommant une chaîne GrantedAuthority ? Je le fais très certainement mal comprendre. Que sont-ils conceptuellement dans Spring Security?

Comment puis-je stocker le rôle d’un utilisateur, distinct des autorités pour ce rôle?

Je regarde également l’interface org.springframework.security.core.userdetails.UserDetails qui est utilisée dans le DAO référencé par le fournisseur d’authentification, qui consum un User (notez la dernière autorité octroyée):

 public User(Ssortingng username, Ssortingng password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection authorities) 

Ou existe-t-il un autre moyen de différencier les deux autres? Ou n’est-ce pas supporté et nous devons faire notre propre?

Pensez à une autorité reconnue comme étant une “permission” ou un “droit”. Ces “permissions” sont (normalement) exprimées sous forme de chaînes (avec la méthode getAuthority() ). Ces chaînes vous permettent d’identifier les permissions et permettent à vos électeurs de décider s’ils accordent l’access à quelque chose.

Vous pouvez accorder différentes permissions GrantedAuthority (permissions) aux utilisateurs en les plaçant dans le contexte de sécurité. Vous le faites normalement en implémentant votre propre UserDetailsService qui retourne une implémentation UserDetails qui renvoie les permissions octroyées nécessaires.

Les rôles (tels qu’ils sont utilisés dans de nombreux exemples) ne sont que des “permissions” avec une convention de dénomination indiquant qu’un rôle est une autorité octroyée qui commence par le préfixe ROLE_ . Il n’y a plus rien. Un rôle est simplement une autorisation accordée – une “permission” – un “droit”. Vous voyez beaucoup d’endroits dans la sécurité Spring où le rôle avec son préfixe ROLE_ est géré spécialement, par exemple, dans le RoleVoter, où le préfixe ROLE_ est utilisé par défaut. Cela vous permet de fournir les noms de rôle sans le préfixe ROLE_ . Avant Spring security 4, cette gestion spéciale des “rôles” n’a pas été suivie de manière très cohérente et les autorités et les rôles étaient souvent traités de la même manière (comme dans la méthode hasAuthority() de SecurityExpressionRoot , qui appelle simplement hasRole() ). Avec Spring Security 4, le traitement des rôles est plus cohérent et le code traitant des «rôles» (comme RoleVoter , l’expression hasRole , etc.) ajoute toujours le préfixe ROLE_ pour vous. Ainsi, hasAuthority('ROLE_ADMIN') signifie la même chose que hasRole('ADMIN') car le préfixe ROLE_ est ajouté automatiquement. Reportez-vous au guide de migration Spring Safety 3 pour 4 pour plus d’informations.

Mais encore: un rôle est juste une autorité avec un préfixe ROLE_ spécial. Donc, dans Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')") est identique à @PreAuthorize("hasAuthority('ROLE_XYZ')") et dans Spring security 4 @PreAuthorize("hasRole('XYZ')") est identique à @PreAuthorize("hasAuthority('ROLE_XYZ')") .

Concernant votre cas d’utilisation:

Les utilisateurs ont des rôles et des rôles pouvant effectuer certaines opérations.

Vous pourriez vous retrouver dans GrantedAuthorities pour les rôles GrantedAuthorities un utilisateur appartient et les opérations qu’un rôle peut effectuer. Les GrantedAuthorities pour les rôles ont le préfixe ROLE_ et les opérations ont le préfixe OP_ . OP_DELETE_ACCOUNT , OP_CREATE_USER , OP_RUN_BATCH_JOB etc. Les rôles peuvent être ROLE_ADMIN, ROLE_USER, etc.

Vous pourriez finir par avoir vos entités implémenter GrantedAuthority comme dans cet exemple (pseudo-code):

 @Entity class Role implements GrantedAuthority { @Id private Ssortingng id; @OneToMany private final List allowedOperations = new ArrayList<>(); @Override public String getAuthority() { return id; } public Collection getAllowedOperations() { return allowedOperations; } } @Entity class User { @Id private Ssortingng id; @OneToMany private final List roles = new ArrayList<>(); public Collection getRoles() { return roles; } } @Entity class Operation implements GrantedAuthority { @Id private Ssortingng id; @Override public Ssortingng getAuthority() { return id; } } 

Les identifiants des rôles et des opérations que vous créez dans votre firebase database seraient la représentation GrantedAuthority, par exemple “ROLE_ADMIN”, “OP_DELETE_ACCOUNT” etc. Lorsqu’un utilisateur est authentifié, assurez-vous que toutes les permissions accordées de la méthode UserDetails.getAuthorities ()

Exemple: Le rôle admin avec l’ID ROLE_ADMIN a les opérations OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB qui lui sont affectées. Le rôle d’utilisateur avec l’ID ROLE_USER a pour opération OP_READ_ACCOUNT.

Si un administrateur se connecte au contexte de sécurité résultant, les permissions octroyées sont atsortingbuées: ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB

Si un utilisateur le connecte, il aura: ROLE_USER, OP_READ_ACCOUNT

Le UserDetailsService prendrait soin de collecter tous les rôles et toutes les opérations de ces rôles et de les rendre disponibles par la méthode getAuthorities () dans l’instance UserDetails renvoyée.

AFAIK GrantedAuthority et les rôles sont les mêmes pour la spring security. La chaîne getAuthority () de GrantedAuthority est le rôle (par défaut implémentation SimpleGrantedAuthority).

Pour votre cas, vous pouvez utiliser des rôles hiérarchiques

       ROLE_ADMIN > ROLE_createSubUsers ROLE_ADMIN > ROLE_deleteAccounts ROLE_USER > ROLE_viewAccounts    

Pas le sol exact que vous recherchez, mais j’espère que cela vous aidera

Edit : Répondre à votre commentaire

Le rôle est comme une permission dans la sécurité du spring. Utiliser intercept-url avec hasRole fournit un contrôle très précis de l’opération autorisée pour quel rôle / permission.

La manière dont nous gérons notre application est la suivante: nous définissons une autorisation (par exemple, un rôle) pour view_account, delete_account, add_account, etc. Nous créons ensuite des profils logiques pour chaque utilisateur comme admin, user_user, normal_user. Les profils ne sont que des regroupements logiques d’permissions, indépendamment de la sécurité Spring. Lorsqu’un nouvel utilisateur est ajouté, un profil lui est atsortingbué (avec toutes les permissions autorisées). Désormais, chaque fois qu’un utilisateur tente d’effectuer une action, la permission / le rôle de cette action est vérifié par rapport aux permissions accordées par l’utilisateur.

De même, le RoleVoter par défaut utilise le préfixe ROLE_, donc toute autorité commençant par ROLE_ est considérée comme un rôle, vous pouvez modifier ce comportement par défaut en utilisant un RolePrefix personnalisé dans le rôle de votant et en l’utilisant dans la sécurité Spring.

Une autre façon de comprendre la relation entre ces concepts consiste à interpréter un ROLE comme un conteneur d’autorités.

Les autorités sont des permissions affinées ciblant une action spécifique associée parfois à une scope ou à un contexte de données spécifique. Par exemple, Read, Write, Manage peut représenter différents niveaux d’permissions pour un périmètre d’informations donné.

En outre, les autorités sont impliquées dans le stream de traitement d’une demande, tandis que ROLE est filtré par filtre de demande avant d’atteindre le contrôleur. Les meilleures pratiques imposent d’implémenter l’application par les autorités au-delà du contrôleur dans la couche de gestion.

D’autre part, ROLES est une représentation grossière d’un ensemble d’permissions. Un ROLE_READER aurait uniquement l’autorité Read ou View alors qu’un ROLE_EDITOR aurait à la fois la lecture et l’écriture. Les rôles sont principalement utilisés pour un premier filtrage à la périphérie du traitement des requêtes, tel que http. … .antMatcher (…). hasRole (ROLE_MANAGER)

Les Autorités appliquées profondément dans le stream de processus de la requête permettent une application plus fine de l’autorisation. Par exemple, un utilisateur peut avoir l’autorisation d’écriture en lecture pour niveler d’abord une ressource, mais seulement lire une sous-ressource. Avoir un ROLE_READER restreindrait son droit d’éditer la ressource de premier niveau car il a besoin de l’autorisation d’écriture pour modifier cette ressource, mais un intercepteur @PreAuthorize pourrait bloquer sa tentative d’éditer la sous-ressource.

Jake