权限管理(1/3):pyCasbin 持久化,基于json文件adapter 实现方法

PyCasbin: 支持 ACL、RBAC、ABAC 多种模型的 Python 权限管理框架

PyCasbin 是一个用 Python 语言打造的轻量级开源访问控制框架( https://github.com/casbin/pycasbin ),目前在 GitHub 开源。PyCasbin 采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制 RBAC、基于属性的访问控制 ABAC 等。

PyCasbin 的主要特性包括

1.支持自定义请求的格式,默认的请求格式为{subject, object, action};

2.具有访问控制模型 model 和策略 policy 两个核心概念;

3.支持 RBAC 中的多层角色继承,不止主体可以有角色,资源也可以具有角色;

4.支持超级用户,如 root 或 Administrator,超级用户可以不受授权策略的约束访问任意资源;

5.支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*

PyCasbin 不做的事情:

1.身份认证 authentication (即验证用户的用户名、密码),PyCasbin 只负责访问控制。应该有其他专门的组件负责身份认证,然后由 PyCasbin 进行访问控制,二者是相互配合的关系;

2.管理用户列表或角色列表。PyCasbin 认为由项目自身来管理用户、角色列表更为合适,PyCasbin 假设所有策略和请求中出现的用户、角色、资源都是合法有效的。

安装

pip install casbin

HelloWorld 例子

1.初始化一个 enforcer,传入两个参数:模型文件路径和策略文件路径;

import casbin
e = casbin.Enforcer("path/to/model.conf", "path/to/policy.csv")

2.在你的代码需要进行访问控制的位置,加入如下钩子;

sub = "alice"  # the user that wants to access a resource.
obj = "data1"  # the resource that is going to be accessed.
act = "read"  # the operation that the user performs on the resource.

if e.enforce(sub, obj, act):
    # permit alice to read data1
    pass
else:
    # deny the request, show an error
    pass

3.采用管理 API 进行权限的管理,如获取一个用户所有的角色;

roles = e.get_roles("alice")

社区进展

PyCasbin 目前正在积极向社区进行推送,并且可以通过插件的方式已经支持与 Django 等 Web 框架进行集成,将来会推广到更多 Web 框架以及社区。Casbin 已经有 Golang 版本、Java 版本、PHP 版本、Node.js 版本、Pytho n版本 等主流语言版本。有跨语言需求的开发者可以只用 Casbin 这一套框架就实现多个不同语言的项目的权限管理任务。

协议

PyCasbin 采用 Apache 2.0 开源协议发布。


权限管理开源库pyCasbin 持久化 基于json文件adapter 实现方法

前言
公司的软件管理一直没有权限管理模块,最近老板让研究一下Casbin 这个开源库,花了两天简单的了解了一下,由于Casbin没有c/c++版本实现,而我会一点python 语法,所以选择研究一下python 版本pyCasbin的使用

PyCasbin 是一个用 Python 语言打造的轻量级开源访问控制框架目前GitHub(https://github.com/casbin/pycasbin)开源。PyCasbin 采用了元模型的设计思想,支持多种经典的访问控制方案,如基于角色的访问控制 RBAC、基于属性的访问控制 ABAC 等。
主要特性:
1.支持自定义请求的格式,默认的请求格式为{subject, object, action};
2.具有访问控制模型 model 和策略 policy 两个核心概念;
3.支持 RBAC 中的多层角色继承,不止主体可以有角色,资源也可以具有角色;
4.支持超级用户,如 root 或 Administrator,超级用户可以不受授权策略的约束访问任意资源;
5.支持多种内置的操作符,如 keyMatch,方便对路径式的资源进行管理,如 /foo/bar 可以映射到 /foo*

1.安装和使用测试
英文ok 可以官网https://python.ctolib.com/casbin-pycasbin.html 了解一下,或者找个博客https://blog.csdn.net/byywcsnd/article/details/86644190了解一下,安装使用测试还是比较简单的,熟悉python的同学按照文章中的步骤做就行了

2.关于持久化
按照上面链接的文章使用会发现如果调用pycasbin 接口增加删除policy然后保存policy(有自动保存选项),下次再次调用,之前增加或者删除的policy效果无效,查看原来导入 policy对应的文件内容没有变化,查看官方文档发现原来为了保持casbin库的轻量级和灵活性,持久化(保存功能)只提供了虚接口,具体实现需要安装或者自己实现对应的adapter

3.adapter的作用和实现方法
adapter的最主要作用
1.提供把文件或者数据库中的policy信息读取解析导入casbin 中的policy的方法
2.提供把casbin中的policy 存入文件或者数据库中的方法
所以自己实现的adapter只要实现有这两个功能的就行了
class MAdapter(persist.Adapter): #定义一个python 类 MAdapter继承 persist.Adapter这个类,我们看着这个类

    `class Adapter:
"""the interface for Casbin adapters."""
def load_policy(self, model):
    """loads all policy rules from the storage."""
    pass
def save_policy(self, model):
    """saves all policy rules to the storage."""
    pass
def add_policy(self, sec, ptype, rule):
    """adds a policy rule to the storage."""
    pass
def remove_policy(self, sec, ptype, rule):
    """removes a policy rule from the storage."""
    pass`

可以看出这个基类有方法load_policy,和save_policy,对应上面这个adapter最主要的两个作用,我们按照要求重写这两个方法就行了

由于我的python语法和一些常见的python方法使用不熟练所以做了一个简单的基于json文件的adapter(demon级别只少没有错误异常检测 当policy信息量大的时候保存性能没有考虑),就当抛转作用,大家可以简单参考下写出基于其它的各种文件类型和数据库类型的adapter

4.代码实现和测试

自己写的adapter文件mJsonAdapter.py

import casbin
import json
import os
from casbin import persist

class CasbinRule(object):
    #PType=''
    #v0=''
    #v1=''
    #v2=''
    #v3=''
    #v4=''
    #v5=''
    __tablename__ = "casbin_rule"
    def __init__(self,PType_='',v0_='',
                 v1_='',v2_='',v3_='',
                 v4_='',v5_=''):
        self.PType=PType_
        self.v0=v0_
        self.v1=v1_
        self.v2=v2_
        self.v3=v3_
        self.v4=v4_
        self.v5=v5_

    def load(self):
        text = self.PType
        if self.v0!='':
            text = text+', '+self.v0
        if self.v1!='':
            text = text+', '+self.v1
        if self.v2!='':
            text = text+', '+self.v2
        if self.v3!='':
            text = text+', '+self.v3
        if self.v4!='':
            text = text+', '+self.v4
        if self.v5!='':
            text = text+', '+self.v5
        return text

    def __repr__(self):
        return '<CasbinRule :"{}">'.format(str(self))

class MAdapter(persist.Adapter):

    pfpath='none.json'
    storeJs=json.loads("{}")
    def __init__(self,  policyFilePath):
        self.pfpath=policyFilePath
        
    def load_policy(self, model):
        fd=open(self.pfpath,mode='r')
        str=fd.read()
        fd.close()
        #print (str)
        self.storeJs=json.loads(str)

        casbinRuleStrct = []
        for item in self.storeJs:
            cr=CasbinRule(item['PType'],
                          item['V0'],item['V1'],
                          '','',
                          '', '')
            if item.get('V2'):
                cr.v2=item['V2']
            if item.get('V3'):
                cr.v2=item['V3']
            if item.get('V4'):
                cr.v2=item['V4']
            if item.get('V5'):
                cr.v2 = item['V5']
            print (cr.load())
            persist.load_policy_line(cr.load(),model)

    def _save_policy_line(self, ptype, rule):
        csbr = CasbinRule()
        csbr.PType=ptype
        if len(rule) > 0:
            csbr.v0 = rule[0]
        if len(rule) > 1:
            csbr.v1 = rule[1]
        if len(rule) > 2:
            csbr.v2 = rule[2]
        if len(rule) > 3:
            csbr.v3 = rule[3]
        if len(rule) > 4:
            csbr.v4 = rule[4]
        if len(rule) > 5:
            csbr.v5 = rule[5]
        self.saveCasbinRule(csbr)
    def saveCasbinRule(self,casbinRule):
        if(casbinRule.PType==''):
            return False
        js=json.loads("{}")
        js["PType"]=casbinRule.PType
        if(casbinRule.v0!=''):
            js['V0']=casbinRule.v0
        if(casbinRule.v1!=''):
            js['V1']=casbinRule.v1
        if(casbinRule.v2!=''):
            js['V2']=casbinRule.v2
        if(casbinRule.v3!=''):
            js['V3']=casbinRule.v3
        if(casbinRule.v4!=''):
            js['V4']=casbinRule.v4
        if(casbinRule.v5!=''):
            js['V5']=casbinRule.v5
        flag = 0
        for item in self.storeJs:
            if (item==js):
                flag=1
                break
        if (flag==0):
            self.storeJs.append(js)


    def save_policy(self, model):
        '''
        implementing add Interface for casbin \n
        save the policy in mongodb \n
        '''
        for sec in ["p", "g"]:
            if sec not in model.model.keys():
                continue
            for ptype, ast in model.model[sec].items():
                for rule in ast.policy:
                    self._save_policy_line(ptype, rule)
        fd = open(self.pfpath, mode='w+')
        fd.write(json.dumps(self.storeJs))
        print (json.dumps(self.storeJs))
        fd.close()
        return True

    def add_policy(self, sec, ptype, rule):
        """add policy rules to mongodb"""
        self._save_policy_line(ptype, rule)

    def remove_policy(self, sec, ptype, rule):
        """delete policy rules from mongodb"""
        pass

    def remove_filtered_policy(self, sec, ptype, field_index, *field_values):
        """
        delete policy rules for matching filters from mongodb
        """
        pass


model配置文件    rbac_model.conf
1
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act


policy导入和保存的文件 rbac_policy.json

[{"PType": "p", "V0": "alice", "V1": "data1", "V2": "read"}, 
    {"PType": "p", "V0": "bob", "V1": "data2", "V2": "write"},
     {"PType": "p", "V0": "data2_admin", "V1": "data2", "V2": "read"}, 
     {"PType": "p", "V0": "data2_admin", "V1": "data2", "V2": "write"},
      {"PType": "g", "V0": "alice", "V1": "data2_admin"}, 
 {"PType": "p", "V0": "alice", "V1": "data2", "V2": "write"}]


测试代码文件 jsonAdapterTest.py

import casbin
import mJsonAdapter

from  mJsonAdapter import  MAdapter        

adapter=MAdapter('rbac_policy.json') 

e=casbin.Enforcer('rbac_model.conf',adapter,True)

f=e.enforce('ywh','data','read')
e.add_policy('ywh','data','read') #'ywh','data','write'
e.save_policy()
if f:
    print ("true")
else:
    print ("false")


测试方法很简单,因为配置文件中刚开始没有 ‘ywh’,‘data’,'read’这个policy信息,第一次执行打印是false,关闭程序再次执行会发现打印true,同时会发现文件rbac_policy.json内容改变了.
已经通过本人测试,基于json文件adapter 已经简单实现,这只是一个简单版本,提供一下casbin的adapter的实现思路

    [参考](https://python.ctolib.com/casbin-pycasbin.html)
    [参考](https://casbin.org/docs/en/adapters)
    [参考](https://blog.csdn.net/byywcsnd/article/details/86644190)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值