java - hasrole - Spring Security con roles y permisos
spring security roles (4)
Esta es la forma más simple de hacerlo. Permite a las autoridades del grupo, así como a las autoridades de usuarios.
-- Postgres syntax
create table users (
user_id serial primary key,
enabled boolean not null default true,
password text not null,
username citext not null unique
);
create index on users (username);
create table groups (
group_id serial primary key,
name citext not null unique
);
create table authorities (
authority_id serial primary key,
authority citext not null unique
);
create table user_authorities (
user_id int references users,
authority_id int references authorities,
primary key (user_id, authority_id)
);
create table group_users (
group_id int references groups,
user_id int referenecs users,
primary key (group_id, user_id)
);
create table group_authorities (
group_id int references groups,
authority_id int references authorities,
primary key (group_id, authority_id)
);
Luego en META-INF / applicationContext-security.xml
<beans:bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="passwordEncoder" />
<authentication-manager>
<authentication-provider>
<jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password, enabled from users where username=?"
authorities-by-username-query="select users.username, authorities.authority from users join user_authorities using(user_id) join authorities using(authority_id) where users.username=?"
group-authorities-by-username-query="select groups.id, groups.name, authorities.authority from users join group_users using(user_id) join groups using(group_id) join group_authorities using(group_id) join authorities using(authority_id) where users.username=?"
/>
<password-encoder ref="passwordEncoder" />
</authentication-provider>
</authentication-manager>
Estoy tratando de configurar una Seguridad basada en roles con permisos. Estoy tratando de hacer esto junto con Spring-Security.
No quiero configurar ACL porque parece que es excesivo para mis requerimientos.
Solo quiero tener permisos y roles simples como se describe en este article . Lamentablemente, el artículo no describe cómo implementar la solución dada.
¿Alguien ya ha intentado esto y puede señalarme en la dirección correcta? Tal vez hay otra entrada de blog que describe la implementación?
Muchas gracias.
Los pasos básicos son:
Use un proveedor de autenticación personalizado
<bean id="myAuthenticationProvider" class="myProviderImplementation" scope="singleton"> ... </bean>
Haga que su proveedor personalizado devuelva una implementación personalizada de
UserDetails
. EsteUserDetailsImpl
tendrá ungetAuthorities()
como este:public Collection<GrantedAuthority> getAuthorities() { List<GrantedAuthority> permissions = new ArrayList<GrantedAuthority>(); for (GrantedAuthority role: roles) { permissions.addAll(getPermissionsIncludedInRole(role)); } return permissions; }
Por supuesto, desde aquí podría aplicar una gran cantidad de optimizaciones / personalizaciones para sus requisitos específicos.
Para implementar eso, parece que tienes que:
- Cree su modelo (usuario, rol, permisos) y una forma de recuperar permisos para un usuario dado;
- Defina su propia
org.springframework.security.authentication.ProviderManager
y configúrela (configure sus proveedores) a unaorg.springframework.security.authentication.AuthenticationProvider
personalizada. Este último debe devolver en su método de autentificación una Autenticación, que debe ser configurada con laorg.springframework.security.core.GrantedAuthority
, en su caso, todos los permisos para el usuario dado.
El truco de ese artículo es asignar roles a los usuarios, pero establecer los permisos para esos roles en el objeto Authentication.authorities
.
Para eso, le aconsejo que lea la API y vea si puede ampliar algunos ProviderManager y AuthenticationProvider básicos en lugar de implementar todo. Lo hice con org.springframework.security.ldap.authentication.LdapAuthenticationProvider
estableciendo un LdapAuthoritiesPopulator personalizado, que recuperaría las funciones correctas para el usuario.
Espero que esta vez obtuve lo que estás buscando. Buena suerte.
Soy el autor del artículo en cuestión.
Sin duda, existen múltiples formas de hacerlo, pero la forma en que normalmente lo hago es implementar un UserDetails
personalizado que conoce los roles y permisos. Role
y el Permission
son solo clases personalizadas que usted escribe. (Nada de extravagante: el Role
tiene un nombre y un conjunto de instancias de Permission
, y el Permission
tiene un nombre.) Luego, getAuthorities()
devuelve objetos de GrantedAuthority
que se ven así:
PERM_CREATE_POST
, PERM_UPDATE_POST
, PERM_READ_POST
en lugar de devolver cosas como
ROLE_USER
, ROLE_MODERATOR
Los roles todavía están disponibles si su implementación UserDetails
tiene un método getRoles()
. (Recomiendo tener uno)
Idealmente, le asigna roles al usuario y los permisos asociados se completan automáticamente. Esto implicaría tener un UserDetailsService
personalizado que sepa cómo realizar esa asignación, y todo lo que tiene que hacer es generar la asignación desde la base de datos. (Ver el artículo para el esquema).
Luego puede definir sus reglas de autorización en términos de permisos en lugar de roles.
Espero que ayude.