Como especificar roles dinámicamente en archivo de configuración de Spring Security?
Hola comunidad Java, espero puedan ayudarme a lo siguiente.
Estoy configurando Spring Security en una aplicación web, la funcionalidad es la siguiente:
Tengo una pantalla en la que el usuario puede definir roles, para eso el usuario debe crear un nuevo rol y que permisos tiene
ej)
ROL_PRODUCCION
este sera almacenado en BD en una tabla de Roles, no tengo manera de saber como se van a llamar cada rol.
por lo tanto necesito saber como indicarle a Spring Security donde tomar esos roles y con su respectiva url y asi poder configurarlo con el tag
Tengo definido mi spring-security.xml de la siguiente manera:
<beans:beans
xsi:schemaLocation="http://www.springframework.org/schema/beans <a href="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" title="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">http://www.springframework.org/schema/beans/spring-beans-3.1.xsd</a>
<a href="http://www.springframework.org/schema/security" title="http://www.springframework.org/schema/security">http://www.springframework.org/schema/security</a> <a href="http://www.springframework.org/schema/security/spring-security-3.1.xsd"
" title="http://www.springframework.org/schema/security/spring-security-3.1.xsd"
">http://www.springframework.org/schema/security/spring-security-3.1.xsd"
</a> xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns="http://www.springframework.org/schema/beans">
<security:global-method-security secured-annotations="enabled" />
<security:http auto-config="true" use-expressions="true">
<security:form-login login-page="/vistas/login.xhtml" authentication-failure-url="/vistas/login.xhtml" />
<security:intercept-url pattern="/vistas/index.xhtml" access="isAuthenticated()" />
<!-- <security:intercept-url pattern="/vistas/seguridad/usuarios.xhtml" access="hasRole('ADMINISTRADOR')"/> -->
<security:intercept-url pattern="/vistas/seguridad/**" access="isAuthenticated()"/>
<security:logout logout-success-url="/vistas/login.xhtml?loggedout=true" invalidate-session="true" />
<security:session-management>
<security:concurrency-control max-sessions="1" expired-url="/vistas/login.xhtml" error-if-maximum-exceeded="false" />
</security:session-management>
</security:http>
<!-- *** Configuracion de LDAP *** -->
<beans:bean id="adAuthenticationProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="XXX.XXX.XXX"/>
<beans:constructor-arg value="ldap://XXX.XXX.XXX.XXX:XXX"/>
</beans:bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="adAuthenticationProvider"/>
</security:authentication-manager>
</beans:beans>
Gracias
- _RIP's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
security:custom-filter
En la configuración de spring, debes indicar que utilizarás un custom-filter. Ese filtro tienes que programarlo para implementar tu método de autenticación y de asignación de roles. A mi megusta mucho definir mi propio filtro porqueen muchisimas ocaciones no se puede seguir el estandar que indica spring para autenticar directamente desde DB y la configuración de spring no es para nada flexible si los usuarios y sus roles son valriables en cuanto a número e incluso en cuanto a perfil.
Gracias por la respuesta pero
Gracias por la respuesta pero no puede acceder al contenido que mencionas, puedes postear el codigo? por favor.
Ooops
Es que hice un refactor al nombre del paquete, https://github.com/javadabadoo/chachareando/blob/master/basureando-web/s...
Lo que se trata (como ves en la configuración) es de indicar que vas a definir tu propio
AuthenticationManager
, para ello debes de immplementar dicha interfaceSólo debes de definir el método
authenticate
Esta es la clase que no pudiste ver:
@Autowired
private UserDao userDao;
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
UsernamePasswordAuthenticationToken authenticationToken;
User user = this.getUserInformation(auth.getPrincipal().toString());
if (user == null || !user.getPassword().equals(auth.getCredentials().toString())) {
throw new BadCredentialsException(PropertiesContainer.get("seguridad.acceso.mensaje.informacionDeAccesoIncorrecta"));
}
Collection<GrantedAuthority> userRoles = this.authorize(user.getRolesList());
authenticationToken = new UsernamePasswordAuthenticationToken(
user.getName(),
user.getPassword(),
userRoles);
return authenticationToken;
}
private User getUserInformation(String userAlias) {
User user = this.userDao.select(userAlias);
if (user != null) {
user.setRolesList(this.userDao.selectUserRoles(user.getId()));
}
return user;
}
private Collection<GrantedAuthority> authorize(List<String> roles) {
List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
for (String rol : roles) {
authList.add(new SimpleGrantedAuthority(rol));
}
return authList;
}
}
Nota que desde el método
authenticate
se invoca agetUserInformation
el cual se encarga de consultar la información del usuario mediante el alias. Si encuentra al usuario (es porque está registrado en el sistema) entonces consulta sus roles. Después se realiza la validación del password. Tambien es posible que valides mas chácharas como tipo de usuario, vigencia (si aplica), etc.Finalmente, como la información de los roles debe estar en
Collection<GrantedAuthority>
hay otro métodito (authorize
) que genera esa lista deGrantedAuthority
Creo que la solucion planteada es para otro problema.
La solucion es para autentificarte de forma corecta anexandoles a esa autentificacion los roles con la metodologia de AuthenticationManager.
Aqui el problema planteado es que los roles por ejemplo "ADMINISTRADOR" y los url que administran no deben de ir en el archivo de configuracion sino que esos datos vienen de la base de datos.
entonces lo que requieres es implementar el FilterInvocationSecurityMetadataSource para que al momento de que Spring security pregunte por los URL vaya a la base de datos y sepa que roles le corresponden.
En este enlace puedes encontrar tips para que hagas tu solucion.
Saludos.