ASP.NET Core

ASP.NET Core Identity メールアドレスとは異なるユーザー名を持っている際のログイン認証について

2020年7月10日

ASP.NET Core Identity では、デフォルトの設定として、「ユーザー名 = 登録メールアドレス」として認証を行うようになっています。ただし、ユーザー名をメールアドレスではなく任意のユーザー名にしたい局面もあります。このような場合、デフォルトの Identity フレームワークのログイン実装では認証が通りません。メールアドレスではない、任意のユーザー名を持っている際にもログインできるように、ログインの実装をカスタマイズする必要があります。

Login.cshtml.cs

UserManager の FindByEmailAsync メソッドを利用して、メールアドレスからユーザー名を割り出します。(13 - 14 行目)
その上で、SignInManager の PasswordSignInAsync メソッドに、メールアドレスではなく割り出したユーザー名を渡します。(17 - 20 行目)
これで、任意のユーザー名を指定した場合にも、ログインができるようになります。

namespace App.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LoginModel : PageModel
    {
        ...

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");

            if (ModelState.IsValid)
            {
                // 追加
                var user = await _userManager.FindByEmailAsync(Input.Email);
                // This doesn't count login failures towards account lockout
                // To enable password failures to trigger account lockout, set lockoutOnFailure: true
                // 変更前
                //var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true);
                // 変更後
                var result = await _signInManager.PasswordSignInAsync(user.UserName, Input.Password, Input.RememberMe, lockoutOnFailure: true);
                if (result.Succeeded)
                {
                    _logger.LogInformation("User logged in.");
                    return LocalRedirect(returnUrl);
                }
                if (result.RequiresTwoFactor)
                {
                    return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
                }
                if (result.IsLockedOut)
                {
                    _logger.LogWarning("User account locked out.");
                    return RedirectToPage("./Lockout");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return Page();
                }
            }

            // If we got this far, something failed, redisplay form
            return Page();
        }

        ...
    }
}

-ASP.NET Core