2010-10-05 21 views
0

Je travaille sur un projet d'héritage de grails. Une classe de domaine appelée User existe. Il contient le mot de passe, le nom d'utilisateur, les rôles, etc.Grails printemps sécurité/Acegi. Utilisateur personnalisé + Mot de passe expiré gestion

Ce projet utilise Spring Security pour la gestion des rôles. Je voudrais ajouter l'expiration des informations d'identification (forcer l'utilisateur à renouveler son mot de passe).

J'ai modifié la classe User. Non, il implémente le UserDetails interface.

Cependant, quand je commence le serveur, je reçois cette erreur>

org.springframework.beans.factory.BeanCreationException: Erreur de création de haricot avec le nom 'MessageSource': Initialisation de haricots a échoué; exception imbriquée est org.springframework.beans.factory.BeanCreationException:

Erreur de création de haricot avec le nom « transactionManager »: Impossible de résoudre référence aux haricots « sessionFactory » tout en définissant la propriété de haricots « sessionFactory »; exception imbriquée est org.springframework.beans.factory.BeanCreationException:

Erreur de création de haricot avec le nom 'sessionFactory': Invocation de la méthode init a échoué; exception imbriquée est org.hibernate.PropertyNotFoundException:

Impossible de trouver un poseur de propriété accountNonExpired en classe com.company.app.user.User

Dois-je inscrire certains haricots? Je trouve l'erreur assez confuse, puisque l'interface ne demande pas de méthode setter.

mise à jour

Après avoir enquêté sur un peu plus, je suis tombé sur mon SecurityConfig.groovy, qui ressemble BEAUCOUP comme celui-ci (AcegiSecurity Plugin):

security { 
    // see DefaultSecurityConfig.groovy for all settable/overridable properties 

    active = true 

    loginUserDomainClass = "User" 
    authorityDomainClass = "Role" 

.... 
} 

Ma classe utilisateur regarde aussi BEAUCOUP comme ceci:

/** 
* User domain class. 
*/ 
class User { 
    static transients = ['pass','passwordExpired','credentialsNonExpired'] 
    static hasMany = [authorities: Role] 
    static belongsTo = Role 
    /** Username */ 
    String username 
    /** User Real Name*/ 
    String userRealName 
    /** MD5 Password */ 
    String passwd 
    /** enabled */ 
    boolean enabled 

    String email 
    boolean emailShow 

    /** description */ 
    String description = '' 

    /** plain password to create a MD5 password */ 
    String pass = '[secret]' 

    static constraints = { 
     username(blank: false, unique: true) 
     userRealName(blank: false) 
     passwd(blank: false) 
     enabled() 
    } 

    public boolean isCredentialsNonExpired() { 
     return true; 
    } 
} 

J'ai ajouté une méthode pour ch eck si le mot de passe doit expirer ou non pour cette classe (isCredentialsNonExpired). J'ai besoin de cette méthode pour exécuter à la connexion. En ce moment, ce n'est pas.

Donc, il semble que ce soit l'approche Acegi que je devrais adopter. Des pensées? Je crois comprendre qu'Acegi utilise Spring Security, n'est-ce pas?

+0

Oui, Acegi utilise Spring Secutity 2.0.x. Comme je l'ai dit dans ma réponse si vous avez ajouté une méthode isAccountNonExpired(), vous devez soit ajouter un setter pour le rendre persistant, soit le rendre transitoire si vous voulez juste déduire l'expiration d'autres données. –

Répondre

3

Utilisez-vous le plugin Acegi ou le configurez-vous directement? Si vous utilisez le plugin Spring Security Core cela sera beaucoup plus facile car il est pris en charge dès sa sortie de la boîte. Vous ne voulez probablement pas que votre classe User soit votre classe UserDetailsService car elle a souvent d'autres bagages comme des collections mappées, etc. Cela peut certainement fonctionner, mais créer une classe de données simple est une meilleure approche. Il est pratique de sous-classer org.springframework.security.userdetails.User ou org.springframework.security.core.userdetails.User en fonction de la version de Spring Security.

Il semble que vous venez d'ajouter un getter pour accountNonExpired, mais s'il doit être persistant, il a également besoin d'un setter. Si vous dérivez la valeur et ne veulent pas que champ dans la base de données, vous pouvez l'ajouter à la liste des transitoires:

static transients = ['accountNonExpired'] 
+0

Merci. Si je dois vérifier les informations d'identification expirées, serait-ce ['passwordExpired'] et une méthode isCredentialsNonExpired()? – Tom

+0

Droite. Ceci est également pris en charge dans le plugin Spring Security Core btw, voir la section 12.3 dans http://burtbeckwith.github.com/grails-spring-security-core/docs/manual/ –

+0

Impossible de le faire fonctionner, le débogueur ne s'arrêtera pas à ma méthode :( – Tom