ASP.NET l'Adhésion changer le mot de passe ne fonctionne pas
J'ai ce code pour changer un mot de passe utilisateur lorsqu'il clique sur le bouton de réinitialisation de mot de passe (avec un code pour se connecter à ELMAH afin que je puisse essayer de comprendre ce qui ne va pas).
C'est dans ASP.NET MVC 2, en utilisant le standard du réseau du fournisseur d'appartenances, avec une Vue simple comme ceci:
New Password: ______
Confirm Password: ______
[Reset] [Cancel]
L'itinéraire de ce point de vue est /Account/Reset/guid
, où guid est l'id de l'utilisateur dans la base de données des membres du réseau.
La partie de la clé du code de l'est où elle appelle user.ChangePassword()
. Vous pouvez voir qu'il enregistre un message en cas de succès. Le problème est que pour certains utilisateurs, le message de succès est connecté, mais ils ne peuvent pas se connecter avec le nouveau mot de passe. Pour les autres utilisateurs il enregistre le message de réussite et qu'ils peuvent se connecter.
if (user.ChangePassword(pwd, confirmPassword))
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - changed successfully!"));
return Json(new {
Msg = "You have reset your password successfully." },
JsonRequestBehavior.AllowGet);
}
Le code complet d'inscription est de:
[HttpPost]
public JsonResult ResetPassword(string id, string newPassword, string confirmPassword)
{
ErrorSignal.FromCurrentContext().Raise(new Exception("ResetPassword started for " + id));
ViewData["PasswordLength"] = Membership.MinRequiredPasswordLength;
if (string.IsNullOrWhiteSpace(newPassword))
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - new password was blank."));
ModelState.AddModelError("_FORM", "Please enter a new password.");
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
if (newPassword.Length < Membership.MinRequiredPasswordLength)
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - new password was less than minimum length."));
ModelState.AddModelError("_FORM",
string.Format("The password must be at least {0} characters long.",
Membership.MinRequiredPasswordLength));
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
if (string.IsNullOrWhiteSpace(confirmPassword))
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - confirm password was blank."));
ModelState.AddModelError("_FORM",
"Please enter the same new password in the confirm password textbox.");
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
if (confirmPassword.Length < Membership.MinRequiredPasswordLength)
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - confirm password was less than minimum length."));
ModelState.AddModelError("_FORM",
string.Format("The password must be at least {0} characters long.",
Membership.MinRequiredPasswordLength));
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
if (confirmPassword != newPassword)
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - new password did not match the confirm password."));
ModelState.AddModelError("_FORM", "Please enter the same password again.");
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
bool isMatch = ValidationHelper.IsGUID(id);
if (string.IsNullOrWhiteSpace(id) || !isMatch)
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - id was not a guid."));
ModelState.AddModelError("_FORM", "An invalid ID value was passed in through the URL");
}
else
{
//ID exists and is kosher, see if this user is already approved
//Get the ID sent in the querystring
Guid userId = new Guid(id);
try
{
//Get information about the user
MembershipUser user = Membership.GetUser(userId);
if (user == null)
{
//could not find the user
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - could not find user by id " + id));
ModelState.AddModelError("_FORM",
"The user account can not be found in the system.");
}
else
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - user is " + user.UserName));
string pwd = user.ResetPassword();
if (user.ChangePassword(pwd, confirmPassword))
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword - changed successfully!"));
return Json(new {
Msg = "You have reset your password successfully." },
JsonRequestBehavior.AllowGet);
}
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword
- failed to change the password, for an unknown reason"));
}
}
catch (Exception ex)
{
ErrorSignal.FromCurrentContext().Raise(
new Exception("ResetPassword: " + ex));
return Json(new { Error = ex.Message + " -> "
+ ex.InnerException.Message }, JsonRequestBehavior.AllowGet);
}
}
return Json(new { Errors = ModelState.Errors() }, JsonRequestBehavior.AllowGet);
}
Edit: Ajout d'une prime à essayer d'obtenir ce résolus. C'est l'un des plus ennuyeux de problèmes sur ma liste des problèmes, et je n'ai aucune idée de comment procéder.
Aussi, quel est le message d'erreur spécifique à l'utilisateur devient quand ils essaient d'ouvrir une session? C'est autre chose que la réinitialisation de leur mot de passe dans l'intervalle? Fondamentalement, la MembershipProvider fonctionne aussi loin que l'on sait, et le code que vous avez posté l'air bon, donc je suppose que le problème n'est pas un problème, ou est-ce dans un autre code.
Je l'ai essayé moi-même en réinitialisant le mot de passe à "password1", puis en essayant de se connecter immédiatement. Je ne pouvais pas vous connecter (nom d'utilisateur ou mot de passe incorrect). Pour les autres utilisateurs, et pour mon propre compte, je peux changer le mot de passe.
Est-ce la norme SQL Server ASP.NET de l'appartenance ou de l'autre?
N'êtes-vous pas censé envoyer un nom d'utilisateur pour le ResetPassword fonction? msdn.microsoft.com/en-us/library/...
OriginalL'auteur JK. | 2011-02-19
Vous devez vous connecter pour publier un commentaire.
Si l'utilisateur doit réinitialiser son mot de passe, il ya une chance que leur compte a été bloqué dans un trop grand nombre d'échecs. Si c'est le cas, alors le mot de passe est réinitialisé avec succès, mais l'utilisateur ne peut se connecter jusqu'à ce que la condition de verrouillage est désactivée.
Essayez de vérifier MembershipUser.IsLockedOut:
Modifier
Avez-vous également de vérifier IsApproved? L'authentification échoue c'est que c'est
false
pour l'utilisateur.Aussi, en supposant par défaut du fournisseur d'appartenances, tu veux dire que le SqlMembershipProvider, vous pouvez exécuter la requête suivante sur votre base de données et assurez-vous tout semble correct?
Essayez d'exécuter la requête avant de tenter de vous connecter à vérifier
IsApproved
etIsLockedOut
sont ok. Notez également la valeur pourFailedPasswordAttemptCount
.Essayez de vous connecter, puis exécutez à nouveau la requête. Si signin échoue, a de la valeur pour
FailedPasswordAttemptCount
été incrémenté?Vous pouvez consulter également
PasswordFormat
dans le aspnet_Membership table et assurez-vous qu'elle est la valeur correcte en fonction du format que vous utilisez (0 pour Effacer, 1 pour Hachés, et 2 pour les Crypté).veuillez voir mes modifications ci-dessus. Espérons que l'un de ces suggestions vous permettra de mettre en place un indice qui permet de. Je suis curieux de savoir ce que le problème s'avère être.
+1 IsApproved était faux dirait que le problème a été trouvé 🙂
OriginalL'auteur Jeff Ogata
Hmm, j'ai toujours utilisé des
Je n'ai jamais eu un problème avec elle renvoie true et le mot de passe n'est pas modifiée correctement.
Comme fas que je peux dire que votre code a l'air correct. Il est difficile de suivre, avec toutes les Elmah bruit. (vous pouvez le supprimer ou le remplacer par un simple journal d'appel, de sorte qu'il est plus facile à suivre).
Vérifiez que l'id de chaîne que vous avez passé en argument correspond à l'Identifiant de l'utilisateur. Vous pourriez être l'envoi de l'identifiant d'un autre utilisateur et changer le mot de passe des utilisateurs à la place.
user.UserName
- et il affiche le nom correct à chaque fois. Je vais essayer d'utiliserMembershipUser.ChangePassword
au lieu deuser.ChangePassword()
.Vous l'utilisez correctement. Ce n'est pas une méthode statique. Je viens de la signature, donc il est clair que la méthode qui j'ai été en vous référant à la. 😉
BTW, vous n'avez pas besoin JsonRequestBehavior.AllowGet depuis votre ResetPassword action est de la manipulation de ne Poster que des demandes. [HttpPost] Attribut.
OK je ne vais pas le changer ensuite. Je suis perdu, je ne peux pas voir pourquoi l'utilisateur.ChangePassword retourne vrai, mais vous ne pouvez pas vous connecter avec ce nouveau mot de passe. Je l'ai essayé moi-même en utilisant le guid d'un utilisateur qui ne pouvait pas changer son mot de passe, et confirmé que cela ne se produise.
Étrange affaire. Pendant que vous êtes encore le suivi de la question assurez-vous de connecter le confirmPassword argument. Vous ne savez jamais, il pourrait ne pas être ce que vous attendiez. Il pourrait par exemple être codées dans l'url si ils ont utilisé des caractères spéciaux (<,>, etc..)
OriginalL'auteur santiagoIT
Édité - suite à la réponse est "faux" voir les commentaires
Donc attendez vous essayez de localiser quelqu'un par un Guid? En faisant
Vous êtes pratiquement la création d'une garantie unique d'identification. Si ma conjecture est que vous n'êtes jamais trouver un utilisateur et vous êtes à la réinitialisation d'un mot de passe avec succès pour personne. Ne pouvez-vous pas juste les trouver par le paramètre id vous passer?
Guid userId = nouveau Guid(id) convertit la chaîne en paramètre id pour un Guid. Il ne génère pas un complètement nouveau Guid. Depuis L'Adhésion.GetUser s'attend à un Guid, vous devez utiliser cette conversion.
droit désolée de ne pas penser tout de suite ici ce soir édité le post, donc on n'y prend-il pour être vrai. pas sûr alors le code a l'air bien pour moi et bien sûr ce n'est pas vraiment de soulever des exceptions, donc je suppose que c'est une erreur sur le côté de la base de données. afin de ne pas avoir de problème avec aucun autre mot de passe méthodes?
en regardant votre commentaire à saint - auriez-vous de l'échantillon les mots de passe que vous avez confirmé le travail et l'exemple de ceux que vous pas du tout? ou êtes-vous en cours d'exécution dans la situation qui a donné le mot de passe de travail sur certains soumet mais pas sur d'autres?
Oui, je peux changer certains utilisateurs des mots de passe pour "password1" et d'autres utilisateurs, je ne peux pas changer pour le même "password1"
OriginalL'auteur Will Ayd
Cela fonctionne pour moi:
OriginalL'auteur
Je me demande si le problème, c'est que vous êtes en train de réinitialiser le mot de passe avant de le modifier. Sans entrer dans tous les internes de l'Appartenance de classe, pourriez-vous essayer de mettre dans une sorte de délai entre ces deux commandes?
OriginalL'auteur Frank Perez
Qui MemberShipProvider utilisez-vous? Est-il le même pour chaque utilisateur? Par exemple, si vous utilisez SqlMembershipProvider et définir enablePasswordReset à false, il va tranquillement ne pas mettre à jour le mot de passe. ChangePassword, dans ce cas, retourne vrai que si tout s'est bien passé.
OriginalL'auteur Pieter
Si vous utilisez le haut-SQLServer fournisseurs de prendre un coup d'oeil à votre Stockées SQL procs. C'est ce que mon défaut proc ressemble:
Comme vous pouvez le voir l'instruction de mise à jour pourrait tout à fait d'échouer et de la procédure stockée peut retourner la valeur true. Je pense que c'est là que vos erreurs sont probablement à venir. Peut être des problèmes de verrouillage...
OriginalL'auteur im_nullable
Eh bien, ce n'est certainement intéressant. Le "ça marche pour certains, pas pour d'autres," la partie est vraiment bizarre.
Est-ce un problème intermittent, ou faut-il toujours se produire pour certains utilisateurs, et toujours pas se produire pour les autres utilisateurs?
Quelqu'un d'autre ici a suggéré d'exécuter
ValidateUser(username, newPassword)
pour confirmer que l'utilisateur puisse authentifier correctement avant d'assumer succès.Avez-vous essayé? Vous pourriez boucle en continu, la réinitialisation de + changer le mot de passe jusqu'à ce que ValidateUser est réussie, peut-être la sortie après la N des échecs.
Remarque: Ce n'est pas pour une utilisation en production, juste pour le test pour voir si cela résout le problème.
OriginalL'auteur Pandincus
Êtes-vous à l'aide de 1 serveur ou plusieurs serveurs? Avec plusieurs serveurs, il se pourrait que la machinekey utilisé pour crypter le mot de passe n'est pas le même sur al serveurs.
OriginalL'auteur Wim
Votre principal bloc catch être lancer une exception que vous n'avez pas remarqué?
L'ex.InnerException.Message de déclaration n'est pas sûr car il pourrait jeter une exception NullReferenceException.
OriginalL'auteur miguelv