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

摘要:
authorizationResult.Sceeded){context.Result=newForbidResult();}}AuthorizationService是一个用户定义的授权类,需要预先在Startup文件的ConfigureServices函数中注册,而PermissionAuthorizationRequirement()是一个参数类publicvoid ConfigureServices{…services.AddSingleton<IAuthorizationHandler,PermissionAuthorization Handler>();}以下代码是PermissionAuthorizationHandler的具体实现:publicclassPermissionAuthorization Requirement:IAuthorizationRequirement{publicPermissionAuthoriizationRequirement}Path=Path;}publicstringPath{get;set;}}publicclassPermissionAuthorizationHandler:AuthorizationHandler<PermissionAuthorization Requirement>{protectedoverrideTaskHandleRequirementAsync{if(context.User!=null){//if{context.Sceeded;}}}}returnTask。CompletedTask;}}在HandleRequirementAsync函数中,上下文Succeede表示授权已通过。控制器上的功能Path正是这里的权限,因此授权是检测用户是否具有Path的权限。

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

 

免责声明:文章转载自《如何在.netcore 上实现 Rbac 权限管理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js应用实现博客个性主页布局拖拽功能PromQL-基础下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

实现自己的.NET Core配置Provider之Yaml

YAML是一种更适合人阅读的文件格式,很多大型的项目像Ruby on Rails都选择YAML作为配置文件的格式。如果项目的配置很少,用JSON或YAML没有多大差别。看看rails项目中的配置文件,如果用JSON写试试什么感受吧。 在《实现自己的.NET Core配置Provider之EF》中已经讲过配置的执行流程,这里不再复述,直接动手。 YamlCo...

在.net core中数据操作的两种方式(Db first &amp;amp;&amp;amp; Code first)

在开发过程中我们通常使用的是Db first这种模式,而在.net core 中推荐使用的却是 code first 反正我是很不习惯这种开发模式 于是就搜寻整个微软的官方文档,终于找到了有关.net core 使用Db first 的教程,这里给出链接:https://docs.microsoft.com/zh-cn/ef/core/miscellane...

Canvas:橡皮筋线条绘制

Canvas:橡皮筋线条绘制 效果演示 实现要点 事件监听 【说明】: 在Canvas中检测鼠标事件是非常简单的,可以在canvas中添加一个事件监听器,当事件发生时,浏览器就会调用这个监听器。 我们可以使用绑定事件属性: canvas.onmousedown = function(e) { //..... }   此外,也可以使用更为通用的...

Android 3.0 r1 API中文文档(107) —— AsyncPlayer

前言   本章内容是android.media.AsyncPlayer,版本为Android 3.0 r1!期待你一起参与Android API的翻译,联系我over140@gmail.com。 声明   欢迎转载,但请保留文章原始出处:)     博客园:http://www.cnblogs.com/     Android中文翻译组:http:/...

Android程序版本更新--通知栏更新下载安装

Android应用检查版本更新后,在通知栏下载,更新下载进度,下载完成自动安装,效果图如下: 检查当前版本号 AndroidManifest文件中的versionCode用来标识版本,在服务器放一个新版本的apk,versioncode大于当前版本,下面代码用来获取versioncode的值 PackageInfo packageInfo = conte...

odoo开发笔记:Server+Action服务器动作自动触发执行

       Odoo的市场定位是SME(中小型企业),这个市场的ERP产品,多如牛毛,产品各具特色。不过,Odoo的自动化处理机制,可以睥睨天下,无人能及。包括一些大型国产软件,如用友、金蝶也不具备如此强大的自动化业务处理功能。Odoo的业务自动化机制,可以非常容易地扩充ERP系统功能,非常容易地让业务工作自动化。 Odoo自动化动作 如下图,增...