微服务下的权限设计

OSC_RCurQr 发布于 2019/10/25 18:55
阅读 2K+
收藏 1

不知道大家怎么设计微服务下的权限的,很长时间了,一直没有找到很满意的答案。我的情况是这样的,还请大家帮忙出主意。

我情况如下:

1、目前系统中权限为分大类:系统权限(web操作的权限)和APP权限(手机APP操作权限)

2、每个权限又可以分为:功能权限和数据权限。 功能权限(比如菜单、按钮的显示与否),数据权限(查看本部门或下级部门等)

3、人员信息和权限等这些配置在一个微服务模块,而且是一个独立的数据库。

4、各子系统根据业务线拆成了不同的微服务模块,而且各自有独立的数据库,这里注意的是,与人员权限库不在同一个库里。

 

问题:

在子系统中,如果要查询某个用户能够查看的数据时,这里就无法通过关连权限表的方式。网上有很多方案,但基本上是不分库的,通过关联表的方式查询的。  但是我们系统是分库的,所以无法直接left join。

 当前处理方案是:通过远程调用的方式,查询出这个用户能够查看的部门的List, 然后再带入到sql语句中,通过in的方式查询。 但是这种方式是每个子系统,很多方法都要调用时都要写一段判断权限等级,然后查询list的代码。造成很多重复代码,而且效率也比较低。

请问大家在微服务的架构中,数据权限是如何设计的呢?

加载中
0
白天蓝草
白天蓝草

我认可这个处理方法。 

当前处理方案是:通过远程调用的方式,查询出这个用户能够查看的部门的List, 然后再带入到sql语句中,通过in的方式查询。 

1、权限控制,实质上就是sql的过滤。 所以逃不了 left join 方式的过滤或是in方式的过滤,这个必要条件。

针对你提出的问题:

2、重复代码:这个可以尝试进行抽象提取出通用代码,提出一定系统编程、数据库字段要求规定, 配合使用通用代码, 减少重复代码。

3、效率低:远程查询权限数据,这个作为不经常变更、且使用率高的数据,可以使用缓存,减少数据库交互。尝试在最终查询资源sql的过滤上进行SQL优化。

白天蓝草
白天蓝草
回复 @OSC_RCurQr : 我想的是, 这个问题在不离开关系型数据库的前提下,本质都是sql过滤,所以这个是绕不开的。服务拆分,是要损耗小部分性能(远程调用),换取更大性能的机会(支持多机部署的人海战术),如果不能接受这小部分性能损害,那就不用上微服务或这个服务不能拆分。
白天蓝草
白天蓝草
回复 @zhaobohao : 你这个回答,应该直接在问题下回复, 而不是在我的回答下评论。
OSC_RCurQr
OSC_RCurQr
我们目前就是这么做的。而且终于有人能明白我的意思了,知音啊!
zhaobohao
zhaobohao
1.这是标准的微服务拆分,将公用的服务放到微服务系统中去。代码重复的问题,你是否可以参考一个mybatis plus的sql fliter,可以根据配置 自动在你写的Sql里加where条件。 2.如果你的系统在多数据访问上没有限制的话,可以参考多数据源。在你的系统当中把权限数据源和业务数据源都 引入。
0
落舞者
落舞者

网关、oauth2

OSC_RCurQr
OSC_RCurQr
网关、oauth2,没有办法解决查询数据范围的要求。
Jerry_ZJL
Jerry_ZJL
别人问的是思路,你丢个框架出来
0
Kit_lee
Kit_lee

我觉得是你这边微服务拆分有问题,一些需要sql join的数据不应该分,就冗余一些字段记录,不要想什么数据库设计范式,互联网和分布式应用有时候不吃这一套。

如果硬是要分,还可以用视图方式将多个库(schema)的数据表连起来,当然如果你们的分库是不同的数据库实例就当没说吧。

我认为权限与数据的具体查询条件无关,系统定义的权限就是关注资源(方法、视图页面)的访问权限,有权限访问的方法里,即可根据当前用户的授权信息(role, premission等)过滤数据即可。那么剩下只需要考虑如何就为多个微服务间实现单点登入授权,这个框架有很多,例如oauth或者其他以令牌方式实现的SSO。具体可以看看spring-cloud-security

Kit_lee
Kit_lee
回复 @OSC_RCurQr : 资源表的数据为什么跟权限表关联查询?假设资源的访问通过一个微服务B,有三个角色去访问这些资源,微服务之间通过Oauth2进行授权,那当A服务调用B服务的API时,B服务通过Oauth拿到当前用户授权信息(角色及一些permission),B服务在公开的入口方法通过判断角色或permission再调用不同的私有子方法返回数据。
OSC_RCurQr
OSC_RCurQr
回复 @OSC_RCurQr : 有个错字,应该是不在一个库里。
OSC_RCurQr
OSC_RCurQr
像方法,视图等访问都实现了。现在主要就是数据范围的控制。就比如说领导查看所有部门的数据,经理只查看本部门的数据,员工只能查看本人的数据。 只能是通过sql语句来判断,问题就在于权限跟业务不在一个表里。
0
贝克街的天才

可以 独立出一个 会员服务  和 一个权限服务。

红薯官方
红薯官方
回复 @OSC_RCurQr : 基于RBAC权限控制设计,你可以增加一些特殊的权限资源配置用于控制数据可见范围,比如“是否可以管理本部门XX数据”,授权true则不限定查询条件UserId=currentUserId,否则将限定只能查询本人的数据。
贝克街的天才
回复 @OSC_RCurQr : 试试mycat 能不能解决你的问题。
OSC_RCurQr
OSC_RCurQr
已经独立出来了,但是像这种情况: 总经理只查看本部门的数据,员工只能查看本人的数据。 只能是通过sql语句来判断,问题就在于权限跟业务不在一个库里,无法直接left join查询。 不知道怎么做?
0
isscy
isscy

请问为何要抽出web和app两套不同的权限来?
以及数据权限是怎么控制的? 

0
温家阿宝
温家阿宝

你好,我也遇到了相同的问题,权限独立成了一个微服务,过滤数据权限用select in,由于我们业务比较复杂配置得也多,往往一个SQL会有几个select in,一个in的范围多的时候有上百个,导致性能异常低。

请问下你有找到合适的解决办法吗

 

0
喝假酒了
喝假酒了

自定义注解,切面实现中调用远程服务获取当前用户的数据权限标识(比如组织id:orgId),然后组装一段sql,大概是这个样子(org_id in (...) or user_id=xxx),orgId标识该用户有哪些数据权限,,userId标识没有组织的数据权限,但是属于自己的数据也能查看,,然后在service实现类方法上使用数据权限注解,将sql拼接上去,,如果你使用mybatisplus那就更方便了,直接apply就完事儿了
思路可以看看renren-security:https://gitee.com/renrenio/renren-security ,无非就是把他调用service的地方改成调其他服务,至于性能嘛,,鱼和熊掌不可兼得,要想多做点事儿肯定要付出点儿“小代价”

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部