Pensez à une GrantedAuthority comme étant une "autorisation" ou un "droit". Ces "autorisations" sont (normalement) exprimées sous forme de chaînes de caractères (avec la méthode getAuthority()
). Ces chaînes vous permettent d'identifier les autorisations et de laisser vos voteurs décider s'ils accordent l'accès à quelque chose.
Vous pouvez accorder différentes GrantedAuthoritys (autorisations) aux utilisateurs en les plaçant dans le contexte de sécurité. Vous le faites normalement en implémentant votre propre UserDetailsService qui renvoie une implémentation de UserDetails qui renvoie les GrantedAuthorities nécessaires.
Les rôles (comme ils sont utilisés dans de nombreux exemples) ne sont rien de plus que des "autorisations" suivant une convention de nommage selon laquelle un rôle est une GrantedAuthority commençant par le préfixe ROLE_
. Rien de plus. Un rôle est juste une GrantedAuthority - une "autorisation" - un "droit". Vous pouvez voir à de nombreux endroits de Spring Security où le rôle avec son préfixe ROLE_
est traité spécialement comme par exemple dans le RoleVoter, où le préfixe ROLE_
est utilisé par défaut. Cela vous permet de fournir les noms de rôles sans le préfixe ROLE_
. Avant Spring Security 4, ce traitement spécial des "rôles" n'était pas suivi 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 vous pouvez le voir dans l'implémentation de la méthode hasAuthority()
dans SecurityExpressionRoot - qui appelle simplement hasRole()
). Avec Spring Security 4, le traitement des rôles est plus cohérent et le code qui traite des "rôles" (comme le 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. Consultez le guide de migration de Spring Security 3 à 4 pour plus d'informations.
Cependant : un rôle n'est qu'une autorité avec un préfixe spécial ROLE_
. Donc dans Spring Security 3, @PreAuthorize("hasRole('ROLE_XYZ')")
est la même chose que @PreAuthorize("hasAuthority('ROLE_XYZ')")
et dans Spring Security 4, @PreAuthorize("hasRole('XYZ')")
est la même chose que @PreAuthorize("hasAuthority('ROLE_XYZ')")
.
Concernant votre cas d'utilisation :
Les utilisateurs ont des rôles et les rôles peuvent effectuer certaines opérations.
Vous pourriez obtenir des GrantedAuthorities
pour les rôles auxquels 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_
. Un exemple d'autorités d'opération pourrait être OP_DELETE_ACCOUNT
, OP_CREATE_USER
, OP_RUN_BATCH_JOB
, etc. Les rôles peuvent être ROLE_ADMIN
, ROLE_USER
, ROLE_OWNER
, etc.
Vos entités pourraient implémenter GrantedAuthority
comme dans cet exemple (pseudo-code) :
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@ManyToMany
private final List allowedOperations = new ArrayList<>();
@Override
public String getAuthority() {
return id;
}
public Collection getAllowedOperations() {
return allowedOperations;
}
}
@Entity
class User {
@Id
private String id;
@ManyToMany
private final List roles = new ArrayList<>();
public Collection getRoles() {
return roles;
}
}
@Entity
class Operation implements GrantedAuthority {
@Id
private String id;
@Override
public String getAuthority() {
return id;
}
}
Les IDs des rôles et opérations que vous créez dans votre base de données seraient la représentation GrantedAuthority, par exemple ROLE_ADMIN
, OP_DELETE_ACCOUNT
, etc. Lorsqu'un utilisateur est authentifié, assurez-vous que toutes les GrantedAuthorities de tous ses rôles et des opérations correspondantes sont renvoyées par la méthode UserDetails.getAuthorities().
Exemple : Le rôle administrateur avec l'ID ROLE_ADMIN
a les opérations OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
qui lui sont assignées. Le rôle utilisateur avec l'ID ROLE_USER
a l'opération OP_READ_ACCOUNT
.
Si un administrateur se connecte, le contexte de sécurité obtenu aura les GrantedAuthorities : ROLE_ADMIN
, OP_DELETE_ACCOUNT
, OP_READ_ACCOUNT
, OP_RUN_BATCH_JOB
Si un utilisateur se connecte, il aura : ROLE_USER
, OP_READ_ACCOUNT
Le UserDetailsService se chargerait 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 retournée.