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

ASP.NET Core基于用户角色重定向视图及404/405错误排查

问题修复方案

1. 初始HTTP 404错误修复

404的根因是ASP.NET Core Identity默认将未认证请求重定向到内置路径/Account/Login,但你的登录接口实际部署在Home控制器下(路径为/Home/Login),路由不匹配导致找不到页面。
在Startup.cs中补充Cookie认证路径配置即可修复,配置代码如下:

services.AddIdentity<User, IdentityRole>(opt =>
{
    // 保留原有Identity配置
    opt.User.RequireUniqueEmail = true;
    opt.User.AllowedUserNameCharacters = "";
    opt.Password.RequiredLength = 7;
    opt.Password.RequireDigit = false;
    opt.Password.RequireUppercase = false;
})
.AddEntityFrameworkStores<ApplicationContext>();

// 新增以下配置,匹配你实际的控制器路由
services.ConfigureApplicationCookie(opt =>
{
    opt.LoginPath = "/Home/Login";
    opt.AccessDeniedPath = "/Home/AccessDenied"; // 可按需配置无权限跳转页
});

// 保留你原有服务注册代码
services.AddScoped<IUserClaimsPrincipalFactory<User>, CustomClaimsFactory>();
services.AddAutoMapper(typeof(Startup));
services.AddControllersWithViews();

2. HTTP 405错误修复

405为请求方法不允许错误,根因是你给POST提交的Login接口错误添加了[Authorize]特性:用户提交登录表单时处于未认证状态,请求会被认证中间件拦截,而Identity默认仅对GET请求执行302重定向到登录页,POST请求会直接返回405状态码。
修复方式:

  • 移除POST版Login方法上的[Authorize]特性
  • 建议给GET、POST版Login接口都添加[AllowAnonymous]特性,明确标记接口允许匿名访问,避免全局授权规则拦截
[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
    ViewData["ReturnUrl"] = returnUrl;
    return View();
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(UserLoginModel userModel)
{
    // 方法逻辑见下文修正版
}

3. 角色重定向逻辑修复

你当前的重定向逻辑存在3个问题,会导致角色匹配失败:

  • HttpContext.User.IsInRole() 方法仅支持传入单个角色名判断,传入逗号分隔的多角色字符串时永远返回false
  • 角色名拼写错误:判断采购角色时把Procurment错写为Procurmant,无法匹配到实际角色
  • 调用_signInManager.PasswordSignInAsync登录成功后,当前请求的HttpContext.User不会立刻刷新为登录后身份,直接调用IsInRole无法获取到用户角色信息
    修正后的Login POST逻辑如下:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(UserLoginModel userModel)
{
    if (!ModelState.IsValid)
    {
        return View(userModel);
    }

    var result = await _signInManager.PasswordSignInAsync(userModel.UserName, userModel.Password, userModel.RememberMe, false);

    if (result.Succeeded)
    {
        // 登录成功后重新查询用户和所属角色,避免上下文未刷新的问题
        var user = await _userManager.FindByNameAsync(userModel.UserName);
        var userRoles = await _userManager.GetRolesAsync(user);

        // 按角色优先级匹配跳转
        if (userRoles.Contains("HR") || userRoles.Contains("HR-Manager"))
        {
            return RedirectToAction(nameof(HR));
        }
        if (userRoles.Contains("Projects") || userRoles.Contains("Projects-Manager"))
        {
            return RedirectToAction(nameof(Projects));
        }
        if (userRoles.Contains("Procurment") || userRoles.Contains("Procurment-Manager"))
        {
            return RedirectToAction(nameof(Procurment));
        }

        // 无匹配角色时优先跳回来源页,否则默认跳转首页
        if (!string.IsNullOrEmpty(userModel.ReturnUrl) && Url.IsLocalUrl(userModel.ReturnUrl))
        {
            return Redirect(userModel.ReturnUrl);
        }
        return RedirectToAction(nameof(Index));
    }

    ModelState.AddModelError("", "Invalid UserName or Password");
    return View(userModel);
}

注意:上述代码用到了_userManager,需要在控制器的构造函数中注入UserManager<User>实例即可。


内容的提问来源于stack exchange,提问作者Majid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:56:48