在 ASP.NET Core 中强制更改密码

问题描述 投票:0回答:1

我正在配置我的应用程序来处理以下场景:当我创建一个新用户作为管理员时,会为该用户生成一个临时(随机)密码。用户首次登录后,需要修改密码。使用

MustChangePassword
类中的
AppUser : Identity
字段跟踪此要求。

我想强制用户在登录后必须立即更改密码。如果用户尝试访问任何其他链接,他们应该被重定向到“更改密码”页面。我认为配置中间件是最好的方法。

但是,根据我当前的配置(见下文),即使我提交更改密码表单,它仍然重定向到

/Account/ChangePassword.

public class CheckPasswordChangeMiddleware
{
    private readonly RequestDelegate _next;

    public CheckPasswordChangeMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
    {
        if (context.User.Identity.IsAuthenticated)
        {
            var user = await userManager.GetUserAsync(context.User);

            if (user != null && user.MustChangePassword && !context.Request.Path.StartsWithSegments("/Account/ChangePassword"))
            {
                context.Response.Redirect("/Account/ChangePassword");
                return;
            }
        }

        await _next(context);
    }
}
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePassword model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var result = await _accountService.ChangePasswordAsync(model);
    if (result)
    {
        return RedirectToAction("Index", "Home");
    }

    ModelState.AddModelError(string.Empty, "An error occurred while changing the password.");
    return View(model);
}
public async Task<bool> ChangePasswordAsync(ChangePassword model)
{
    var user = await _userManager.GetUserAsync(_httpContextAccessor.HttpContext!.User);
    if (user == null)
    {
        return false;
    }

    var changePasswordResult = await _userManager.ChangePasswordAsync(user, model.CurrentPassword, model.NewPassword);

    if (changePasswordResult.Succeeded)
    {
        user.MustChangePassword = false;
        await _userManager.UpdateAsync(user);
        await _signInManager.RefreshSignInAsync(user);
        return true;
    }
    return false;
}

感谢您的帮助或建议!

asp.net-core-mvc claims-based-identity asp.net-core-identity change-password
1个回答
0
投票

最好的方法是不要在

MustChangePassword
中添加
AppUser
字段,因为没有必要。您只会使用它一次,并且它将保留在那里未使用。

相反,请使用类型

claim
针对该用户添加
new Claim("MUST_CHANGE_PASSWORD","")

在您的中间件中:

public async Task InvokeAsync (HttpContext context)
{
    if (context.User.Identity.IsAuthenticated)
    {
        if (context.User.HasClaim("MUST_CHANGE_PASSWORD","") && context.Request.Path != "/Account/ChangePassword")
        {
            context.Response.Redirect("/Account/ChangePassword");
            return;
        }
    }

    await _next(context);
}

在您的

ChangePassword
HttpPost
方法中,一旦更改密码,请删除该声明
userManager.RemoveClaimAsync(User, new Claim("MUST_CHANGE_PASSWORD",""))

© www.soinside.com 2019 - 2024. All rights reserved.