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();
}
...
}
}