zoukankan      html  css  js  c++  java
  • 如何在.netcore 上实现 Rbac 权限管理

    如何在.netcore 上实现 Rbac 权限管理

    1、.netcore 的权限系统

         .netcore 的权限系统是将认证系统和授权系统分两步实现的

     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
            ...
                
            // 认证系统
            app.UseAuthentication();
            // 授权系统
            app.UseAuthorization();
    
            ...
      }    
    

    认证系统:解决用户是谁的问题。

    当用户完成 Login 操作后,用户携带的相关信息通过 Claims 直接存到了 HttpContext.User.Identity 中。

    授权系统:解决该用户有没有对应的权限问题。

    2、.netcore 上的自定义授权实现

    可以在 controller 上加 attribute 的方式,通过实现 IAsyncAuthorizationFilter 接口获得授权执行的入口。

       [Authorize]
        public class HomeController : Controller
        {
            ...
      
            [PermissionFilter]
            public IActionResult Privacy()
            {
                return View();
            }
    
            ...
        }
    

     

      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
        public class PermissionFilter : Attribute, IAsyncAuthorizationFilter
        {
            public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
            {
                var url = context.HttpContext.Request.Path;
                var authorizationService = context.HttpContext.RequestServices.GetRequiredService<IAuthorizationService>();
                var authorizationResult = await authorizationService.AuthorizeAsync(context.HttpContext.User, null, new PermissionAuthorizationRequirement(url));
                if (!authorizationResult.Succeeded)
                {
                    context.Result = new ForbidResult();
                }
            }
        }
    

      

    其中 authorizationService 是自定义的授权类,需要在 Startup 文件中的 ConfigureServices 函数中提前注册好,而 PermissionAuthorizationRequirement() 是授权类需要用到的参数类

         public void ConfigureServices(IServiceCollection services)
            {
                ...
    
                services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();
            }
    

      

    下面的代码是 PermissionAuthorizationHandler 的具体实现:

        public class PermissionAuthorizationRequirement : IAuthorizationRequirement
        {
            public PermissionAuthorizationRequirement(string path)
            {
                Path = path;
            }
    
            public string Path { get; set; }
        }
    
        public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionAuthorizationRequirement>
        {
            protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionAuthorizationRequirement requirement)
            {
                if (context.User != null)
                {
                    if (context.User.IsInRole("admin"))
                    {
                        context.Succeed(requirement);
                    }
                    else
                    {
                        var userIdClaim = context.User.FindFirst(_ => _.Type == ClaimTypes.NameIdentifier);
                        if (userIdClaim != null)
                        {
                            //if (_userStore.CheckPermission(int.Parse(userIdClaim.Value), requirement.Path))
                            {
                                context.Succeed(requirement);
                            }
                        }
                    }
                }
                return Task.CompletedTask;
            }
        }
    

    通过在 HandleRequirementAsync 函数中,返回

    context.Succeed(requirement)

    表示授权通过。

    3、Rbac 授权实现

    通过 1和2 ,我们找到了实现自定义授权的方式,下面看看 Rbac 授权如何实现。

     Rbac 是通过把 permission 列表配给 role ,然后把多个 role 分配给用户。

    对于 controller 上的函数 Path ,正好就是这里的 permission,所以授权就是检测用户是否有 Path 的授权。

    CheckPermission(int.Parse(userIdClaim.Value), requirement.Path)
    

      

    4、参考资料

     ASP.NET Core 认证与授权[5]:初识授权

    在ASP.NET Identity 2.0中使用声明(Claims)实现用户组

     扩展IdentityRole和IdentityUser(Extending IdentityRole and IdentityUser)

    如何创建UserManager的实例(How do i create an instance of UserManager)

    扩展ASP.NET Identity使用Int做主键

     

  • 相关阅读:
    PHP快速入门
    redis命令_ZREVRANGEBYSCORE
    redis命令_ZRANGE
    redis命令_ZREM
    redis命令_ZINCRBY
    redis命令_ZADD
    redis命令_SETEX
    编译过程的一点心得
    关于c语言中的program_invocation_short_name
    关于toolchain(工具链)的一点知识
  • 原文地址:https://www.cnblogs.com/citycomputing/p/15329135.html
Copyright © 2011-2022 走看看