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

ASP.NET Core中三个区域专属登录表单的认证实现指引

实现ASP.NET Core区域专属登录流程的步骤

1. 区域控制器与路由配置

为每个区域创建独立的AccountController,并添加[Area]特性指定所属区域:

// ProvinceArea/Controllers/AccountController.cs
[Area("ProvinceArea")]
public class AccountController : Controller
{
    [HttpGet]
    public IActionResult Login(string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        return View();
    }
}

CountyArea和DistrictArea的AccountController同理,仅需修改[Area]特性的参数值。

2. 完善Cookie认证方案配置

在Startup中为每个区域配置独立的Cookie认证方案,指定对应区域的登录路径:

services.AddAuthentication()
.AddCookie("ProvinceAuth", options =>
{
    options.LoginPath = "/ProvinceArea/Account/Login";
    options.AccessDeniedPath = "/ProvinceArea/Account/AccessDenied";
})
.AddCookie("CountyAuth", options =>
{
    options.LoginPath = "/CountyArea/Account/Login";
    options.AccessDeniedPath = "/CountyArea/Account/AccessDenied";
})
.AddCookie("DistrictAuth", options =>
{
    options.LoginPath = "/DistrictArea/Account/Login";
    options.AccessDeniedPath = "/DistrictArea/Account/AccessDenied";
});

3. 登录Post方法实现

以ProvinceArea为例,实现登录验证与认证逻辑:

[Area("ProvinceArea")]
public class AccountController : Controller
{
    // 注入用户验证服务(替换为你的业务逻辑实现)
    private readonly IProvinceUserService _userService;

    public AccountController(IProvinceUserService userService)
    {
        _userService = userService;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            // 验证区域专属用户
            var user = await _userService.ValidateUser(model.UserName, model.Password);
            if (user != null)
            {
                // 创建Claims身份
                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim(ClaimTypes.Role, "ProvinceAdmin")
                };
                var identity = new ClaimsIdentity(claims, "ProvinceAuth");
                var principal = new ClaimsPrincipal(identity);
                
                // 使用对应区域的认证方案登录
                await HttpContext.SignInAsync("ProvinceAuth", principal, new AuthenticationProperties
                {
                    IsPersistent = model.RememberMe
                });

                // 安全跳转回原请求页或区域首页
                if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                return RedirectToAction("Index", "Home", new { area = "ProvinceArea" });
            }
            ModelState.AddModelError(string.Empty, "用户名或密码错误");
        }
        // 验证失败返回登录页
        return View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync("ProvinceAuth");
        return RedirectToAction("Login", "Account", new { area = "ProvinceArea" });
    }
}

CountyArea和DistrictArea的登录逻辑仅需替换认证方案名(如"CountyAuth")、用户验证服务及跳转目标即可。

4. 区域页面的授权绑定

在区域内需要授权的控制器/Action上,指定对应区域的认证方案:

[Area("ProvinceArea")]
[Authorize(AuthenticationSchemes = "ProvinceAuth")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

未登录用户访问该控制器时,会自动跳转到对应区域的登录表单。

关键注意事项

  • 登录表单的ViewModel可共用,但需确保用户验证逻辑区分区域用户池。
  • 跳转returnUrl时必须用Url.IsLocalUrl验证,防止开放重定向攻击。
  • 认证方案名需与Startup配置完全一致,避免认证逻辑混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:22:57