用图形数据库Neo4j 设计权限模块
已经 SpringSecurity 在几个项目中 实现权限模块,对于数据库,也是思考了不少,从Mysql 到 mongodb 都不是特别满意,
在Mysql中,如果权限相对简单,那么还能接受,如果稍微复杂一点,那么就有点恶心了.
在最近一个项目中,使用mongodb 做多租户的权限,实现起来简单明了了很多,关系也没有那么绕,但是毕竟非关系型数据库,没有级联操作,修改删除,可能会留下一些脏数据,
虽然Spring Data Mongodb 有对象持久化的监听事件,但是依然需要手动编写一些处理过期,以及脏数据的代码.
最近发现有个东西叫做Neo4j,好说了,这个特别关系的数据库,第一个想法,就是很适合做这种关系复杂的权限模块.
这里模拟一个基于多租户的权限设计
1:租户依赖系统权限,根据租户付费套餐不一,拥有不一样的权限,但不可越过系统权限边界(废话)
2:租户可以创建角色(角色不可以越过租户权限的边界)
3:租户创建的用户,可以有多个角色(权限基于租户的权限,多角色叠加)
首先用kubernetes 启动一个neo4j
neo4j.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: neo4j
namespace: k8s-springcloud
spec:
replicas: 1
selector:
matchLabels:
app: neo4j
template:
metadata:
labels:
app: neo4j
spec:
nodeName: k8s-node-0
terminationGracePeriodSeconds: 60
hostNetwork: true
containers:
- name: neo4j
image: 192.168.91.137:5000/neo4j
volumeMounts:
- name: data
mountPath: /data
- name: conf
mountPath: /var/lib/neo4j/conf
volumes:
- name: data
hostPath:
path: /mnt/gv0/k8s-springcloud/neo4j/data
- name: conf
hostPath:
path: /mnt/gv0/k8s-springcloud/neo4j/conf --- apiVersion: v1
kind: Service
metadata:
name: neo4j
namespace: k8s-springcloud
labels:
app: neo4j
spec:
type: NodePort
ports:
- name: api
port: 7687
nodePort: 7687
targetPort: 7687
- name: web
port: 7474
nodePort: 7474
targetPort: 7474
kubectl create -f neo4j.yaml
首先看看系统总权限(假设系统有两个模块:订单(增删改查),库存(增删改查))

