• 如何在.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做主键

     

  • 相关阅读:
    ByteBuffer的mark、position、limit、flip、reset,get方法介绍ok
    java.nio.ByteBuffer的flip、rewind和compact几个方法的区分使用
    maven之一:maven安装和eclipse集成
    Java 8 函数式接口
    Lambda 表达式
    jdk8十大新的特性
    阿里巴巴73款开源产品列表,值得收藏
    【Java】java.util.Objects 工具类方法研究
    ARIMA 模型简单介绍
    python 二维数组取值
  • 原文地址:https://www.cnblogs.com/citycomputing/p/15329135.html
Copyright © 2020-2023  润新知