Autorité accordée à rôle dans la sécurité de printemps

Autorité accordée contre rôle dans la sécurité de printemps

1. Vue d'ensemble

Dans cet article rapide, nous expliqueronsthe subtle but significant difference between a Role and a GrantedAuthority in Spring Security. Pour plus d'informations sur les rôles et les autorités, consultez l'articlehere.

Lectures complémentaires:

Tutoriel d'authentification de sécurité Spring

Comment créer un processus d'inscription de niveau production pour les nouveaux utilisateurs et un flux de connexion pour les utilisateurs existants.

Read more

Spring Security pour une API REST

Comment sécuriser une API REST avec Spring Security - la configuration XML, le fichier web.xml, les codes d'état HTTP pour l'authentification, etc.

Read more

Authentification de base de Spring Security

Configurez l'authentification de base dans Spring - la configuration XML, les messages d'erreur et un exemple d'utilisation des URL sécurisées avec curl.

Read more

2. GrantedAuthority

Dans Spring Security, nous pouvonsthink of each GrantedAuthority as an individual privilege. Les exemples peuvent inclureREAD_AUTHORITY,WRITE_PRIVILEGE ou mêmeCAN_EXECUTE_AS_ROOT. La chose importante à comprendre est quethe name is arbitrary.

Lorsque vous utilisez unGrantedAuthority directement, par exemple en utilisant une expression commehasAuthority(‘READ_AUTHORITY'),, nous sommesrestricting access in a fine-grained manner.

Comme vous pouvez probablement le comprendre, nous pouvons faire référence au concept deauthority en utilisant égalementprivilege.

3. Rôle en tant qu'autorité

De même, dans Spring Security, nous pouvonsthink of each Role as a coarse-grained GrantedAuthority that is represented as a String and prefixed with “ROLE. Lorsque vous utilisez unRole directement, par exemple via une expression commehasRole(“ADMIN”), nous limitons l'accès de manière grossière.

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

The core difference between these two is the semantics we attach to how we use the feature. Pour le framework, la différence est minime - et il les traite essentiellement exactement de la même manière.

4. Rôle en tant que conteneur

Maintenant que nous avons vu comment le framework utilise le conceptrole, discutons aussi rapidement d'une alternative - et c'estusing roles as containers of authorities/privileges.

Il s’agit d’une approche de haut niveau des rôles, qui en fait un concept davantage axé sur les entreprises plutôt que 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 à la mise en œuvre.

5. Configuration de sécurité de printemps

Nous pouvons démontrer une exigence d'autorisation fine en restreignant l'accès à/protectedbyauthority aux utilisateurs avecREAD_AUTHORITY.

Nous pouvons démontrer une exigence d'autorisation grossière en restreignant l'accès à/protectedbyrole aux utilisateurs avecROLE_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.

Il s’agit bien entendu d’une manière très simple de procéder, en cours de développement, avec quelques utilisateurs testant préalablement, et non de la manière 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");
}

La mise en œuvre réelle n’a pas vraiment d’importance et dépend généralement de la solution de persistance que vous utilisez. Le point principal est que nous persistons dans les autorités que nous utilisons dans le code.

7. UserDetailsService

Notre implémentation deUserDetailsService is where the authority mapping takes place. Une fois que l'utilisateur s'est authentifié, notre méthodegetAuthorities() remplit et renvoie un objetUserDetails:

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 JavaRolesAuthoritiesApplication, trouvé dans lesGitHub project.

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

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

9. Conclusion

Dans ce tutoriel rapide, nous avons examiné la différence subtile mais significative entre unRole et unGrantedAuthority dans Spring Security.