代码:
AclTenantModuleRelation sysModuleRelation = new AclTenantModuleRelation();
AclModule orderModule = new AclModule();
orderModule.setCode("AUTH_ORDER");
orderModule.setName("订单管理");
AclMethod orderQuery = new AclMethod("AUTH_ORDER_QUERY", "查询订单");
orderQuery.setAclModule(orderModule);
AclMethod orderDelete = new AclMethod("AUTH_ORDER_DELETE", "删除订单");
orderDelete.setAclModule(orderModule);
AclMethod orderEdit = new AclMethod("AUTH_ORDER_EDIT", "编辑订单");
orderEdit.setAclModule(orderModule);
AclMethod orderAdd = new AclMethod("AUTH_ORDER_ADD", "新增订单");
orderAdd.setAclModule(orderModule);
orderModule.setAclMethods(new HashSet<>(Arrays.asList(orderAdd, orderDelete, orderEdit, orderQuery)));
aclMethodService.saveAll(orderModule.getAclMethods());
aclModuleService.save(orderModule);
sysModuleRelation.setTenantId(TenantInfo.SYSTEM_TENANT_ID);
AclModule stockModule = new AclModule();
stockModule.setCode("AUTH_STOCK");
stockModule.setName("库存管理");
AclMethod stockQuery = new AclMethod("AUTH_STOCK_QUERY", "查询库存");
stockQuery.setAclModule(stockModule);
AclMethod stockDelete = new AclMethod("AUTH_STOCK_DELETE", "删除库存");
stockDelete.setAclModule(stockModule);
AclMethod stockEdit = new AclMethod("AUTH_STOCK_EDIT", "编辑库存");
stockEdit.setAclModule(stockModule);
AclMethod stockAdd = new AclMethod("AUTH_STOCK_ADD", "新增库存");
stockAdd.setAclModule(stockModule);
stockModule.setAclMethods(new HashSet<>(Arrays.asList(stockAdd, stockDelete, stockEdit, stockQuery)));
aclMethodService.saveAll(stockModule.getAclMethods());
aclModuleService.save(stockModule);
sysModuleRelation.setAclModules(new HashSet<>(Arrays.asList(orderModule,stockModule)));
sysModuleRelation.setAclMethods(new HashSet<>(Arrays.asList(orderAdd, orderDelete, orderEdit, orderQuery,stockAdd, stockDelete, stockEdit, stockQuery)));
来设置一个租户,给租户分配一些权限
/**
* User: laizhenwei
* Date: 2018-03-25 Time: 15:09
*/
@Test
public void initTenantModule(){
AclModule aclModule = aclModuleService.findTop1ByCode("AUTH_STOCK");
TenantInfo tenantInfo = new TenantInfo("租户1");
tenantInfoService.saveAndFlush(tenantInfo);
Iterator<AclMethod> aclMethodIterator = aclModule.getAclMethods().iterator();
AclTenantModuleRelation aclTenantModuleRelation = new AclTenantModuleRelation(tenantInfo.getId(),new HashSet<>(Arrays.asList(aclModule)),new HashSet<>(Arrays.asList(aclMethodIterator.next(),aclMethodIterator.next())));
aclTenantModuleRelationService.save(aclTenantModuleRelation);
}
CQL
match (tenantModule:AclTenantModuleRelation)-[:HAS_OF]->(atMethod:AclMethod) where tenantModule.tenantId = '40288183625d600c01625d6032fa0000' match (atMethod)-[:DEPEND_OF]->(module:AclModule) return atMethod,module

模拟租户创建一个角色
/**
* User: laizhenwei
* Date: 2018-03-25 Time: 15:09
*/
@Test
public void addRole(){
Optional<AclTenantModuleRelation> aclTenantModuleRelationOptional = aclTenantModuleRelationService.findById(212l);
aclTenantModuleRelationOptional.ifPresent(aclTenantModuleRelation -> {
AclRole aclRole = new AclRole();
aclRole.setTenantId("40288183625d600c01625d6032fa0000");
aclRole.setCode("ROLE_NORMAL");
aclRole.setName("普通用户");
aclRole.setAclTenantModuleRelation(aclTenantModuleRelation);
Iterator<AclModule> aclModuleIterator = aclTenantModuleRelation.getAclModules().iterator();
AclModule aclModule = aclModuleIterator.next();
Iterator<AclMethod> aclMethodIterator = aclTenantModuleRelation.getAclMethods().iterator();
aclRole.setAclModules(new HashSet<>(Arrays.asList(aclModule)));
aclRole.setAclMethods(new HashSet<>(Arrays.asList(aclMethodIterator.next())));
aclRoleService.save(aclRole);
});
}
CQL
match (t:AclTenantModuleRelation)-[:HAS_OF]->(method:AclMethod) match(r:AclRole)-[:HAS_OF]->(rmethod:AclMethod) where r.tenantId='40288183625d600c01625d6032fa0000' and r.code='ROLE_NORMAL' and method=rmethod match(method)-[:DEPEND_OF]->(module:AclModule) return method,module
结果(左),点击展开关系(右)


