2012-03-15 11 views
11

Stiamo lavorando a un nuovo progetto con Grails 2.0.1 e Spring Security. Il contesto di creazione dell'utente non riesce a causa di springSecurityService nell'oggetto di dominio Utente che è null. Stranamente ciò si verifica solo nella nostra casella di testo di Linux mentre su tutte le finestre di Windows dello sviluppatore funziona correttamente. Non sono sicuro che abbia qualcosa a che fare con l'ambiente o se sia qualcos'altro. Sulla linux box questo fallisce costantemente.Null springSecurityService causa l'errore in encodePassword in Grails 2.0.1

La classe di dominio utente che stiamo utilizzando è di sotto (la classe generata da plugin con un paio di campi aggiuntivi). La codificaPassword viene gestita dai trigger beforeInsert(), beforeUpdate().

È venuto attraverso questo thread che parla dei riferimenti transitori che causano problemi nei flussi web, che presumo non vengono utilizzati qui, quindi non sono sicuro se questo è rilevante. 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) 
    } 
} 

Grazie in anticipo

+1

io preferirei non usare encodePassword nel dominio dell'utente, ma in posizione quando si crea utente: controllore, il servizio, i test: nuovo utente (username: "root", password: springSecurityService.encodePassword ('1')) Non penso che questo sia un workaround o un hack. –

+0

Quindi c'è un modo per creare una nuova istanza utente senza che la sua password sia codificata, poiché un chiamante non deve necessariamente usare encodePassword. Questa decisione di progettazione garantisce che la password sia sempre codificata quando il dominio Utente viene manipolato, che da un punto di vista della sicurezza è più robusto. –

risposta

20

È possibile utilizzare Groovy meta-programmazione per sovrascrivere il metodo encodePassword se desideri solo per assicurarsi che l'oggetto utente viene salvato e non si preoccupano della password per il test.

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

     service.invokeTestThatSavesUserDomainClass() 
    } 
} 
+0

Snap è stato semplice. Esattamente quello che stavo cercando di essere nuovo per i test e tutto. Ho letto le altre soluzioni su questo e altri post SO su questo stesso problema, questa è di gran lunga la soluzione più semplice! – Quad64Bit

3

springSecurityService NON deve essere transitorio. Il seguente codice dovrebbe funzionare

class User { 

    def springSecurityService 

    static transients = ["springSecurityService"] 

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

La sintassi degli OP funziona con Grails 2.0+ e così fa. –