已经 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. Java如何检查线程是否停止?

    在Java编程中,如何检查线程是否停止? 以下示例演示如何通过使用isAlive()方法来检查线程是否已停止. // from W w w .Y I I b AI.c o M package com. ...

  2. Python——os(一)进程参数

    python的os模块提供了一种使用操作系统相关函数的通用手段,如果只是想读或写文件请移步 open(),向操作路径请查阅 os.path 模块,如果想要读取命令行中所有文件里的所有行请查阅 file ...

  3. c# 递归函数使用案例

    /// <summary> /// 递归查询 /// </summary> /// <param name="groupID"></par ...

  4. 架构师素养及从小菜进阶架构(CTO)的书籍【转】

    CTO要了解无线技术/搜索/大数据/数据库等. -- 通常定义架构有几个层次,这包括业务架构.产品架构.应用架构和技术架构: 1.业务架构:描述一个企业围绕一个行业做了哪些业务,例如支付行业的收单.退 ...

  5. MacOS下MySQL配置

    先去官网下载一个 MySQL for mac http://www.cnblogs.com/xiaobo-Linux/ 命令行运行终端,运行下面两条命令: 1 2 alias mysql=/usr/l ...

  6. 带你玩转Eclipse项目转成AndroidStudio项目

    随着Android对Eclipse开发工具的淘汰,越来越多的公司使用AndroidStudio进行相应的Android开发工作.如此,原来用Eclipse开发的项目,怎么导入到AndroidStudi ...

  7. UFLDL教程练习(exercise)答案(2)

    主成分分析与白化,这部分很简单,当然,其实是用Matlab比较简单,要是自己写SVD分解算法,足够研究好几个月的了.下面是我自己实现的练习答案,不保证完全正确,不过结果和网站上面给出的基本一致. 1. ...

  8. Thinkphp5笔记五:配置data文件夹

    如果你看项目下的各种文件,有种乱七八糟的感觉的话,你就可以进行以下配置. 配置data文件夹的,整理各种文件,让看起来舒服些. 一.设置runtime文件夹 index.php define('RUN ...

  9. 一款基于 Android 开发的离线版的 MM 图片浏览 App

    一款离线版的 MM 图片浏览 App,有点类似掌上百度的图片专栏应用.图片采用瀑布流展示方式,点击图片集,支持左右手势滑动切换图片:支持放大缩小功能. 实现功能:1)图片完全离线,不耗个人 GPRS ...

  10. level 6 - unit 2 - 情态动词May

    情态动词May 正式的请求/许可 意思为可以 例如我们在机场候机室听广播的时候,在播报航班前经常听到: may i have your attention ,please ! (请注意听) 在机场过安 ...