2011-06-20 22 views
7

Tengo una aplicación Grails sencilla con Spring Security Core plugin instalado y funciona bien. Sin embargo, no he encontrado ninguna solución al problema con la actualización de las autoridades de un usuario conectado en el contexto de seguridad. No estoy hablando de actualizar los detalles del usuario actual (es decir, springSecurityService.reauthenticate).Grails Spring Security plugin - modificar las autorizaciones de usuario registradas

Mi problema es: Tengo una aplicación de administración de usuarios sencilla con las autoridades ROLE_ADMIN y ROLE_USER utilizadas. Ahora, tengo 2 administradores conectados al mismo tiempo (con la autoridad ROLE_ADMIN) de diferentes computadoras, y un administrador decide cambiar la autoridad del otro administrador de ROLE_ADMIN a ROLE_USER.

¿Cómo puedo actualizar el usuario y la función para que el usuario modificado (con la nueva función ROLE_USER) no pueda realizar ninguna acción de nivel ROLE_ADMIN y se redireccione inmediatamente a las páginas de nivel ROLE_USER? ¿Hay alguna manera de actualizar el contexto de seguridad para que no tenga que hacer comprobaciones adicionales en todas las acciones del controlador si las autoridades del usuario registrado han sido modificadas? ¿Puedo usar la propiedad cahceUsers para eso de alguna manera? No he modificado los cacheUsers y, a mi entender, es falso de manera predeterminada. Por favor corrígeme si estoy equivocado.

EDIT: La secuencia que está causando el problema es

  1. Administrador "A" modifica administrador "B" y establece un nuevo papel (ROLE_USER) para el administrador "B"

  2. el código llama a PersonRole.removeAll(personInstanceB) and PersonRole.create(personInstanceB, roleAdmin) y todo se actualiza normalmente

  3. al mismo tiempo El administrador "B" ya está conectado cuando se modifican sus autoridades. El administrador "B" puede seguir trabajando en las páginas restringidas ROLE_ADMIN hasta que se desconecte y realice un nuevo inicio de sesión. Solo entonces las autoridades se actualizan y el administrador "B" tiene el nuevo rol (ROLE_USER)

  4. Quiero que el administrador "B" sea redirigido a las páginas ROLE_USER cuando el usuario se actualiza con el nuevo rol y no solo después de desconectarse/login

  5. llamando al springSecurityService.reauthenticate personInstanceB.username) hace que el administrador "A" esté "conectado" como administrador "B" por lo que esto no funciona.

Cualquier idea sería muy bienvenida. Puede que me haya perdido algo simple aquí, pero no tengo idea de cuál sería la solución.

Saludos, mizzzto

Respuesta

11

Esto no se ha probado, pero darle una oportunidad

En su clase controlador/servicio,

... 

User user = User.get(springSecurityService.principal.id) //get the user 
Role adminRole = //get or create the admin Role 
UserRole.remove user, role // remove admin Role 

Role userRole = // get or create the user Role 
UserRole.create user, role //add the user Role 

... 

if (!user.hasErrors() && user.save(flush: true)) { 
    springSecurityService.reauthenticate user.username // refresh the users security deatils 
} 

.... 

EDITAR

Eso es mucho más claro ahora.

Lo que haría fuera de mi cabeza es utilizar la función de cambio de usuario.ver Switch User

  • En primer lugar se establece el atributo useSwitchUserFilter a true
  • Se aconseja que realiza una nueva función (por ejemplo ROLE_SWITCH_USER) para este privilegio.
  • en su página de administración en alguna parte,

    <sec:ifAllGranted roles='ROLE_SWITCH_USER'> 
        <form action='/j_spring_security_switch_user' method='POST'> 
         Switch to user: <input type='text' name='j_username'/> <br/> 
         <input type='submit' value='Switch'/> 
        </form> 
    </sec:ifAllGranted> 
    
  • registro como el usuario que desea editar usando su nombre de usuario
  • cambiar su configuración de las funciones mediante una llamada al método adminToUser() a continuación (por ejemplo)
  • cambiar de nuevo al usuario original
  • Listo.

- Usted puede utilizar el formato de código la primera respuesta para crear un método en el controlador o de servicios, tomar un userInstance y cambia emabrgo función de administrador para el usuario.

def adminToUser(user, adminRole, userRole){ 
    UserRole.remove user, adminRole 
    UserRole.create user, userRole 
    if (!user.hasErrors() && user.save(flush: true)) { 
     springSecurityService.reauthenticate user.username 
    } 
} 
+0

Hola, gracias por responder. Antes de publicar mi pregunta, ya había hecho lo que describió. Sin embargo, esto significa que si eres un administrador y actualizas la autoridad de otro administrador, entonces llamar a springSecurityService.reauthenticate user.username hará que la sesión se actualice con las credenciales del usuario modificado. Y eso significa que acaba de "iniciar sesión" como el usuario que ha modificado. No quiero eso :) Editaré mi publicación para que quede más claro en lo que estoy buscando. – mizzzto

+0

@mizzzto see EDIT! – gotomanners

+0

muchas gracias, parece estar funcionando bien ahora, ¡tan simple y sin embargo muy poderoso! :) Aunque, realmente debería haber una manera más fácil de notificar al usuario modificado que sus autoridades han sido cambiadas mientras el usuario está conectado. Necesito llegar al fondo de esto :) – mizzzto

6

que han resuelto este problema volver a autenticar dos veces:

Guardar el nombre del administrador que está degradando el otro usuario:

def originalUserName = springSecurityService.principal.name 
springSecurityService.reauthenticate user.username 
springSecurityService.reauthenticate originalUserName 
Cuestiones relacionadas