Saltar al contenido

Diferencia entre Role y GrantedAuthority en Spring Security

Solución:

Piense en una autoridad concedida como un “permiso” o un “derecho”. Esos “permisos” se expresan (normalmente) como cadenas (con la getAuthority() método). Esas cadenas le permiten identificar los permisos y permitir que sus votantes decidan si otorgan acceso a algo.

Puede otorgar diferentes GrantedAuthoritys (permisos) a los usuarios colocándolos en el contexto de seguridad. Normalmente lo hace implementando su propio UserDetailsService que devuelve una implementación de UserDetails que devuelve los GrantedAuthorities necesarios.

Los roles (como se usan en muchos ejemplos) son solo “permisos” con una convención de nomenclatura que dice que un rol es una autoridad concedida que comienza con el prefijo ROLE_. No hay nada mas. Un rol es solo una autoridad concedida, un “permiso”, un “derecho”. Ves muchos lugares en la seguridad de primavera donde el rol con su ROLE_ El prefijo se maneja especialmente como, por ejemplo, en el RoleVoter, donde el ROLE_ El prefijo se utiliza de forma predeterminada. Esto le permite proporcionar los nombres de los roles sin ROLE_ prefijo. Antes de Spring Security 4, este manejo especial de “roles” no se seguía de manera muy consistente y las autoridades y roles a menudo se trataban de la misma manera (como puede ver, por ejemplo, en la implementación del hasAuthority() en SecurityExpressionRoot, que simplemente llama hasRole()). Con Spring Security 4, el tratamiento de los roles es más consistente y el código que se ocupa de los “roles” (como el RoleVoter, los hasRole expresión, etc.) siempre agrega el ROLE_ prefijo para ti. Entonces hasAuthority('ROLE_ADMIN') significa lo mismo que hasRole('ADMIN') porque el ROLE_ El prefijo se agrega automáticamente. Consulte la guía de migración de Spring Security 3 a 4 para obtener más información.

Pero aún así: un rol es solo una autoridad con un especial ROLE_ prefijo. Entonces, en Spring Security 3 @PreAuthorize("hasRole('ROLE_XYZ')") es lo mismo que @PreAuthorize("hasAuthority('ROLE_XYZ')") y en Spring Security 4 @PreAuthorize("hasRole('XYZ')") es lo mismo que @PreAuthorize("hasAuthority('ROLE_XYZ')").

Con respecto a su caso de uso:

Los usuarios tienen roles y los roles pueden realizar ciertas operaciones.

Podrías terminar en GrantedAuthorities para los roles a los que pertenece un usuario y las operaciones que puede realizar un rol. los GrantedAuthorities porque los roles tienen el prefijo ROLE_ y las operaciones tienen el prefijo OP_. Un ejemplo para las autoridades de operación podría ser OP_DELETE_ACCOUNT, OP_CREATE_USER, OP_RUN_BATCH_JOBetc. Los roles pueden ser ROLE_ADMIN, ROLE_USER, ROLE_OWNER etc.

Podría terminar haciendo que sus entidades se implementen GrantedAuthority como en este ejemplo (pseudocódigo):

@Entity
class Role implements GrantedAuthority {
    @Id
    private String id;

    @ManyToMany
    private final List<Operation> allowedOperations = new ArrayList<>();

    @Override
    public String getAuthority() {
        return id;
    }

    public Collection<GrantedAuthority> getAllowedOperations() {
        return allowedOperations;
    }
}

@Entity
class User {
    @Id
    private String id;

    @ManyToMany
    private final List<Role> roles = new ArrayList<>();

    public Collection<Role> getRoles() {
        return roles;
    }
}

@Entity
class Operation implements GrantedAuthority {
    @Id
    private String id;

    @Override
    public String getAuthority() {
        return id;
    }
}

Los identificadores de los roles y operaciones que crea en su base de datos serían la representación de GrantedAuthority, p. Ej. ROLE_ADMIN, OP_DELETE_ACCOUNT etc. Cuando un usuario está autenticado, asegúrese de que todas las GrantedAuthorities de todos sus roles y las operaciones correspondientes se devuelvan desde el método UserDetails.getAuthorities ().

