网关动态数据级权限处理

Posted by Coding Ideal World on November 4, 2022

背景

在 “基于APISIX的ABAC模型鉴权插件开发: http://idealworld.group/2021/09/03/apisix-plugin-development/” 中简单描述过数据级权限处理的方案。对应的完整代码见: https://github.com/ideal-world/bios/tree/main/core/gateway/apisix/apisix/plugins

在这个方案的简化描述是:有一个需要鉴权的URI集合,不在该集合中的请求直接放行,命中该集合的请求要进一步比对Token或是AkSk认证后的请求者信息是否在允许,如果允许则放行,反之拒绝。

该URI集合简化后的格式是: <带模糊匹配的URI Path+Query> <操作方法> <允许的请求信息>

以知识库为例:

/kb/k1/**           GET     "app":"app1"    # k1的知识库所有app1的应用用户都可以查看
/kb/k1/cate1/**     GET     "group":"dev"   # 但是k1/cate1的目录只有开发部门(group=dev)的人可以查看
/kb/k1/cate1/**     ALL     "role":"admin"  # k1/cate1的目录有管理员角色(role=admin)的人可以有所有操作

如上所示,鉴权时优先匹配具象化的URI,再逐步泛化。

问题

知识库有一个需求是: 要可以编辑、删除自己创建的文档 。从统一的鉴权角度来看,可以添加如下规则:

/kb/k1/cate1/doc1   ALL     "account":"user1"  # doc1由user1创建,故添加user1对doc1的所有操作权限

但是这样的规则会导致一个问题: 如果知识库的文档数量很多,那么就需要为每个文档都添加一条规则 。这会导致规则数量过多,且难以维护。并且数据权限不限于知识库,还有其他的应用,如:文件管理、工单系统等等。

解决

为了解决上述问题,可以引入动态权限,大概逻辑如下:

  1. 由网关(APISIX可以提供脚本执行能力)或是认证组件提供签名接口,实现对原始文本加密签名,该接口只可内部访问

  2. 调用签名接口,传入 <Current Method>+<Current Path+Sorted Query>+<Allow AccountId/AppId/RoleId/……> 返回签名

  3. 在目标URI的Query中加上类似 dynamic_perm=<ACC/APP/ROLE/……>:<签名> , ACC表示匹配账号,APP表示匹配应用,……

  4. 网关收到请求后先执行原先的鉴权逻辑,如果鉴权失败,再根据Query中的动态权限进行鉴权,调用验签接口,传入 <Request Method>+<Request Path>+<Request Sorted Query>+<Request AccountId/AppId/RoleId/……> 与Query中的动态权限进行比对,如果相同则去除该Query键值后放行,否则拒绝

示例:

接上示例,调用签名接口,生成doc1文档的访问签名, 请求``GET+/kb/k1/cate1/doc1+user1``, 返回如08cab464dfc098856c19b11c26a0d309的签名。

生成可访问的URI ``/kb/k1/cate1/doc1?dynamic_perm=ACC:08cab464dfc098856c19b11c26a0d309`` 。

当user1访问该URI时,网关会先执行原先的鉴权逻辑,显然这个鉴权会失败(因为匹配到GET /kb/k1/cate1/** 路由,不符合要求),此时再执行动态权限鉴权,调用签名接口,使用当前的请求信息,将返回的签名与dynamic_perm比对,比对成功,去除dynamic_perm后放行。

当user2访问该URI时,使用当前的请求信息签名后与dynamic_perm比对,由于用户名不同,比对失败,请求拒绝。

当user1访问 ``/kb/k1/cate1/doc2?dynamic_perm=08cab464dfc098856c19b11c26e0b309`` 尝试水平越权时,使用当前的请求信息与dynamic_perm比对,由于URI路径不同,比对失败,请求拒绝。

当user1访问 ``/kb/k1/cate1/doc1?dynamic_perm=xxx`` 尝试破解时,签名不合法,比对失败,请求拒绝。

综上,此方案可以比较好的解决需要根据创建者、归属应用、角色等特征实现数据级(记录级)统一鉴权处理的问题。