style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

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:

<?xml version="1.0" encoding="UTF-8"?>
<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

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

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.

Imagen de _RIP

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 interface

... implements AuthenticationManager {

Sólo debes de definir el método authenticate

Esta es la clase que no pudiste ver:

public class AccessControl implements AuthenticationManager {
 
 
    @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 a getUserInformation 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 de GrantedAuthority

Imagen de avefenix_x

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.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">