MVC 6 Identity ChangePassword for" SuperUser"

时间:2016-05-19 18:05:11

标签: asp.net-mvc asp.net-identity

我需要"超级用户"能够更改身份系统中任何用户的密码。我检查了两个解决方案。

1)将这个重载函数添加到CustomUserManager for CRUD:

public async Task<IdentityResult> ChangePasswordAsync(TenantUser user, string newPassword)
    {...}

使用具有令牌参数的原始函数,但控制器中的此功能不起作用并返回无效令牌:

string Token = await manager.GeneratePasswordResetTokenAsync(TenantUser);
var resultPasswordChange = await manager.ResetPasswordAsync(TenantUser, Token, model.TenantUsersPassword.Password);

自定义用户管理器:所有PRIVATE功能和参数已从orig UserManager复制到派生的CustomUserManager。 NotSupportedException的资源仍然无法使用...我对结果不满意...... 你能帮助我吗?什么是更好的?实现CustomUserManager或解决无效令牌错误?请问该怎么做?

示例您需要复制多一个函数(ChangePasswordAsync):

namespace Program.Models
{

public class TenantUserManager<TenantUser> : UserManager<TenantUser>, IDisposable where TenantUser : class
{
   // protected const string ResetPasswordTokenPurpose = "ResetPassword";
  //  protected const string ConfirmEmailTokenPurpose = "EmailConfirmation";



    private TimeSpan _defaultLockout = TimeSpan.Zero;
    private bool _disposed;
    private readonly HttpContext _context;
    private CancellationToken CancellationToken => _context?.RequestAborted ?? CancellationToken.None;



    /// <summary>
    /// Constructs a new instance of <see cref="UserManager{TenantUser}"/>.
    /// </summary> 
    /// <param name="store">The persistence store the manager will operate over.</param> 
    /// <param name="optionsAccessor">The accessor used to access the <see cref="IdentityOptions"/>.</param> 
    /// <param name="userValidators">A collection of <see cref="IUserValidator{TenantUser}"/> to validate users against.</param> 
    /// <param name="passwordValidators">A collection of <see cref="IPasswordValidator{TenantUser}"/> to validate passwords against.</param> 
    /// <param name="keyNormalizer">The <see cref="ILookupNormalizer"/> to use when generating index keys for users.</param> 
    /// <param name="errors">The <see cref="IdentityErrorDescriber"/> used to provider error messages.</param> 
    /// <param name="services">The <see cref="IServiceProvider"/> used to resolve services.</param> 
    public TenantUserManager(IUserStore<TenantUser> store, IOptions<IdentityOptions> optionsAccessor,
    IPasswordHasher<TenantUser> passwordHasher, IEnumerable<IUserValidator<TenantUser>> userValidators,
    IEnumerable<IPasswordValidator<TenantUser>> passwordValidators, ILookupNormalizer keyNormalizer,
    IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<TenantUser>> logger, IHttpContextAccessor contextAccessor)
    : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger, contextAccessor)
    {

    }
    /// <summary>
    /// Gets or sets the persistence store the manager operates over.
    /// </summary>
    /// <value>The persistence store the manager operates over.</value>
    protected internal IUserStore<TenantUser> Store { get; set; }

    /// <summary>
    /// Gets the <see cref="ILogger"/> used to log messages from the manager.
    /// </summary>
    /// <value>
    /// The <see cref="ILogger"/> used to log messages from the manager.
    /// </value>
 //   protected internal virtual ILogger Logger { get; set; }

    internal IPasswordHasher<TenantUser> PasswordHasher { get; set; }

    internal IList<IUserValidator<TenantUser>> UserValidators { get; } = new List<IUserValidator<TenantUser>>();

    internal IList<IPasswordValidator<TenantUser>> PasswordValidators { get; } = new List<IPasswordValidator<TenantUser>>();

    internal ILookupNormalizer KeyNormalizer { get; set; }

    internal IdentityErrorDescriber ErrorDescriber { get; set; }

    internal IdentityOptions Options { get; set; }






