ASP.NET 核心自定义用户角色实现

ASP.NET Core custom defined User Roles implementation

我正在尝试定义 用户角色 的自定义方式,因为我的用户 table 数据库结构如下:


Role 是一个布尔值,所以如果它是 true,则用户是管理员,否则他是普通用户。


我知道我需要在 Startup.cs. 中声明 add.UseAuthorization() 并且我可以添加属性 [Roles="Administrator"] / [Roles="User"]Controller 中,但我不确定如何定义由用户 table 的 Role 列确定的角色。

我一直在网上搜索,也阅读了有关政策的内容,但我认为这不是实施的正确方法。我在网上找到的所有内容都与某种 Identity 结构有关,但对于如何将其附加到我的 Role 列没有任何意义。

希望有人能帮助我。谢谢!

如果您可以随意操作您的数据库,我强烈建议您使用 IdentityFramework,它是一个可以集成到您自己的数据库中的强大框架。

但要具体回答您的问题,缺少两个步骤:

  • 选择一个身份验证方案来登录用户(例如,基于 Cookie,...)
  • 用户登录后,将设计好的 Role 保存在 ClaimsPrincipal 对象中。这样 [Authorize(Roles = "User")] 声明就可以选择它。

下面是一个使用 Visual Studio 中默认 ASP.NET 核心模板的基本示例。

  1. 添加身份验证中间件您的 ConfigureServices 方法,并使用 AuthenticationScheme 对其进行配置。在这种情况下,我使用的是 Cookie 身份验证。

    //in ConfigureServices, add both middlewares
    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie();
    
    //in the Configure() method, enable these middlewares
    app.UseAuthentication();
    app.UseCookiePolicy(new CookiePolicyOptions());
    

现在您可以开始行动了。假设您有一个要在其中对用户进行身份验证的 Action 方法。这是您要转换角色的地方,以便它可以被 [Authorize]

识别
  1. 从数据库中获取所需的值。你最终会得到 bool。将其转换为角色 Claim,并将其添加到 ClaimsIdentity

    bool roleFromDb = true;  //this comes from db
    
    //convert to Claim of "Role" type, and create a ClaimsIdentity with it
    var adminClaim = new Claim(ClaimTypes.Role, roleFromDb ? "Administrator" : "User"); 
    var claimIdentity = new ClaimsIdentity(new[] { adminClaim }, 
                        CookieAuthenticationDefaults.AuthenticationScheme);
    
    //signs in the user and add the ClaimsIdentity which states that user is Admin
    await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme,
            new ClaimsPrincipal(claimIdentity));
    

完成后,您可以使用 [Authorize] 属性标记其他操作方法,例如:

[Authorize(Roles = "User")]
public IActionResult About() { ... }

[Authorize(Roles = "Administrator")]
public IActionResult Contact() { ... }

现在,只有具有 "Administrator" 角色的登录用户才能访问联系人页面。

检查 this 资源以获得所用中间件的更精细配置。

另一种基于我的数据库而不进行任何修改的实施方式是使用声明和 Cookie。我已经阅读了以下文档

Link One

Link Two

我只遇到过一个主要问题,通过阅读 this 解决了。

我还将添加登录方法和 Startup.cs 行,以便其他人可以看到如何使用它(如果文档不够)。

来自 Controller

Login 方法

   [AllowAnonymous]
    [HttpPost]
    public async Task<IActionResult> Login(UserModel userModel)
    {
        if (_iUserBus.LoginUser(userModel))
        {
            var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, userModel.Email),
                    new Claim(ClaimTypes.Role, _iUserBus.GetRole(userModel.Email)),
                };

            ClaimsIdentity userIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
            ClaimsPrincipal principal = new ClaimsPrincipal(userIdentity);

            var authProperties = new AuthenticationProperties
            {
                IsPersistent = false,
            };

            await HttpContext.SignInAsync(principal, authProperties);

            return RedirectToAction("Index", "Home");
        }
        else
        {
            ModelState.AddModelError("Password", "Email and/or Password wrong");

            return View();
        }
    }

Startup.cs

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        });

        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
        {
            options.LoginPath = "/Users/Login";
            options.LogoutPath = "/Users/Logout";
        });

希望这对有需要的人有用。