用户与角色,不再做演示.
想想SpringSecurity 的角色继承的配置格式为 role1>role2>role3 这种方式,用neo4j,是否很好实现动态角色继承?
用图形数据库Neo4j 设计权限模块的更多相关文章
- 基于ASP.Net Core开发一套通用后台框架记录-(数据库设计(权限模块))
写在前面 本系列博客是本人在学习的过程中搭建学习的记录,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 前期我不会公开源码,我想是一点点敲代码,不然复制.粘贴那就没意思了. ...
- 解析大型.NET ERP系统 权限模块设计与实现
权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...
- 权限模块_整体方案说明_设计实体&映射实体_实现初始化权限数据的功能
权限模块_整体方案说明 要点说明 权限就是控制功能的使用(功能对应着URL). 对功能的控制就是对URL的访问控制. 在我们的程序中,一个功能对应一个或两个URL: 1,例如列表或删除功能,只对应一个 ...
- Web应用程序系统的多用户权限控制设计及实现-权限模块【10】
前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的权限配置模块.页面模块涉及到的数据表为权限表.权限配置模块是按照用户组和页面,栏目结合组成的.通过配置一个用 ...
- 图形数据库Neo4J简介
最近我在用图形数据库来完成对一个初创项目的支持.在使用过程中觉得这种图形数据库实际上挺有意思的.因此在这里给大家做一个简单的介绍. NoSQL数据库相信大家都听说过.它们常常可以用来处理传统的关系型数 ...
- nopcommerce之权限模块
这篇文章简单介绍一下nopcommerce的权限模块,nopcommerce里面的权限设计相对比较简单,主要针对后台的action和前台的是否显示(比如产品.品牌等),虽然简单但是应付一般的项目应该没 ...
- [转]nopcommerce之权限模块
本文转自:http://www.nopchina.net/category/%E6%9E%B6%E6%9E%84.html 这篇文章简单介绍一下nopcommerce的权限模块,nopcommerce ...
- 从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理
从本章开始,主要讲解的是页面中对框架相关功能的调用方法,比如列表页面(又分为有层次感列表和普通列表).编辑页面.多标签页面等,只要熟悉了这些函数的使用方法,那么开发起来就会很便捷了. 1.如图先创建菜 ...
- SharePoint 2013 单一页面赋设计权限
本文介绍SharePoint的使用中,断开单一页面权限,给用户编辑权限以及操作中遇到的问题,希望给相关需要的人一个参考. 1.首先进入页面库,找到我们的页面,进入共享,如下图: 2.在弹出的窗口中选择 ...
随机推荐
- C# 在托盘显示图标
//上面一行是主窗体InitializeComponent()方法中需要添加的引用 this.SizeChanged += new System.EventHandler(this.Form1_Siz ...
- MySQL中information_schema是什么
转载地址:http://help.wopus.org/mysql-manage/607.html 大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_sche ...
- 推荐个office能在线预览的插件
1.chrome office viewer 这个可以离线使用 2.微软 office web app 可以使用微软在线服务器或则自己搭建服务器 有兴趣的朋友百度一下具体操作方法
- ICMP Ping模版实现对客户端网络状态的监控
Zabbix使用外部命令fping处理ICMP ping的请求,fping不包含在zabbix的发行版本中,需要额外去下载安装fping程序,安装完毕之后需要zabinx_server.conf中的参 ...
- excel做回归分析的应用【风控数据分析】
方法1 统计逻辑:统计一个loginname的所有去重的通讯录数C,统计这个Loginname对应的每个设备对应的通讯录c1,c2,c3…cn; X=(c1/c+c2/c+c3/c+….cn/ ...
- __setup、early_param的解析
内核初始化时根据字符串匹配获得相应的处理函数,查找的时候有些麻烦. 写个脚本对将内核中的__setup和early_param显式做了解析: __setup #! /bin/bash grep '\& ...
- tomcat设置debug模式
1.设置 编辑catalina.bat,在 rem Guess CATALINA_HOME if not definedset "CURRENT_DIR=%cd%"if not & ...
- Aspose------导出Excel
代码: /// <summary> /// 导出Excel /// </summary> /// <typeparam name="T">泛型类 ...
- 大杂烩 -- Iterator 和 Iterable 区别和联系
基础大杂烩 -- 目录 用Iterator模式实现遍历集合 Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构. 例 ...
- 8 -- 深入使用Spring -- 0...
要点梗概: 利用后处理器扩展Spring容器 Bean后处理器和容器后处理器 Spring3.0 的“零配置” 支持 Spring的资源访问策略 在ApplicationContext中使用资源 AO ...