2009-05-27 6 views
3

J'écris une application Web dans Grails avec le plug-in Acegi/Spring Security et je n'arrive pas à voir les modifications apportées aux instances User . Je travaille seulement avec Groovy/Grails depuis environ trois semaines, donc s'il vous plaît pardonnez-moi si ce problème est trivial, puisque j'ai été penché sur des listes de diffusion et des tutoriels en essayant de trouver la réponse. J'ai ajouté de nouveaux attributs à la classe de domaine User chaque fois que j'ai besoin d'un utilisateur pour contenir plus d'informations comme un jeton de confirmation d'email ou un vrai nom, puisque je n'ai trouvé aucune recommandation à l'effet contraire. Tout semble bien fonctionner pour créer de nouveaux utilisateurs, mais lorsque je modifie l'utilisateur, les changements apparaissent dans la liste des utilisateurs, mais les bibliothèques de balises Acegi et les fonctions associées ne semblent pas voir les changements.Le plug-in Acegi/Spring Security Grails ne voit pas les modifications apportées à une instance utilisateur

Voici l'extrait pertinent de UserController.update():

def person = User.get(params.id) 
//...snip error checking... 

//Update user attributes 
person.username = params.email 
person.email = params.email 
person.userRealName = params.userRealName 

//Attempt to save changes 
if (person.save()) { 
    //If successful, redirect back to profile viewing page 
    redirect action: show, id: person.id 
    return 
} 
else { 
    //Otherwise, show errors and edit again 
    render view: 'edit', model: buildPersonModel(person) 
    return 
} 

Une fois ce code fonctionne, je peux voir les changements si je reçois toujours les données utilisateur par ID, mais pas si j'utilise les balises Acegi ou des fonctions. Par exemple, cela ne fonctionne pas:

loggedInUserInfo(field:'realName') 

Mais cela ne:

User.get(loggedInUserInfo(field:'id').toLong()).realName 

Les nouvelles informations parfois apparaît après que je vous déconnecter et à nouveau, mais le plus souvent il ne le fait pas, souvent ne pas apparaître même après trois ou plusieurs reloges. En outre, j'ai essayé d'ajouter "flush: true" à person.save() sans effet.

(question périphérique: est-il mauvais pour moi d'être jongler avec la classe utilisateur comme celui-ci Sinon, quelle est la meilleure façon d'ajouter des informations?)

Mise à jour après une enquête plus approfondie: Il On dirait que si j'utilise loggedInUserInfo() dans une page normale, cela fonctionne bien, mais si je l'utilise dans une mise en page, il présente le comportement que j'ai décrit. Pourrait-il y avoir quelque chose de caché bizarre?

Répondre

2

J'ai une solution de contournement pour ce problème et j'ai également créé une entrée JIRA pour le problème.

Il semble y avoir un bug dans la façon dont Acegi met à jour ses utilisateurs en interne. Je fournis une solution de contournement sous la forme d'un filtre Grails qui met à jour les droits de l'utilisateur manuellement chaque fois qu'un contrôleur est accédé. Pas idéal, mais ça marche.

Cheers,

+0

Merci pour le lien. Pourriez-vous donner un exemple de comment écrire un tel filtre? Je ne travaille plus sur le projet qui a le problème, mais je suis sûr que quelqu'un d'autre pourrait bénéficier de le voir. –

+0

chose sûre. Le guide des filtres de grails est ici: http://www.grails.org/Filters mais la version courte est qu'il suffit de mettre ce fichier de filtre dans votre répertoire grails-app/conf et cela fonctionne. Bravo – sinjax

+0

+1 - J'ai eu le même problème avec les rôles, et le filtre de contournement fourni dans le JIRA a résolu le problème. –

2

Avez-vous exécuté grails generate-manager après avoir modifié votre classe d'utilisateurs?

+0

Non, je ne l'ai pas fait, et je n'avais aucune idée de ce dont j'avais besoin. Je vous remercie! Je ne peux pas tester cela avant lundi, donc je vais attendre quelques jours avant de dire si c'est la solution ou non. –

+0

Je ne savais pas non plus il y a environ 3 mois. Mais sur http://www.infoq.com/articles/grails-acegi-integration j'ai trouvé la réponse dans le commentaire "Comment puis-je ajouter de nouveaux champs à AuthUser/User? Pourquoi 2 types d'utilisateurs?" Cela a résolu mon problème. –

+0

Désolé, mais cela ne le résout pas. Le problème persiste. Merci pour le lien, cependant. Je soupçonne que cela a quelque chose à voir avec les données mises en cache dans les sessions, mais je ne suis pas sûr. –

1

Acegi caches Informations sur l'utilisateur, si je me souviens bien. Vérifiez le fichier 'DefaultSecurityConfig' (je pense que c'est le nom, sous config /) pour désactiver le cache d'informations utilisateur. Vous pouvez également appeler une méthode sur authenticateService (ne peut pas se souvenir de la méthode en ce moment) pour expulser le cache de l'utilisateur.

Vous pouvez trouver ce dernier dans la fermeture UserController#update.

+0

Désolé, la définition de cacheUsers = false n'a pas résolu le problème. En outre, je n'ai pas trouvé la méthode pour expulser le cache utilisateur dans authenticateService. –

1

J'ai fait face au même problème, et j'ai suivi les conseils donnés par Maximilian Schweitzer ci-dessus. Cela n'a pas fonctionné pour moi au début.

Donnez ces étapes un essai et voir si elle résout le problème:

  1. j'ai couru générer-manager comme par réponse ci-dessus par Maximilian Schweitzer.
  2. Essayé de se connecter avec les utilisateurs créés avant couru générer-manager - Ça n'a pas marché
  3. J'ai créé un nouvel utilisateur (avec de nouveaux UserController, gsp, etc.)
  4. ai essayé de se connecter avec un nouvel utilisateur fonctionne très bien.
  5. Anciens utilisateurs supprimés créés avant et recréés. Cela a bien fonctionné.

Vous ne savez pas si cela s'applique à votre situation.

HTH!

+0

Si je n'avais pas déjà fait un tas de modifications sur les différents modèles et contrôleurs, j'essaierais cela, mais comme j'ai la solution, je vais laisser tomber. –

1

Je faisais face au même problème. Ma solution était de faire une mise à jour du plugin acegi vers la version 0.5.1 (acegi 0.5.1 - Grails Spring Security 2.0 Plugin).

Puis je me suis fixé à /plugins/acegi-0.5.1/grails-app/conf/DefaultSecurityConfig.groovy

cacheUsers = false 

et maintenant le tour est joué! ça fonctionne!

Luis

0

Vous devez réinitialiser l'utilisateur authentifié. Le code ci-dessous fait juste cela (de this blog).

import org.springframework.security.context.SecurityContextHolder 
import org.springframework.security.providers.UsernamePasswordAuthenticationToken 
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserImpl 
import org.springframework.security.GrantedAuthority 
import org.springframework.security.GrantedAuthorityImpl 

... 

def refreshAuthenticatedUser(user) { 
    GrantedAuthority[] auths = user.authorities.collect { 
     new GrantedAuthorityImpl(it.authority) 
    } 
    def grailsUser = new GrailsUserImpl(
      user.username, 
      "", 
      user.enabled, 
      true, 
      true, 
      true, 
      auths, 
      user) 
    def authToken = new UsernamePasswordAuthenticationToken(grailsUser, '', auths) 
    SecurityContextHolder.context.authentication = authToken 

}