Ejemplo: el rol de administrador con id ROLE_ADMIN tiene las operaciones OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB asignado a él. El rol de usuario con id ROLE_USER tiene la operación OP_READ_ACCOUNT.

Si un administrador inicia sesión en el contexto de seguridad resultante, tendrá GrantedAuthorities:
ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB

Si un usuario lo registra, tendrá:
ROLE_USER, OP_READ_ACCOUNT

UserDetailsService se encargaría de recopilar todos los roles y todas las operaciones de esos roles y hacerlos disponibles mediante el método getAuthorities () en la instancia de UserDetails devuelta.

AFAIK GrantedAuthority y los roles son los mismos en la seguridad de primavera. La cadena getAuthority () de GrantedAuthority es el rol (según la implementación predeterminada SimpleGrantedAuthority).

Para su caso, puede usar Roles jerárquicos

<bean id="roleVoter" class="org.springframework.security.access.vote.RoleHierarchyVoter">
    <constructor-arg ref="roleHierarchy" />
</bean>
<bean id="roleHierarchy"
        class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
    <property name="hierarchy">
        <value>
            ROLE_ADMIN > ROLE_createSubUsers
            ROLE_ADMIN > ROLE_deleteAccounts 
            ROLE_USER > ROLE_viewAccounts
        </value>
    </property>
</bean>

No es el sol exacto que buscas, pero espero que te ayude

Editar: Responde a tu comentario

El rol es como un permiso en spring-security. El uso de intercept-url con hasRole proporciona un control muy detallado de qué operación está permitida para qué rol / permiso.

La forma en que manejamos nuestra aplicación es, definimos el permiso (es decir, el rol) para cada operación (o URL de descanso) para, por ejemplo, view_account, delete_account, add_account, etc. Luego creamos perfiles lógicos para cada usuario como admin, guest_user, normal_user. Los perfiles son simplemente agrupaciones lógicas de permisos, independientes de Spring-Security. Cuando se agrega un nuevo usuario, se le asigna un perfil (con todos los permisos permitidos). Ahora, cuando un usuario intenta realizar alguna acción, el permiso / rol para esa acción se compara con las Autoridades concedidas por el usuario.

Además, el RoleVoter predeterminado usa el prefijo ROLE_, por lo que cualquier autoridad que comience con ROLE_ se considera un rol, puede cambiar este comportamiento predeterminado usando un RolePrefix personalizado en el rol de votante y usándolo en Spring Security.

Otra forma de entender la relación entre estos conceptos es interpretar un ROL como un contenedor de Autoridades.

Las autoridades son permisos detallados que tienen como objetivo una acción específica junto a veces con un contexto o alcance de datos específicos. Por ejemplo, Leer, Escribir, Administrar, puede representar varios niveles de permisos para un determinado alcance de información.

Además, las autoridades se aplican en lo profundo del flujo de procesamiento de una solicitud, mientras que ROLE se filtra mediante un filtro de solicitud antes de llegar al controlador. Las mejores prácticas prescriben la implementación de la aplicación de las autoridades más allá del Controlador en la capa empresarial.

Por otro lado, los ROLES son una representación burda de un conjunto de permisos. Un ROLE_READER solo tendría autoridad de lectura o visualización, mientras que un ROLE_EDITOR tendría tanto lectura como escritura. Los roles se utilizan principalmente para una primera selección en las afueras del procesamiento de la solicitud, como http. … .antMatcher (…). hasRole (ROLE_MANAGER)

Las Autoridades que se aplican en lo profundo del flujo de proceso de la solicitud permiten una aplicación más detallada del permiso. Por ejemplo, un usuario puede tener permiso de lectura y escritura para el primer nivel de un recurso, pero solo de lectura en un sub-recurso. Tener un ROLE_READER restringiría su derecho a editar el recurso de primer nivel, ya que necesita el permiso de escritura para editar este recurso, pero un interceptor @PreAuthorize podría bloquear su intento de editar el sub-recurso.

Jake

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *