Autorité accordée par rapport au rôle dans Spring Security

1. Vue d'ensemble

Dans cet article rapide, nous expliquerons la différence subtile mais significative entre un rôle et une autorité accordée dans Spring Security . Pour plus d'informations sur les rôles et les autorités, consultez l'article ici.

2. Autorité accordée

Dans Spring Security, nous pouvons considérer chaque Autorité Accordée comme un privilège individuel . Les exemples peuvent inclure READ_AUTHORITY , WRITE_PRIVILEGE ou même CAN_EXECUTE_AS_ROOT . La chose importante à comprendre est que le nom est arbitraire .

Lorsque vous utilisez un GrantedAuthority directement, par exemple via l'utilisation d'une expression comme hasAuthority ('READ_AUTHORITY'), nous limitons l'accès de manière fine .

Comme vous pouvez probablement le comprendre, nous pouvons également faire référence au concept d' autorité en utilisant le privilège .

3. Rôle en tant qu'autorité

De même, dans Spring Security, nous pouvons considérer chaque rôle comme une autorité GrantedAuthority à gros grain qui est représentée sous forme de chaîne et précédée de « ROLE » . Lorsque vous utilisez un rôle directement, par exemple via une expression comme hasRole («ADMIN») , nous restreignons l'accès de manière grossière.

Il est à noter que le préfixe " ROLE" par défaut est configurable, mais expliquer comment faire cela dépasse le cadre de cet article.

La principale différence entre ces deux éléments réside dans la sémantique que nous attachons à la façon dont nous utilisons la fonctionnalité. Pour le cadre, la différence est minime - et il traite essentiellement ces derniers exactement de la même manière.

4. Rôle en tant que conteneur

Maintenant que nous avons vu comment le framework utilise le concept de rôle , discutons également rapidement d'une alternative - utiliser les rôles comme conteneurs d'autorités / privilèges .

Il s'agit d'une approche de plus haut niveau des rôles - ce qui en fait un concept plus orienté vers l'entreprise que centré sur la mise en œuvre.

Le framework Spring Security ne donne aucune indication sur la façon dont nous devrions utiliser le concept, le choix est donc entièrement spécifique à l'implémentation.

5. Configuration de la sécurité Spring

Nous pouvons démontrer une exigence d'autorisation précise en limitant l'accès à / protectedbyauthority aux utilisateurs avec READ_AUTHORITY .

Nous pouvons démontrer une exigence d'autorisation grossière en limitant l'accès à / protectedbyrole aux utilisateurs avec ROLE_USER .

Configurons un tel scénario dans notre configuration de sécurité:

@Override protected void configure(HttpSecurity http) throws Exception { // ... .antMatchers("/protectedbyrole").hasRole("USER") .antMatchers("/protectedbyauthority").hasAuthority("READ_PRIVILEGE") // ... }

6. Init données simples

Maintenant que nous comprenons mieux les concepts de base, parlons de la création de certaines données de configuration au démarrage de l'application.

C'est, bien sûr, une façon très simple de faire cela, de démarrer avec certains utilisateurs de test préliminaires pendant le développement - pas la façon dont vous devriez gérer les données en production.

Nous allons écouter l'événement d'actualisation du contexte:

@Override @Transactional public void onApplicationEvent(ContextRefreshedEvent event) { MyPrivilege readPrivilege = createPrivilegeIfNotFound("READ_PRIVILEGE"); MyPrivilege writePrivilege = createPrivilegeIfNotFound("WRITE_PRIVILEGE"); }

L'implémentation réelle ici n'a pas vraiment d'importance - et dépend généralement de la solution de persistance que vous utilisez. Le point principal est - nous persistons les autorités que nous utilisons dans le code.

7. UserDetailsService

Notre implémentation de UserDetailsService est l'endroit où le mappage d'autorité a lieu . Une fois l'utilisateur authentifié, notre méthode getAuthorities () remplit et renvoie un objet UserDetails :

private Collection getAuthorities( Collection roles) { List authorities = new ArrayList(); for (Role role: roles) { authorities.add(new SimpleGrantedAuthority(role.getName())); role.getPrivileges().stream() .map(p -> new SimpleGrantedAuthority(p.getName())) .forEach(authorities::add); } return authorities; }

8. Exécution et test de l'exemple

Nous pouvons exécuter l'exemple d' application Java RolesAuthoritiesApplication , qui se trouve dans le projet GitHub.

Pour voir l'autorisation basée sur les rôles en action, nous devons:

  • Accès // localhost: 8082 / protectedbyrole
  • Authentifiez-vous en tant que [email protected] (le mot de passe est «user» )
  • Notez l'autorisation réussie
  • Accès // localhost: 8082 / protectedbyauthority
  • Notez que l'autorisation a échoué

Pour voir l'autorisation basée sur les autorités en action, nous devons nous déconnecter de l'application, puis:

  • Accès // localhost: 8082 / protectedbyauthority
  • Authentifiez-vous en tant que [email protected] / admin
  • Notez l'autorisation réussie
  • Accès // localhsot: 8082 / protectedbyrole
  • Notez que l'autorisation a échoué

9. Conclusion

Dans ce rapide didacticiel, nous avons examiné la différence subtile mais significative entre un rôle et une autorité accordée dans Spring Security.