No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aplicar authorities a los usuarios

15/23
Recursos

¿Cómo gestionar permisos en Spring para que los usuarios realicen ciertas acciones?

La gestión de permisos en una aplicación es fundamental para garantizar la seguridad y correcta operación de los servicios, especialmente en aplicaciones web donde diferentes usuarios pueden requerir distintos niveles de acceso. En el contexto de aplicaciones Spring, el uso de Authorities y Roles es clave para la implementación de esta funcionalidad. Exploremos cómo se utiliza Spring Security para definir permisos específicos que permiten a los usuarios ejecutar determinado tipo de acciones de acuerdo a su rol.

¿Cuál es la diferencia entre Authorities y Roles?

En Spring Security, las Authorities y Roles aunque a primera vista podrían parecer similares, poseen diferencias cruciales:

  • Roles: Son grupos de permisos que un usuario puede tener. Un rol puede agrupar varios permisos, facilitando la gestión de permisos de usuarios que realizan funciones similares.
  • Authorities: Son permisos específicos que un usuario puede tener para ejecutar acciones concretas dentro de la aplicación. A diferencia de los roles, son más granulares y permiten asignar permisos muy específicos.

Spring asigna automáticamente el prefijo "ROLE" para diferenciar un rol de una autoridad.

¿Cómo implementar Roles y Authorities en Spring?

La implementación de roles y autoridades se realiza mediante el uso de clases de seguridad que artículen la creación y asignación de estos permisos. El proceso es el siguiente:

  1. Creación de una Lista de Authorities: Se crea un método privado que retorna una lista de GrantedAuthority. Este método recibirá roles que tiene el usuario previamente.

    private List<GrantedAuthority> grantedAuthorities(String[] roles) {
        List<GrantedAuthority> authorities = new ArrayList<>(roles.length);
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role));
        }
        return authorities;
    }
    
  2. Asignación de Permisos Individuales: Además de roles, se pueden asignar permisos individuales a través de un método que retorne un arreglo de strings con los permisos específicos.

    private String[] getAuthorities(String role) {
        if ("admin".equals(role) || "customer".equals(role)) {
            return new String[]{"randomOrder"};
        }
        return new String[]{};
    }
    
  3. Configuración de Seguridad: Se deben definir las reglas de seguridad indicando qué roles o autoridades son necesarias para acceder a ciertas rutas.

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/api/orders/random").hasAuthority("randomOrder")
            .antMatchers("/api/orders/**").hasRole("admin")
            .anyRequest().authenticated();
    }
    

¿Por qué es crucial el orden de las reglas de seguridad?

Es vital tener en cuenta el orden en que se evalúan las reglas de seguridad, ya que se ejecutan de forma escalonada. Si una regla general en la lista impide el acceso a un recurso basado en el rol, ninguna otra regla específica de permiso será evaluada después:

  • La regla que permita permisos específicos debe estar posicionada antes de reglas más generales. Por ejemplo, permitir a un authority específico acceder a un endpoint antes de denegar acceso a roles que no cumplan otros criterios.

¿Qué sucede si se comete un error en el orden?

Al ejecutarse las reglas de seguridad de arriba hacia abajo, un error en el orden puede impedir que un usuario, que debiera tener acceso a una función específica, lo tenga.

Intentar realizar una acción con un usuario con un rol incorrecto resultará en un error del tipo 403 Forbidden, indicando que las credenciales no son suficientes para completar la acción.

Al aplicar estos conceptos, puedes crear usuarios con permisos adaptados a sus necesidades específicas. Usar roles para permiso generales y authorities para quienes necesitan funcionalidades más expresas es una manera eficaz de mejorar la seguridad en tus aplicaciones Spring.

Aportes 8

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Se entiende como un rol un conjunto de authorities. Es decir, un autority es un permiso puntual mientras un rol un conjunto de permisos.
Un rol puede tener estos permisos de manera conceptual, sin tener que especificar cada authority en el código.

Rol: Acceso a un Modulo(s)
Authorities: Permiso puntual sobre el modulo.

i.e;

El rol Admin tiene acceso al modulo alta de usuarios,
y con los authorities puede crear editar, borrar usuarios.

Un Rol Supervisor, tiene acceso al modulo alta de usuarios, pero con los authorities puede editar solamente usuarios.

Nuevo usuario chef que no esta dentro de la condición para tener el authority “random_order”:

Para aplicar authorities a los usuarios en Spring Security, debes diferenciar entre roles y authorities. Los roles son conjuntos de permisos, mientras que las authorities representan permisos individuales. Primero, crea un método que asigne authorities a los usuarios utilizando `GrantedAuthority`. Esto implica transformar tus roles en una lista de `SimpleGrantedAuthority`. Por ejemplo, puedes usar `hasAuthority("randomOrder")` en tu configuración de seguridad para permitir accesos específicos a usuarios. Es esencial establecer el orden correcto de las reglas en tu configuración de seguridad para evitar bloqueos innecesarios.
UserSecurityService ```java ``` SecurityConfig ```java package com.platzi.pizzeria.web.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .cors(Customizer.withDefaults()) .authorizeHttpRequests((authorize) -> authorize .requestMatchers(HttpMethod.GET, "/api/pizzas/**").hasAnyRole("ADMIN", "CUSTOMER") .requestMatchers(HttpMethod.POST, "/api/pizzas/**").hasRole("ADMIN") .requestMatchers(HttpMethod.PUT).hasRole("ADMIN") .requestMatchers("/api/orders/random").hasAuthority("random_order") .requestMatchers("/api/orders/**").hasRole("ADMIN") .anyRequest() .authenticated() ) .httpBasic(Customizer.withDefaults()) ; return http.build(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ```

Lo que entendi sobre los roles y authorities, ejemplo:
Rol: “ADMIN” (agrupa varias authorities)
Authority: "CREATE_USER"
Authority: "DELETE_USER"
Authority: “RANDOM_ORDER”

Estoy tratando de ejectutar **/api/orders/random** pero no he podido por que me manda un error, creo que en el sql no viene incluido la rutina para la creacionde StoreProcedure **take\_random\_pizza\_order**![](https://static.platzi.com/media/user_upload/image-47e2ab3b-2612-4aaa-b6c1-826057367c52.jpg)