ASP.NET Core 6.0 Razor Page基于Identity角色的登录跳转问题
ASP.NET Core 6.0 Razor Page Identity 登录后按角色跳转失效问题
问题描述
在ASP.NET Core 6.0 Razor Page项目中,使用Identity实现用户登录后根据角色跳转到指定页面,但当前登录后总是打开默认页面,角色跳转逻辑未生效。
角色定义代码
namespace PFS.Utility { public class SD { public const string AdminRole = "Admin"; public const string SellerRole = "Seller"; public const string DeliveryRole = "Delivery"; public const string BuyerRole = "Buyer"; } }
当前Login.cshtml.cs代码
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { // 此设置不将登录失败计入账户锁定 // 要启用密码失败触发账户锁定,请设置lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { if (User.IsInRole("Seller")) { return Redirect("~/Areas/Sellerr/Index"); } else if (User.IsInRole("Delivery")) { return Redirect("~"); } else if (User.IsInRole("Buyer")) { return Redirect("~"); } else if (User.IsInRole("Admin")) { return Redirect("~"); } else{ _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(); } } // 执行到此处说明验证失败,重新显示表单 return Page(); }
问题原因及解决方法
核心问题
调用PasswordSignInAsync成功后,当前请求上下文的User对象并未立即更新,此时User.IsInRole()判断的是登录前的身份信息,必然返回false,导致始终走else分支跳转到默认的returnUrl。
解决步骤
- 通过UserManager获取用户并验证角色:登录成功后,先通过邮箱获取用户实例,再用
UserManager.IsInRoleAsync()判断角色,该方法直接从数据库读取角色信息,不受当前请求上下文限制。 - 修正路径拼写错误:代码中
~/Areas/Sellerr/Index的Sellerr多了一个r,应改为Seller。 - 明确各角色跳转目标:避免多个角色都跳转到根路径,根据需求设置具体页面。
修改后的代码示例
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl ??= Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false); if (result.Succeeded) { // 获取当前登录用户实例 var user = await _userManager.FindByEmailAsync(Input.Email); if (user != null) { // 检查用户角色并跳转 if (await _userManager.IsInRoleAsync(user, SD.SellerRole)) { return Redirect("~/Areas/Seller/Index"); // 修正拼写错误 } else if (await _userManager.IsInRoleAsync(user, SD.DeliveryRole)) { return Redirect("~/Delivery/Index"); // 设置配送员专属页面 } else if (await _userManager.IsInRoleAsync(user, SD.BuyerRole)) { return Redirect("~/Buyer/Index"); // 设置买家专属页面 } else if (await _userManager.IsInRoleAsync(user, SD.AdminRole)) { return Redirect("~/Admin/Index"); // 设置管理员专属页面 } } // 无匹配角色时跳转到默认页面 _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, "登录失败,请检查邮箱或密码是否正确。"); return Page(); } } return Page(); }
额外注意事项
- 确保
_userManager已通过构造函数注入到LoginModel中。 - 确认用户已被正确分配对应角色,可通过数据库
AspNetUserRoles表验证角色关联关系。
内容的提问来源于stack exchange,提问作者Amal
相关产品推荐
相关产品推荐

