在系统中,可能存在受限制的数据 . 有时,应根据用户或组成员身份轻松限制或授予对特定实体的访问权限 .
在微服务架构中实现这一点的最佳方法是什么?
#1
访问控制,管理权限等是微服务器本身的责任吗?开发人员必须为每项服务实现访问控制,存储和更新权限 . 似乎不是非常强大且容易出错的方法 .
#2
创建专用的微服务处理权限管理?其他微服务器将调用此服务,以在返回结果之前检查每个实体和过滤实体的访问权限 . 集中式权限存储和管理是一个优势,但微服务必须为每个实体调用“权限服务”,以检查可能对性能产生负面影响的访问权限 . 开发人员仍然必须将访问检查集成到他们的服务中,这会留下错误的空间 .
#3
使API网关或服务网格的访问控制责任 . 可以考虑一种自动过滤所有服务响应的实现 . 但在微服务返回实体列表的情况下,应检查每个实体的权限 . 仍然是潜在的性能问题 .
示例
考虑以下合成示例 . 医疗保健系统处理测试结果,X射线图像等 . Health 信息非常敏感,不应披露 .
测试结果仅适用于:
-
病人
-
医生
-
实验室
主治医生可能会将患者送到另一位专科医生处 . 新医生也应该可以访问测试结果 . 因此可以动态授予访问权限 .
因此,每个实体(例如,测试结果,X射线图像)都具有一组规则,允许用户和组访问它 .
想象一下,有一个名为“测试结果服务”的微服务处理测试结果 . 它应该负责访问控制,管理权限等吗?或者应该提取权限管理来分离微服务?
医疗保健系统也可以处理对医生的访问 . 有关患者就诊的信息应该可用于:
-
病人
-
医生
-
诊所接待员
这是需要基于用户或组成员身份的实体级访问限制的不同实体类型的示例 .
当需要实体级访问控制时,很容易想象更多的例子 .
3 回答
看起来安全性是业务逻辑的一部分 . 在两个例子中 . 然后安全性可能是数据方案的一部分 . 例如,
病人可以看到他的测试:
select * from test_result where patient_id=*patient_id*
医生可以从他的医疗部门看到所有的测试:
select * from test_result where branch_id=*doctor_branch*
我相信单独的MS用于访问控制是一个非常糟糕的主意,可能导致严重的性能问题 . 想象一下,实体访问为零的人试图每次都获取所有实体的情况:)你总是需要处理比实际需要更大的结果集 .
我来到以下通用解决方案 .
使用ACL安全模型 . 系统中的每个对象都具有关联的权限集 . 权限定义可以对对象执行的操作和操作 .
微服务负责实体级授权,并根据对象的权限过滤响应中的对象 .
中央访问控制服务负责创建,更新和删除系统中所有对象的权限 . 访问控制服务数据库是对象权限的主要存储 .
存储在微服务数据库中的权限使用event-carried state transfer与Access Control Service数据库同步 . 每次更改权限时,都会将事件发送到消息代理 . 微服务可以订阅这些事件以同步权限 .
API网关可用作附加保护层 . API网关可以直接调用访问控制服务(RPC)来检查响应对象的权限或加载最近撤销的权限 .
设计特点:
需要一种唯一标识系统中每个对象的方法(例如UUID) .
微服务中的权限同步最终是一致的 . 如果在消息代理和微服务之间进行分区,则不会同步权限 . 撤销权限可能是一个问题 . 该问题的解决方案是一个单独的主题 .
首先,拥有一个单独的(每个微服务)安全模型是一个非常糟糕的主意 . 它应该是单一的横切所有应用程序,因为它可以导致地狱与访问管理,权限授予和 mapping between entities in different microservices .
第二,我假设您理解错误 how to organize microservices..? 您应该将功能分解为微服务的原则:通过功能,按域等 . 查看单一责任,DDD和其他方法,帮助您实现MS的明确行为 .
所以,在最好的情况下,你应该:
选择正确的安全模型ABAC或RBAC - 还有很多其他选项,但看看你的例子我猜ABAC是最好的选择
为访问管理创建单独的MS - 此MS的主要职责是CRUD并分配组/角色/权限/属性给人民账户 .
创建单独的MS以提供 only permitted Health 信息 .
第三, how it works? :
使用ABAC,您可以设置分层角色/权限(基于组/属性) - 它可以帮助您解析谁被允许访问数据的委派路径
设置授权(通过auth-MS)并存储权限列表(在会话,cookie等)
检查给定用户对health-info-MS中所需数据的访问权限 . 这里我们有几个选项如何做到这一点:
如果使用memory-grid(hazelcast,coherence),则可以使用基于安全属性的谓词轻松创建过滤器 .
如果你正在使用SQL(hibernate,普通SQL等),你应该生成 return only permitted data 的查询 - 为 where clause 添加特定于安全性的标准
关于带有安全性检查的SQL查询的更多细节 where :在SQL执行之前(如果使用spring-method-auth hook很容易使用hibernate和spring),你应该解析分配给用户的所有权限 - 你可以通过调用来执行此操作AUTH-MS .
示例
我们为 TestResult 实体创建了CRUD权限 - VIEW,EDIT,DELETE .
DOCTOR可以看到任何TestResults的角色 - 因此,它具有VIEW权限
PATIENT角色只能看到他/她的TestResults
因此,您创建了一个业务规则,为每个业务角色(DOCTOR,PATIENT,LAB等)提供正确的 where clause ,最后SQL请求如下:
对于已分配VIEW权限的患者:
对于尚未分配VIEW权限的患者:
注意:在业务规则中,我们可以添加1 = 1或1!= 1来允许/限制查询结果