xar*_*ar8 17 c# asp.net passwords asp.net-identity
我有一个使用Identity的ASP.NET项目.有关密码的身份配置,PasswordValidator正在使用.如何扩大密码超出了执法PasswordValidator目前有(RequiredLength,RequiredDigit,等),以满足该在N天后询问密码过期的要求?
Rik*_*ard 20
ASP.NET身份2中没有内置的功能.最简单的方法是在用户上添加一个字段,如LastPasswordChangedDate.然后在每次授权期间检查此字段.
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var user = await GetUser(context.UserName, context.Password);
if(user.LastPasswordChangedDate.AddDays(20) < DateTime.Now)
// user needs to change password
}
}
Run Code Online (Sandbox Code Playgroud)
加上@Rikard的答案...
我将模型添加LastPasswordChangedDate到ApplicationUser模型中,如下所示:
public class ApplicationUser : IdentityUser
{
public DateTime LastPasswordChangedDate { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
Run Code Online (Sandbox Code Playgroud)
向中添加静态配置设置AccountController(稍后您将需要Login():
private static readonly int PasswordExpireDays = Convert.ToInt32(ConfigurationManager.AppSettings["PasswordExpireDays"]);
Run Code Online (Sandbox Code Playgroud)
然后,在期间Login,检查用户是否应该重置密码。这仅在成功登录后进行检查,以免给用户带来太多错误。
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
var user = await UserManager.FindByNameAsync(model.Email);
if (user.LastPasswordChangedDate.AddDays(PasswordExpireDays) < DateTime.UtcNow)
{
return RedirectToAction("ChangePassword", "Manage");
}
else
{
return RedirectToLocal(returnUrl);
}
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Error: Invalid username or password");
return View(model);
}
}
Run Code Online (Sandbox Code Playgroud)
确保LastPasswordChangedDate在用户成功更新密码时在ManageController的ChangePassword操作中更新:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user != null)
{
user.LastPasswordChangedDate = DateTime.UtcNow;
await UserManager.UpdateAsync(user);
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12816 次 |
| 最近记录: |