You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

解决步骤

  1. 通过UserManager获取用户并验证角色:登录成功后,先通过邮箱获取用户实例,再用UserManager.IsInRoleAsync()判断角色,该方法直接从数据库读取角色信息,不受当前请求上下文限制。
  2. 修正路径拼写错误:代码中~/Areas/Sellerr/Index的Sellerr多了一个r,应改为Seller。
  3. 明确各角色跳转目标:避免多个角色都跳转到根路径,根据需求设置具体页面。

修改后的代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:12:27