    public async Task<IdentityResult> ChangePasswordAsync(TenantUser user, string newPassword)
    {
        ThrowIfDisposed();
        var passwordStore = GetPasswordStore();
        if (user == null)
        {
            throw new ArgumentNullException(nameof(user));
        }
        var result = await UpdatePasswordHash(passwordStore, user, newPassword);
        if (!result.Succeeded)
        {
            return result;
        }
        return await UpdateUserAsync(user);
      //   Logger.LogWarning(2, "Change password failed for user {userId}.", await GeTenantUserIdAsync(user));
      //  return IdentityResult.Failed(ErrorDescriber.PasswordMismatch());            
    }


    private static string NewSecurityStamp()
    {
        return Guid.NewGuid().ToString();
    }


    private IUserSecurityStampStore<TenantUser> GetSecurityStore()
    {
        var cast = Store as IUserSecurityStampStore<TenantUser>;
        if (cast == null)
        {
            throw new NotSupportedException("Resources.StoreNotIUserSecurityStampStore");
        }
        return cast;
    }



    // Update the security stamp if the store supports it
    internal async Task UpdateSecurityStampInternal(TenantUser user)
    {
        if (SupportsUserSecurityStamp)
        {
            await GetSecurityStore().SetSecurityStampAsync(user, NewSecurityStamp(), CancellationToken);
        }
    }

    internal async Task<IdentityResult> UpdatePasswordHash(IUserPasswordStore<TenantUser> passwordStore,
       TenantUser user, string newPassword, bool validatePassword = true)
    {
        if (validatePassword)
        {
            var validate = await ValidatePasswordInternal(user, newPassword);
            if (!validate.Succeeded)
            {
                return validate;
            }
        }
        var hash = newPassword != null ? PasswordHasher.HashPassword(user, newPassword) : null;
        await passwordStore.SetPasswordHashAsync(user, hash, CancellationToken);
        await UpdateSecurityStampInternal(user);
        return IdentityResult.Success;
    }


    private async Task<IdentityResult> ValidateUserInternal(TenantUser user)
     { 
         var errors = new List<IdentityError>(); 
         foreach (var v in UserValidators) 
         { 
             var result = await v.ValidateAsync(this, user); 
             if (!result.Succeeded) 
             { 
                 errors.AddRange(result.Errors); 
             } 
         } 
         if (errors.Count > 0) 
         { 
         //    Logger.LogWarning(13, "User {userId} validation failed: {errors}.", await GeTenantUserIdAsync(user), string.Join(";", errors.Select(e => e.Code))); 
             return IdentityResult.Failed(errors.ToArray()); 
         } 
         return IdentityResult.Success; 
     } 


    private async Task<IdentityResult> ValidatePasswordInternal(TenantUser user, string password)
     { 
         var errors = new List<IdentityError>(); 
         foreach (var v in PasswordValidators) 
         { 
             var result = await v.ValidateAsync(this, user, password); 
             if (!result.Succeeded) 
             { 
                 errors.AddRange(result.Errors); 
             } 
         } 
         if (errors.Count > 0) 
         { 
          //   Logger.LogWarning(14, "User {userId} password validation failed: {errors}.", await GeTenantUserIdAsync(user), string.Join(";", errors.Select(e => e.Code))); 
             return IdentityResult.Failed(errors.ToArray()); 
         } 
         return IdentityResult.Success; 
     } 



    private async Task<IdentityResult> UpdateUserAsync(TenantUser user)
     { 
         var result = await ValidateUserInternal(user); 
         if (!result.Succeeded) 
         { 
             return result; 
         } 
         await UpdateNormalizedUserNameAsync(user); 
         await UpdateNormalizedEmailAsync(user); 
         return await Store.UpdateAsync(user, CancellationToken); 
     }




    private IUserPasswordStore<TenantUser> GetPasswordStore()
     { 
         var cast = Store as IUserPasswordStore<TenantUser>; 
         if (cast == null) 
         { 
             throw new NotSupportedException("Resources.StoreNotIUserPasswordStore"); //Resources are not awailable
         } 
         return cast; 
     }


    /// <summary> 
    /// Releases the unmanaged resources used by the role manager and optionally releases the managed resources. 
    /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> 
    protected override void Dispose(bool disposing)
     { 
         if (disposing && !_disposed) 
         { 
             Store.Dispose();
            _disposed = true;
        } 
     }


     protected void ThrowIfDisposed()
     { 
         if (_disposed) 
         { 
             throw new ObjectDisposedException(GetType().Name); 
         } 
     } 
}

0 个答案:

没有答案