Asp.net mvc MVC 6身份更改“的密码”;“超级用户”;
我需要“超级用户”的能力,以改变任何用户在身份系统的密码。我检查了两种解决方案 1) 将此重载函数添加到CRUD的CustomUserManager:Asp.net mvc MVC 6身份更改“的密码”;“超级用户”;,asp.net-mvc,asp.net-identity,Asp.net Mvc,Asp.net Identity,我需要“超级用户”的能力,以改变任何用户在身份系统的密码。我检查了两种解决方案 1) 将此重载函数添加到CRUD的CustomUserManager: public async Task<IdentityResult> ChangePasswordAsync(TenantUser user, string newPassword) {...} 自定义用户管理器:所有私有函数和参数已从orig UserManager复制到派生的CustomUserManager。NotSup
public async Task<IdentityResult> ChangePasswordAsync(TenantUser user, string newPassword)
{...}
自定义用户管理器:所有私有函数和参数已从orig UserManager复制到派生的CustomUserManager。NotSupportedException的资源仍然不可用。。。我对结果不满意。。。
你能帮助我吗?什么更好?实现CustomUserManager或解决无效令牌错误?请问怎么办
示例一个或多个函数(ChangePasswordAsync)需要复制的内容:
名称空间程序.Models
{
公共类TenantUserManager:UserManager,IDisposable,其中TenantUser:class
{
//受保护的常量字符串ResetPasswordTokenPurpose=“ResetPassword”;
//受保护的常量字符串ConfirmEmailTokenPurpose=“EmailConfirmation”;
私有时间跨度_defaultlocket=TimeSpan.Zero;
私人住宅;
私有只读HttpContext\u上下文;
private CancellationToken CancellationToken=>\U上下文?.RequestAborted??CancellationToken.None;
///
///构造的新实例。
///
///管理器将操作的持久性存储。
///用于访问的访问器。
///用于验证用户的。
///用于验证密码的集合。
///为用户生成索引键时要使用的。
///提供程序用于显示错误消息。
///用于解析服务的。
公共租户管理员(IUserStore存储、IOptions选项访问器、,
IPasswordHasher密码hasher,IEnumerable用户验证程序,
IEnumerable PasswordValidator、ILookupNormalizer、keyNormalizer、,
IdentityErrorDescriber错误、IServiceProvider服务、ILogger记录器、IHttpContextAccessor上下文访问器)
:base(存储、选项访问器、密码哈希器、用户验证器、密码验证器、密钥规范化器、错误、服务、记录器、上下文访问器)
{
}
///
///获取或设置管理器操作的持久性存储。
///
///管理器操作的持久性存储。
受保护的内部IUserStore存储{get;set;}
///
///获取用于记录来自管理器的消息的。
///
///
///用于记录来自管理器的消息。
///
//受保护的内部虚拟ILogger记录器{get;set;}
内部IPasswordHasher密码hasher{get;set;}
内部IList用户验证程序{get;}=new List();
内部IList密码验证程序{get;}=new List();
内部ILookupNormalizer键规范化器{get;set;}
内部标识ErrorDescriber ErrorDescriber{get;set;}
内部标识选项选项{get;set;}
公共异步任务ChangePasswordAsync(租户用户,字符串newPassword)
{
ThrowIfDisposed();
var passwordStore=GetPasswordStore();
if(user==null)
{
抛出新ArgumentNullException(nameof(user));
}
var result=await UpdatePasswordHash(密码存储、用户、新密码);
如果(!result.successed)
{
返回结果;
}
返回等待更新同步(用户);
//LogWarning(2,“更改用户{userId}的密码失败”,等待GeTenantUserIdAsync(用户));
//返回IdentityResult.Failed(ErrorDescriber.PasswordMismatch());
}
私有静态字符串NewSecurityStamp()
{
返回Guid.NewGuid().ToString();
}
私有IUserSecurityStampStore GetSecurityStore()
{
var cast=存储为IUserSecurityStampStore;
if(cast==null)
{
抛出新的NotSupportedException(“Resources.StoreNotIUserSecurityStampStore”);
}
回浇;
}
//如果存储区支持,请更新安全戳记
内部异步任务更新安全STAMPINTERNAL(租户用户)
{
if(支持SUSERSecurityStamp)
{
等待GetSecurityStore().SetSecurityStampAsync(用户,NewSecurityStamp(),CancellationToken);
}
}
内部异步任务UpdatePasswordHash(IUserPasswordStore passwordStore,
租户用户,字符串newPassword,bool validatePassword=true)
{
如果(验证密码)
{
var validate=await ValidatePasswordInternal(用户,新密码);
如果(!validate.successed)
{
返回验证;
}
}
var hash=newPassword!=null?PasswordHasher.HashPassword(用户,newPassword):null;
wait passwordStore.SetPasswordHashAsync(用户、哈希、取消令牌);
等待更新安全STAMPINTERNAL(用户);
返回IdentityResult.Success;
}
专用异步任务ValidateUserInternal(租户用户)
{
var errors=新列表();
foreach(UserValidators中的var v)
{
var result=await v.ValidateAsync(此,用户);
如果(!result.successed)
{
errors.AddRange(result.errors);
}
}
如果(errors.Count>0)
{
//Logger.LogWarning(13,“用户{userId}验证失败:{errors}.”,等待GeTenantUserIdAsync(用户),string.Join(“;”,errors.Select(e=>e.Code));
返回IdentityResult.Failed(errors.ToArray());
}
返回IdentityResult.Success;
}
专用异步任务ValidatePasswordInternal(租户用户,字符串密码)
{
var errors=新列表();
foreach(PasswordValidators中的var v)
{
var result=wait v.ValidateAsync(这个,用户,密码);
如果(!result.successed)
{
errors.AddRange(result.errors);
}
}
如果(errors.Count>0)
{
//Logger.LogWarning(14,“用户{userI
string Token = await manager.GeneratePasswordResetTokenAsync(TenantUser);
var resultPasswordChange = await manager.ResetPasswordAsync(TenantUser, Token, model.TenantUsersPassword.Password);
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);
}
}
}