基于casbin的ABAC/RBAC权限实践

7b32efc19ab7edb9c1d52547e84a3825.png


五一假期疫情封在家也没事做,就想来优化一下一个前端容器小项目

之前的TODOlist里面有一项是权限这块时隔2年了还一直没有动手

迟迟没搞主要还是我太懒了,哈哈 其实我一直想要找一个轻量级的权限通用方案

  • 权限的数据源可以切换,但是逻辑基本不用动

  • 权限策略定义简单不复杂,支持RBAC,ABAC(粒度可粗可细)

  • 支持内置超级用户(上帝模式)

知道我最近研究了一下casbin(基于各种访问控制模型的授权), 发现它正好满足了我以上几个点官网:https://casbin.org/

基于cashbin的权限实践

1. 权限设计

分为2种权限:超级管理员(上帝模式) 和 普通用户

我这个程序的功能是按照项目维度来区分的,超级管理员创建一个空项目后,授权给别人去维护,总共包含7大功能:

超级管理员可以访问所有功能, 但只能是【超级管理员】做的有1和2和3

  • 1.权限配置(普通用户创建和删除,权限的修改和保存)

  • 2.全局配置

  • 3.创建空项目

  • 4.上传并部署该项目

  • 5.把项目回滚到上一个版本

  • 6.项目维度的服务端js脚本(读和写)

  • 7.项目维度的配置文件(读和写)

普通用户则可以被超级管理员在权限配置页面创建并进行配置来限制是否授予访问4~7这几个功能

2. 代码开发

casbin基本主流的开发语言都有对应的实现,这里我用netcore版本(Casbin.NET)

首先定义模型:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act) || r.sub == "root"

由于我这个是按照project进行权限控制的,所以我选用的是这个模型

  • sub -> user(登录用户名,root是超级用户/上帝模式)

  • obj -> project(项目)

  • act -> api资源(这里用了基于正则的方式为了应对配置一个用户可以访问project下所有权限)

/// <summary>
/// 创建casbin模型
/// </summary>
/// <returns></returns>
public static Enforcer createEnforcer()
{
    var e = new Enforcer();
    var m = NetCasbin.Model.Model.CreateDefault();
    m.AddDef("r", "r", "sub, obj, act");
    m.AddDef("p", "p", "sub, obj, act");
    m.AddDef("e", "e", "some(where (p.eft == allow))");
    m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act) || r.sub == "root"");
    var csv = Path.Combine(WebRootPath, CasBinPolicyFile);
    if (!File.Exists(csv))
    {
        File.CreateText(csv);
    }

    e.SetModel(m);
    // 目前我的权限配置文件是放在csv文件中 切换成存db的话 就切换一个adapter
    e.SetAdapter(new DefaultFileAdapter(csv));
    e.LoadPolicy();
    return e;
}

由于本身我的这个项目是一个中间件,

734f68875e3c1242dde92b25736539f2.png

//内部api
app.UseWhen(
    c =>
    {
        // 检查路由是否满足要求
        if (!ApiMiddleware.CanInvoke(c, out var route))
        {
            return false;
        }
        // 路由规则满足后检查api是否存在
        return c.RequestServices.GetService<SpaDomain>()?.IsSpaApi(route.Item2) ?? false;
    },
    _ => _.UseMiddleware<ApiMiddleware>());

对于普通用户可访问的内部的api访问路径进行规则约束

  • 4.上传并部署该项目-> /{project}.reupload

  • 5.把项目回滚到上一个版本 ->  /{project}.rollback

  • 6.项目维度的服务端js脚本(读) ->  /{project}.getconfigjson

  • 项目维度的服务端js脚本(写) ->  /{project}.saveconfigjson

  • 7.项目维度的配置文件(读) ->  /{project}.serverjsget

  • 项目维度的配置文件(写)->  /{project}.serverjssave

这样我在ApiMiddleware里面可以进行统一权限拦截处理了

  • 解析请求路径 拿到 project(obj) 和 act (api)

  • 拿到当前登录 拿到 sub(user)

  • 拿到了sub,obj,act三要素后调用casbin方法进行验证

bool isAuthed = ef.Enforce(sub, obj, act);
61c63e4e3ac46c019a35f20603a9fdb4.png

设计一个页面来配置策略
18339f9065e54f92558bdd42e3f96371.png

这也是针对casbin的一个ui操作的封装

  • 支持创建用户

  • casbin的策略进行增删改查

  • 支持的api资源的列表展示

那么通过这个ui操作就很容易去配置

粗粒度:某个用户对哪些project有权限
9b4d3bb1ae9e2ba4842ed74dd15d4368.png
image

如上图,资源路径我配置了/* 代表这个zdyu用户可以访问project:test的所有操作

细力度:某个用户对哪些project的哪些具体操作有权限
41c26e9dd96b1895bb5856220ca2850b.png
image

如上图,代表zdyu这个用户只能访问test这个project下的 部署和回滚2个功能

总结

本身研究怎么用casbin是非常简单的,这里主要分享了结合具体项目来如何设计,细节源码可以查看

https://github.com/yuzd/Spa

spa单页面容器里面一个project相当于一个二级域名的应用,应用内互相隔离,可以代替部署nginx或apache,对前端开发者友好,适合在某些只是用来静态项目访问的场景,来提高效率!

权限这块使用casbin很轻量级,目前只保存在本地文件中,将来如果换成db也只是换一个adapter不用改逻辑非常方便。

531e1e4040aa9720a6982a48beacc961.png


我是正东,学的越多不知道也越多。一起追求高效率编程~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JWT是一种基于JSON的标准的身份验证和授权令牌,用于在网络应用中传递声明。而Casbin是一个强大的访问控制框架,它提供了一种灵活的权限管理方式,可以通过编程或配置文件进行RBAC(基于角色的访问控制)权限控制。 使用JWT和Casbin实现RBAC权限管理的一般流程如下: 1. 用户登录:用户提供用户名和密码进行身份验证,验证成功后后端生成JWT令牌并返回给前端。 2. 前端请求授权:前端在每次请求中携带JWT令牌,在请求头中加入Authorization字段,值为"Bearer + 生成的JWT令牌"。 3. 后端验证:后端接收到请求后,从请求头中获取JWT令牌。通过验证JWT的有效性(包括签名、过期时间等),确定用户的身份。 4. Casbin权限验证:后端使用Casbin框架进行RBAC权限验证。Casbin通过配置角色和权限关系的模型文件,根据用户的角色和请求路径,判断用户是否具有访问权限。 5. 授权结果返回:Casbin根据判断结果,返回授权结果给后端。如果授权成功,则继续处理请求;如果授权失败,则返回相应的错误提示。 通过将JWT和Casbin结合使用,可以实现灵活的RBAC权限管理。JWT用于验证用户身份并在请求中携带令牌,Casbin用于基于角色的权限控制。这样可以有效管理系统中的角色和权限关系,保证用户只能访问其拥有权限的资源,从而提高系统的安全性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值