已经 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 设计权限模块的更多相关文章

  1. 基于ASP.Net Core开发一套通用后台框架记录-(数据库设计(权限模块))

    写在前面 本系列博客是本人在学习的过程中搭建学习的记录,如果对你有所帮助那再好不过.如果您有发现错误,请告知我,我会第一时间修改. 前期我不会公开源码,我想是一点点敲代码,不然复制.粘贴那就没意思了. ...

  2. 解析大型.NET ERP系统 权限模块设计与实现

    权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...

  3. 权限模块_整体方案说明_设计实体&映射实体_实现初始化权限数据的功能

    权限模块_整体方案说明 要点说明 权限就是控制功能的使用(功能对应着URL). 对功能的控制就是对URL的访问控制. 在我们的程序中,一个功能对应一个或两个URL: 1,例如列表或删除功能,只对应一个 ...

  4. Web应用程序系统的多用户权限控制设计及实现-权限模块【10】

    前五章均是从整体上讲述了Web应用程序的多用户权限控制实现流程,本章讲述Web权限管理系统的权限配置模块.页面模块涉及到的数据表为权限表.权限配置模块是按照用户组和页面,栏目结合组成的.通过配置一个用 ...

  5. 图形数据库Neo4J简介

    最近我在用图形数据库来完成对一个初创项目的支持.在使用过程中觉得这种图形数据库实际上挺有意思的.因此在这里给大家做一个简单的介绍. NoSQL数据库相信大家都听说过.它们常常可以用来处理传统的关系型数 ...

  6. nopcommerce之权限模块

    这篇文章简单介绍一下nopcommerce的权限模块,nopcommerce里面的权限设计相对比较简单,主要针对后台的action和前台的是否显示(比如产品.品牌等),虽然简单但是应付一般的项目应该没 ...

  7. [转]nopcommerce之权限模块

    本文转自:http://www.nopchina.net/category/%E6%9E%B6%E6%9E%84.html 这篇文章简单介绍一下nopcommerce的权限模块,nopcommerce ...

  8. 从零开始编写自己的C#框架(18)——Web层后端权限模块——菜单管理

    从本章开始,主要讲解的是页面中对框架相关功能的调用方法,比如列表页面(又分为有层次感列表和普通列表).编辑页面.多标签页面等,只要熟悉了这些函数的使用方法,那么开发起来就会很便捷了. 1.如图先创建菜 ...

  9. SharePoint 2013 单一页面赋设计权限

    本文介绍SharePoint的使用中,断开单一页面权限,给用户编辑权限以及操作中遇到的问题,希望给相关需要的人一个参考. 1.首先进入页面库,找到我们的页面,进入共享,如下图: 2.在弹出的窗口中选择 ...

随机推荐

  1. 性能优化系列二:JVM概念及配置

    一.虚拟机组成 虚拟机主要由三部分组成:编译器(执行引擎),堆与栈. 1. 编译器 编译器分为即时编译器与解释器. 即时编译器将代码编译成本地代码存于code区.因此它快,但它有内存限制! 解释器逐行 ...

  2. SQLException: Column count doesn't match value count at row 1

    INSERT INTO table_name(col_name1, col_name2, col_name3) VALUES('value1','value2'); 语句中,前后列数不等造成的 转自: ...

  3. mysql字段类型对应javabean属性

    来吧 我们一起看下图,就能明白了.

  4. C# webbrowser判断页面是否加载完毕

    private void Form1_Load(object sender, EventArgs e) { webalipay.Url = new Uri("https://authzth. ...

  5. Apache TomEE 入门指南

    介绍 Apache TomEE(发音同“tommy”)是一个新的JavaEE服务器,由Apache软件基金会开发,你大概能够从它的名字猜到,它是从Tomcat而来, 同时加入的JavaEE的特征:To ...

  6. JUnit 3一个例子就懂

    JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture f ...

  7. 【WP8】WP8调用官方API使用LED灯

    在WP7中没有相关的API可以直接使用摄像头的LED等,只能通过录像时打开LED等来使用,在WP8中添加了相关的调用接口,可以方便的使用LED灯,并且支持后台,废话不多说,直接上代码 1.在 WMAp ...

  8. iview 下拉刷新loadTop报错解决

    <div class="noData" v-if="lifeList.length==0"> <img src="../assets ...

  9. apt 之 最强技能:【欺骗】,文雅点【偷梁换柱】!

    apt这种软件包管理系统,有个最大特点是:只照本宣科,而不管实际情况. 所以,我们用户就可以利用这一点,来欺骗它,达到我们的目的. ------------------------------好了,现 ...

  10. php解析mpp文件

    php没有找到相应的包 Java的mpxj可以实现 所以借助JavaBridge.jar 1.安装jdk,设置环境变量(我的版本jdk1.8.0_131) 2.下载mpjx 在http://www.m ...