2009-10-31 5 views

Répondre

3

à mon humble avis ce ne fait pas partie du plugin Acegi . J'ai ajouté une action forgotPassword au LoginController:

def forgotPassword = { 
    if (params.username) { 
     User user = User.findByUsername(params.username) 
     if (user) { 
      def password = randomService.generateRandomString(8) 
      user.passwd = authenticateService.encodePassword(password) 
      if (!user.save(flush:true)) { 
       user.errors.each { 
        log.error "err $it" 
       } 
       flash.message = message(code: "LoginController.msg.forgot.error") 
      } else { 
       sendMail { 
        to user.username 
        subject message(code:"LoginController.mail.forgot.subject") 
        body(view:"forgotPasswordEmail", model: [person:user, password:password]) 
       } 
       flash.message = message(code:"LoginController.msg.forgot", args:[user.username]) 
      } 
     } else { 
      flash.message = message(code:"LoginController.msg.forgot.unknown", args:[params.username]) 
     } 
    } 
} 

Le code ci-dessus utilise le plug-in de messagerie Grails.

+2

Ceci est une bonne implémentation de départ. Un problème potentiel est qu'il réinitialise automatiquement le mot de passe, même si quelqu'un d'autre le demande, de sorte qu'il est possible qu'un utilisateur malveillant frappe continuellement le mot de passe réinitialisé et change le mot de passe de l'utilisateur sans le vouloir. d encore recevoir l'e-mail). Nous avons fait quelque chose comme ça, mais à la place, nous avions une table qui contenait des jetons d'utilisation avec une courte durée de vie et qui étaient envoyés par e-mail pour réinitialiser un mot de passe. Si le jeton n'est pas utilisé, le mot de passe reste inchangé. Un seul jeton dans la table par utilisateur maximum. –

+0

Totalement d'accord. Une autre option serait une sorte de question de sécurité que les sites Web par exemple. "Quel est le nom de jeune fille de ta mère?". Seulement si la réponse à la question est correcte, le mot de passe sera réinitialisé. Peut-être que cela aurait du sens, de factoriser les fonctions de gestion de compte "récupérer le mot de passe", "récupérer le nom de connexion", "supprimer le compte" dans un plugin séparé qui dépend du plugin acegi. –

3

Google vous manque parce qu'il n'y en a pas. Il n'est vraiment pas possible d'inverser le mot de passe haché (sans craquage brutal et sans arc-en-ciel), et si c'était le cas, cela signifierait que votre système n'était pas sécurisé. Le modèle commun consiste à envoyer par courrier électronique à l'utilisateur qui a oublié son mot de passe un jeton d'utilisation unique qu'il peut ensuite utiliser pour réinitialiser le mot de passe à tout ce qu'il souhaite. Ce n'est pas construit dans le cadre, mais ce n'est pas trop difficile à faire manuellement (je suggère d'utiliser le plugin Grails mail).

3

Le plugin Acegi ne supporte pas ce plugin out of the box, mais si vous ajoutez le plugin email-confirmation, il est assez facile de rouler le vôtre.

Voici les étapes:

Créer un formulaire de réinitialisation de mot de passe qui demande à l'utilisateur d'entrer son adresse e-mail et nouveau mot de passe. L'action du contrôleur qui gère le formulaire de réinitialisation du mot de passe doit valider les données et utiliser le plugin de confirmation par courrier électronique pour envoyer un courrier électronique à l'utilisateur avec un lien sur lequel il doit cliquer pour confirmer son changement de mot de passe. Vous pouvez le faire en appelant la méthode suivante sur le service EmailConfirmationService ajouté par le plug-in.

def sendConfirmation(String emailAddress, String theSubject, Map model = null, 
String userToken = null) 

où:

emailAddress = address of user changing password 
theSubject = subject of e-mail sent 
model = any data passed to GSP that creates e-mail body 
userToken = hashed user's password 

lorsque l'utilisateur clique sur le lien dans l'e-mail (voir le plugin docs pour les informations sur la façon de personnaliser cet e-mail), la fermeture onConfirmation de le service sera appelé.

Cette fermeture devrait être attribué à Bootstrap.groovy comme ceci:

def emailConfirmationService 

def init = { servletContext -> 

    emailConfirmationService.onConfirmation = { email, hashedPassword -> 

    User user = User.findByEmail(email) 
    user.passwd = hashedPassword 
    if (!user.save()) { 
     // Handle this error, somehow.... 
    } 

    // Then return a map which will redirect the user to the login screen (for example) 
    [controller:'userProfile', action:'login'] 
    } 
} 

Notez que l'e-mail et mot de passe de l'utilisateur hashed sont passés dans cette fermeture, vous permettant de réinitialiser et enregistrer le mot de passe de l'utilisateur.

Questions connexes