java - hasrole - spring security role access
Diferencia entre rol y autoridad otorgada en Spring Security (3)
Hay conceptos e implementaciones en Spring Security, como la interfaz GrantedAuthority
para que una autoridad autorice / controle un acceso.
Me gustaría que las operaciones permitidas, como createSubUsers , o deleteAccounts , que permitiría a un administrador (con el rol ROLE_ADMIN
).
Me estoy confundiendo como los tutoriales / demos que veo en línea. Intento conectar lo que leo, pero creo que tratamos a los dos indistintamente.
Veo que hasRole
consume una cadena de GrantedAuthority
? Definitivamente estoy haciendo mal al entender. ¿Qué es esto conceptualmente en Spring Security?
¿Cómo guardo el rol de un usuario, separado de las autoridades para ese rol?
También estoy mirando la interfaz org.springframework.security.core.userdetails.UserDetails
que se utiliza en el DAO referenciado por el proveedor de autenticación, que consume un User
(nota la última autoridad otorgada):
public User(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities)
¿O hay alguna otra forma de diferenciar a los otros dos? ¿O no es compatible y tenemos que hacer el nuestro?
AFAIK GrantedAuthority y los roles son los mismos en la seguridad de primavera. La cadena getAuthority () de GrantedAuthority es la función (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 exactamente el sol que estás buscando, pero espero que ayude
Editar : responda a su comentario
El rol es como un permiso en primavera-seguridad. El uso de intercept-url con hasRole proporciona un control muy detallado de la operación permitida para cada rol / permiso.
La forma en que manejamos en nuestra aplicación es, definimos permiso (es decir, rol) para cada operación (o url de reposo) 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 solo agrupaciones lógicas de permisos, independientemente de la seguridad de primavera. Cuando se agrega un nuevo usuario, se le asigna un perfil (que tiene todos los permisos permitidos). Ahora, cuando el usuario intenta realizar alguna acción, el permiso / rol para esa acción se compara con las autorizaciones concedidas por el usuario.
Además, el RoleVoter predeterminado usa el prefijo ROLE_, por lo que cualquier autoridad que comience con ROLE_ se considera rol, puede cambiar este comportamiento predeterminado utilizando un RolePrefix personalizado en el votante de función y usándolo en seguridad de primavera.
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 se dirigen a una acción específica, a veces junto con un alcance o contexto de datos específico. Por ejemplo, Leer, Escribir, Administrar, puede representar varios niveles de permisos para un determinado ámbito de información.
Además, las autoridades se imponen en lo más profundo del flujo de procesamiento de una solicitud, mientras que ROLE se filtra a petición del filtro 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 de negocios.
Por otro lado, los ROLES son representaciones de grano grueso de un conjunto de permisos. Un ROLE_READER solo tendría autoridad de lectura o vista, mientras que un ROLE_EDITOR tendrá tanto lectura como escritura. Los roles se utilizan principalmente para una primera proyección en las afueras del procesamiento de solicitudes, como http. ... .antMatcher (...). hasRole (ROLE_MANAGER)
Las Autoridades que se aplican de manera profunda en el 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 primer nivel de un recurso, pero solo lee para 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
Piense en una Autoridad otorgada como un "permiso" o un "derecho". Esos "permisos" son (normalmente) expresados como cadenas (con el método getAuthority()
). Esas cadenas le permiten identificar los permisos y dejar que sus votantes decidan si otorgan acceso a algo.
Puede otorgar diferentes Autorizaciones otorgadas (permisos) a los usuarios al ponerlos en el contexto de seguridad. Normalmente lo hace implementando su propio servicio UserDetails que devuelve una implementación de UserDetails que devuelve las GrantedAuthorities necesarias.
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 otorgada que comienza con el prefijo ROLE_
. No hay nada más Un rol es solo una Autorización otorgada, un "permiso", un "derecho". Verá muchos lugares en la seguridad de primavera, donde el rol con su prefijo ROLE_
se maneja especialmente, por ejemplo, en RoleVoter, donde el prefijo ROLE_
se usa de manera predeterminada. Esto le permite proporcionar los nombres de roles sin el prefijo ROLE_
. Antes de la seguridad Spring 4, este manejo especial de "roles" no se ha seguido de manera muy consistente y las autoridades y roles a menudo se trataron igual (como se puede ver en la implementación del método hasAuthority()
en SecurityExpressionRoot , que simplemente llama a hasRole()
). Con Spring Security 4, el tratamiento de los roles es más consistente y el código que trata con "roles" (como RoleVoter
, la expresión hasRole
, etc.) siempre agrega el prefijo ROLE_
por usted. Así que hasAuthority(''ROLE_ADMIN'')
significa lo mismo que hasRole(''ADMIN'')
porque el prefijo ROLE_
se agrega automáticamente. Consulte la guía de migración de seguridad de primavera 3 a 4 para obtener más información.
Pero aún así: un rol es solo una autoridad con un prefijo ROLE_
especial. Por lo tanto, 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'')")
.
En cuanto a tu caso de uso:
Los usuarios tienen roles y roles que pueden realizar ciertas operaciones.
Podría terminar en GrantedAuthorities
para los roles a los que pertenece un usuario y las operaciones que un rol puede realizar. Las GrantedAuthorities
para 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_JOB
, etc. Las funciones pueden ser ROLE_ADMIN, ROLE_USER, etc.
Podría terminar haciendo que sus entidades implementen GrantedAuthority
como en este ejemplo (pseudocódigo):
@Entity
class Role implements GrantedAuthority {
@Id
private String id;
@OneToMany
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;
@OneToMany
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 cree en su base de datos serían la representación de GrantedAuthority, por ejemplo, "ROLE_ADMIN", "OP_DELETE_ACCOUNT", etc. Cuando un usuario es autenticado, asegúrese de que todas las Autoridades otorgadas de todos sus roles y las operaciones correspondientes sean devueltas el método UserDetails.getAuthorities ().
Ejemplo: El rol de administrador con ID ROLE_ADMIN tiene asignadas las operaciones OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB. La función 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á las Autoridades otorgadas: ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB
Si un usuario lo registra, tendrá: ROLE_USER, OP_READ_ACCOUNT
El UserDetailsService se encargaría de recopilar todos los roles y todas las operaciones de esos roles y ponerlos a disposición mediante el método getAuthorities () en la instancia de UserDetails devuelta.