How to revoke / revoke / revoke an old email confirmation token (id)

I allow new created users who know their password and have not yet confirmed to change their registration letter (if it is not registered in my database)

the problem is that if they change the email, I generate a new email confirmation token, but the old token can still validate them (the one I do when registering), which could pretty much mean people can use their registration mail in the first, change it to a different mail they don't have access to and validate it with the old one, which is a big security hole for me to just leave

Is there a way to remove / revoke an old token? (technically I could create a new user and delete the old one, the old token won't work for the new user, but I think there must be a better solution for that)

+3


source to share


1 answer


I added the following properties to the class ApplicationUser

public class ApplicationUser : IdentityUser {
    public string EmailConfirmationToken { get; set; }
    public string ResetPasswordToken { get; set; }
}

      

This refers to the confirmation token that will be verified when the email token is confirmed.

Then I added the following to mine ApplicationUserManager

, which is a derived class UserManager<ApplicationUser>

.



public override async System.Threading.Tasks.Task<string> GenerateEmailConfirmationTokenAsync(string userId) {
    /* NOTE:
     * The default UserTokenProvider generates tokens based on the users SecurityStamp, so until that changes
     * (like when the user password changes), the tokens will always be the same, and remain valid. 
     * So if you want to simply invalidate old tokens, just call manager.UpdateSecurityStampAsync().
     */
    //await base.UpdateSecurityStampAsync(userId);

    var token = await base.GenerateEmailConfirmationTokenAsync(userId);
    if (!string.IsNullOrEmpty(token)) {
        var user = await FindByIdAsync(userId);
        user.EmailConfirmationToken = token;
        user.EmailConfirmed = false;
        await UpdateAsync(user);
    }
    return token;
}

public override async System.Threading.Tasks.Task<string> GeneratePasswordResetTokenAsync(string userId) {
    var token = await base.GeneratePasswordResetTokenAsync(userId);
    if (!string.IsNullOrEmpty(token)) {
        var x = await FindByIdAsync(userId);
        x.ResetPasswordToken = token;
        await UpdateAsync(x);
    }
    return token;
}

public override async System.Threading.Tasks.Task<IdentityResult> ConfirmEmailAsync(string userId, string token) {
    var result = await base.ConfirmEmailAsync(userId, token);
    if (result.Succeeded) {
        var x = await FindByIdAsync(userId);
        x.EmailConfirmationToken = null;
        await UpdateAsync(x);
    }
    return result;
}

public override async System.Threading.Tasks.Task<IdentityResult> ResetPasswordAsync(string userId, string token, string newPassword) {
    var result = await base.ResetPasswordAsync(userId, token, newPassword);
    if (result.Succeeded) {
        var x = await FindByIdAsync(userId);
        x.ResetPasswordToken = null;
        await UpdateAsync(x);
    }
    return result;
}

      

The following extensions have been added to allow you to find a user based on a stored token.

public static class ApplicationUserManagerExtension {
    public static Task<string> FindIdByEmailConfirmationTokenAsync(this UserManager<ApplicationUser> manager, string confirmationToken) {
        string result = null;

        ApplicationUser user = manager.Users.SingleOrDefault(u => u.EmailConfirmationToken != null && u.EmailConfirmationToken == confirmationToken);

        if (user != null) {
            result = user.Id;
        }

        return Task.FromResult(result);
    }

    public static Task<string> FindIdByResetPasswordTokenAsync(this UserManager<ApplicationUser> manager, string token) {
        string result = null;

        ApplicationUser user = manager.Users.SingleOrDefault(u => u.ResetPasswordToken != null && u.ResetPasswordToken == token);

        if (user != null) {
            result = user.Id;
        }

        return Task.FromResult(result);
    }
}

      

+4


source







All Articles