2012-03-15 13 views
11

Estamos trabajando en un nuevo proyecto con Grails 2.0.1 y Spring Security. El contexto de crear usuario falla porque springSecurityService en el objeto de dominio del usuario es nulo. Extrañamente, esto ocurre solo en nuestro cuadro de texto de Linux, mientras que en todos los cuadros de ventanas de desarrolladores funciona bien. No estoy seguro de si tiene algo que ver con el medio ambiente o si es algo más. En el cuadro de Linux esto falla consistentemente.Null springSecurityService hace que encodePassword falle en Grails 2.0.1

La clase de dominio de usuario que estamos utilizando está por debajo (la clase generada por el complemento con un par de campos adicionales). EncodePassword está siendo manejado por los desencadenadores beforeInsert(), beforeUpdate().

Encontré este hilo que habla de las referencias transitorias que causan problemas en los flujos web, que supongo que no se están utilizando aquí, por lo que no estoy seguro de si esto es relevante. http://grails.1312388.n4.nabble.com/Spring-Security-Plugin-1-of-the-time-springSecurityService-null-td4349941.html

class User { 

    transient springSecurityService 

    static constraints = { 
     firstName blank: false, nullable: false, size: 2..100 
     lastName blank: false, nullable: false, size: 2..100 
     username blank: false, nullable: false, unique : true, email: true 
     password blank: false, nullable: false, size: 6..255 
    } 

    static mapping = { 
     password column: '`password`' 
    } 

    String username 
    String password 
    boolean enabled 
    boolean accountExpired 
    boolean accountLocked 
    boolean passwordExpired 

    /* user details */ 
    String firstName; 
    String lastName; 

    Set<Role> getAuthorities() { 
     UserRole.findAllByUser(this).collect { it.role } as Set 
    } 

    def beforeInsert() { 
     encodePassword() 
    } 

    def beforeUpdate() { 
     if (isDirty('password')) { 
      encodePassword() 
     } 
    } 

    protected void encodePassword() { 
     password = springSecurityService.encodePassword(password) 
    } 
} 

Gracias de antemano

+1

yo preferiría no usar encodePassword en el dominio del usuario, pero en su lugar cuando se está creando usuario: controlador, servicio, pruebas: nuevo usuario (nombre de usuario: "raíz", contraseña: springSecurityService.encodePassword ('1')) No creo que esto sea una solución o pirateo. –

+0

Luego hay una forma de crear una nueva instancia de Usuario sin tener codificada su contraseña, ya que una persona que llama _no necesariamente tiene que usar encodePassword. Esta decisión de diseño garantiza que la contraseña siempre esté codificada cuando se manipule el dominio de usuario, que desde el punto de vista de la seguridad es más robusto. –

Respuesta

20

Usted puede usar Groovy meta-programación para anular el método encodePassword si sólo desea asegurarse de que el objeto del usuario se guarda y no se preocupan por la contraseña de su prueba.

@TestFor(UserService)  
@Mock(User) 
class UserServiceTest { 
    void testMethod() { 
     User.metaClass.encodePassword = { -> } 

     service.invokeTestThatSavesUserDomainClass() 
    } 
} 
+0

Ajustar que era simple. Exactamente lo que estaba buscando ser nuevo en las pruebas y todo. Leí las otras soluciones en esta y otras publicaciones de SO sobre este mismo tema, ¡esta es, de lejos, la solución más simple! – Quad64Bit

3

springSecurityService NO debe ser transitorio. El siguiente código debería funcionar

class User { 

    def springSecurityService 

    static transients = ["springSecurityService"] 

    protected void encodePassword() { 
     password = springSecurityService.encodePassword(password) 
    } 
} 
+0

La sintaxis de OP funciona con Grails 2.0+ y esto también lo hace. –

Cuestiones relacionadas