2012-03-15 18 views
11

Pracujemy nad nowym projektem z Grails 2.0.1 i Spring Security. Kontekst tworzenia użytkownika nie powiódł się, ponieważ właściwość springSecurityService w obiekcie domeny użytkownika ma wartość NULL. O dziwo, pojawia się tylko nasze pole tekstowe w Linuksie, podczas gdy na wszystkich okienkach okien programistycznych działa dobrze. Nie jestem pewien, czy ma to coś wspólnego ze środowiskiem, czy też jest czymś innym. W przypadku Linux-a to się nie udaje.Null springSecurityService powoduje niepowodzenie encodePassword w Grails 2.0.1

Klasa domeny użytkownika, której używamy, znajduje się poniżej (klasa generowana przez wtyczkę z dodatkowymi dodatkowymi polami). Hasło encodePassword obsługiwane jest przez wyzwalacze beforeInsert(), beforeUpdate().

Przychodzi przez ten wątek, który mówi o przejściowych odniesieniach powodujących problemy w przepływie, które, jak zakładam, nie są tutaj używane, więc nie jestem pewien, czy jest to istotne. 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) 
    } 
} 

góry dzięki

+1

wolałbym nie używając encodePassword w domenie użytkownika, ale w miejscu, gdy użytkownik jest tworzony: kontroler, serwis, testy: nowego użytkownika (login: „root”, hasło: springSecurityService.encodePassword („1”)) Nie sądzę, że jest to obejście lub hack. –

+0

Następnie istnieje sposób na utworzenie nowej instancji użytkownika bez zakodowanego hasła, ponieważ wywołujący nie _ musi koniecznie używać encodePassword. Ta decyzja projektowa zapewnia, że ​​hasło jest zawsze kodowane, gdy domena Użytkownika jest manipulowana, co z punktu widzenia bezpieczeństwa jest bardziej niezawodne. –

Odpowiedz

20

Można użyć Groovy na meta-programowanie przesłonić metodę encodePassword jeśli tylko chcą upewnić się, że obiekt użytkownika zostanie zapisany i nie dbają o hasło do testu.

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

     service.invokeTestThatSavesUserDomainClass() 
    } 
} 
+0

Snap, który był prosty. Dokładnie to, czego szukałem będąc nowym w testowaniu i wszystkim. Czytałem inne rozwiązania tego i innych artykułów SO na temat tego samego problemu, jest to zdecydowanie najprostsze rozwiązanie! – Quad64Bit

3

springSecurityService NIE może być przejściowy. Poniższy kod powinien działać

class User { 

    def springSecurityService 

    static transients = ["springSecurityService"] 

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

Składnia OP działa z Grails 2.0+, jak również to robi. –

Powiązane problemy