Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Mikael Lindberg Mortensen 5 posts 35 karma points
    Feb 01, 2022 @ 14:32
    Mikael Lindberg Mortensen
    0

    I am trying to reset a members password. I want to send a token to the member and have him click a link. When I try to reset a password I get an error that the token is invalid. I have tried to bypass all the mail stuff but to no avail.

    Example:

    var member = await _memberManager.FindByEmailAsync("[email protected]");
    string token = await _memberManager.GenerateEmailConfirmationTokenAsync(member);
     string res = await _memberManager.ChangePasswordWithResetAsync(member.Id.ToString(), token, "1qaz2!wsx3dc");
    

    I have also tried this variant:

    var member = await _memberManager.FindByEmailAsync("[email protected]");
    string token = await _memberManager.GenerateEmailConfirmationTokenAsync(member);
    var test = _memberManager.ResetPasswordAsync(member, token, requestNewPassword.Password);
    
  • Bram van den Bogaard 9 posts 104 karma points
    Feb 01, 2022 @ 20:44
    Bram van den Bogaard
    0

    Have you manually created a flow that sends a token and validates the send token?

    I'm not sure what your problem is since you did not add any additional information. But what I do know is that by default the password reset functionality won't work unless you set a value in the web.config.

    Have you set an UmbracoMembershipProvider in the web.config?

    The value allowManuallyChangingPassword must be set to true.

            <membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
            <providers>
                <clear />
                <add name="UmbracoMembershipProvider" type="Umbraco.Web.Security.Providers.MembersMembershipProvider, Umbraco.Web" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="10" useLegacyEncoding="false" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Member" passwordFormat="Hashed" allowManuallyChangingPassword="true" />
                <add name="UsersMembershipProvider" type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco.Web" />
            </providers>
    
  • Mikael Lindberg Mortensen 5 posts 35 karma points
    Feb 01, 2022 @ 21:55
    Mikael Lindberg Mortensen
    0

    I am working in version 9. I haven't got a web.config file.

    The membership commands differs a lot in the .NET Core version.

  • Bram van den Bogaard 9 posts 104 karma points
    Feb 01, 2022 @ 22:01
    Bram van den Bogaard
    100

    Sorry hadn't noticed. In that case: do you have the AllowPasswordReset set to true?

  • Mikael Lindberg Mortensen 5 posts 35 karma points
    Feb 02, 2022 @ 09:23
    Mikael Lindberg Mortensen
    0

    Thank you for showing me that configuration. It did not help med though. I have found a workaround using the PasswordChanger class. I have to compare the token before changing password

    var changingPasswordModel = new Umbraco.Cms.Core.Models.ChangingPasswordModel()
    {
       Id = id,
       NewPassword = requestNewPassword.Password,
       OldPassword = null
    };
    
    var changePasswordResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _memberManager);
    
  • Jamie Attwood 201 posts 493 karma points c-trib
    Mar 28, 2022 @ 13:50
    Jamie Attwood
    2

    Just stumbled on this now. Looking at your original code, I am wondering if you were using the correct token generator method. In your code you use:

    string token = await _memberManager.GenerateEmailConfirmationTokenAsync(member);
    

    Have you tried:

    var token = await _memberManager.GeneratePasswordResetTokenAsync(user);
    var encodedToken = !string.IsNullOrEmpty(token) ? HttpUtility.UrlEncode(token) : string.Empty;
    

    The password reset token generator is probably what you are after. Additionally, you will need to encode the token so it survives the trip back to your change password page. For some reason, the token does not get generated as encoded. Note that you probably don't have to decode it again on the way back in. Hope that helps...

    Cheers,

    Jamie

  • Daljit Kaur 4 posts 74 karma points notactivated
    Apr 24, 2022 @ 11:40
    Daljit Kaur
    0

    Hi Jamie,

    I tried this one. With encoded token : It stated that its invalid.

    But otherwise it worked.

    So Cheers and thanks :)

    Regards.

  • Jamie Attwood 201 posts 493 karma points c-trib
    Apr 25, 2022 @ 12:31
    Jamie Attwood
    1

    Glad to hear that worked. If you are using your test scenario above where you are immediately testing the validity of the token without leaving your class, you would not need to encode it, but if you are sending the token out via email and returning it via a URL to a browser, you probably will need to encode it. If that helped you and this worked, can you please mark this one as solved?

    Cheers,

    Jamie

  • Bjarne Fyrstenborg 1280 posts 3990 karma points MVP 7x c-trib
    Sep 13, 2022 @ 11:40
    Bjarne Fyrstenborg
    0

    I tried GenerateEmailConfirmationTokenAsync()as well, but then got Invalid Token error later when using ChangePasswordWithResetAsync()

    var memberIdentity = await _memberManager.FindByEmailAsync(model.EmailAddress);
    //string token = await _memberManager.GenerateEmailConfirmationTokenAsync(memberIdentity);
    string token = await _memberManager.GeneratePasswordResetTokenAsync(memberIdentity);
    

    It works as expected when using GeneratePasswordResetTokenAsync() though.

    Later a new password if set from previous generated token.

    var memberIdentity = await _memberManager.FindByIdAsync(model.UserId);
    var result = await _memberManager.ChangePasswordWithResetAsync(memberIdentity.Id, token, model.Password);
    

    Not sure if the GenerateEmailConfirmationTokenAsync() shouldn't be used for members as I tried a similar approach the user password reset works in backoffice: https://github.com/umbraco/Umbraco-CMS/blob/26d83381f24fa5b11d1564e283660be31e07f82b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs#L572-L580

  • Jamie Attwood 201 posts 493 karma points c-trib
    Sep 13, 2022 @ 12:02
    Jamie Attwood
    0

    This definitely works for members. Make sure you encode the token in the email outbound. But don’t unencode the token on the way back in. For some reason you don’t need to unencode it.

    But email confirmation tokens are for validating/ confirming email addresses, not for resetting passwords. Two different methods for different purposes. For example after a member registers you want to check if there email is legit, you send them an email confirmation token. On the way back in you set email confirmed = true. Then you can test against that and approve their account at that point. Sorry I am on mobile but can post some examples later.

  • Bjarne Fyrstenborg 1280 posts 3990 karma points MVP 7x c-trib
    Sep 13, 2022 @ 12:33
    Bjarne Fyrstenborg
    0

    Okay, I was using the ToUrlBase64() and FromUrlBase64() extension methods, so with these it shouldn't be necessary to encode the URL further.

    var inviteToken = string.Format("{0}{1}{2}",
                    memberIdentity.Id,
                    WebUtility.UrlEncode("|"),
                    token.ToUrlBase64());
    

    The generated token was the same passed into ChangePasswordWithResetAsync() but I guess it won't work for this purpose.

    GeneratePasswordResetTokenAsync() and ChangePasswordWithResetAsync()seems to do the job.

  • Gareth Evans 140 posts 331 karma points c-trib
    Dec 07, 2022 @ 01:14
    Gareth Evans
    0

    @bjarne When you fetch the member to change the password later using ChangePasswordWithResetAsync, I assume the inviteToken containing the member id at the start (before the | prefix) is used. What prevents someone from changing that id number in the URL and using the link to reset someone elses password?

  • Jamie Attwood 201 posts 493 karma points c-trib
    Dec 07, 2022 @ 17:33
    Jamie Attwood
    0

    @Gareth, The token that is generated by GeneratePasswordResetTokenAsync() is unique to that user. If a different id or email is used against that token, the change password operations will fail.

    Cheers,

    Jamie

Please Sign in or register to post replies

Write your reply to:

Draft