ranger插件开发的上下两篇文章介绍了如何在ranger中支持一个新的服务,并开发对应的客户端插件。但知其然还要知其所以然,简单的几个接口调用的背后,其内部最终是如何进行权限校验的。本文就来简单聊聊其内部实现原理。
【插件中与策略相关的类】
从ranger的web控制台可以看出:
- 一个具体的服务,可能会有多个不同的策略仓库:资源的权限访问控制策略仓库(Access),结果的列访问控制策略仓库(Masking),结果的行访问控制策略仓库(Row Level Filter)
- 每个策略仓库都可以配置多条策略
-
每条策略又包含不同的策略条件
策略条件包括:
- 允许条件(Allow Conditions)
- 从允许条件中排除的条件(Exclude from Allow Conditions)
– 否决条件(Deny Conditions)
– 从否决条件中排除的条件(Exclude from Deny Conditions)
- 而这些策略条件都可以包含多个策略条目,每个策略条目由角色、用户、用户组、资源的访问类型组成。
如下图所示:
在ranger插件内部,有一系列相关的类对应这些信息。类图信息如下图所示:
-
ServicePolicies
服务的某个策略仓库的策略集合。
-
RangerPolicy
对应一条具体的策略,其中包含几个重要的类成员:
- resources:一个map表,key为资源名,value为RangerPolicyResource的实例对象,记录了该策略中包含的资源信息。
- policyItems:对应策略中允许条件中的策略条目集合
- denyPolicyItems:对应策略中否决条件的策略条目集合
- allowException:对应策略中允许条件中排除的条件的策略条目集合
- denyException:对应策略中否决条件中排除的条件的策略条目集合
注意:policyItems、denyPolicyItems、allowException、denyException是同一个类的不同实例对象。
-
RangerPolicyResource
对应一个具体的资源,其类成员value指示该资源的具体值列表。因为在web控制台中,同一个资源允许配置多个值。
-
RangerPolicyItem
对应一个具体的策略条目。其类成员users、groups、roles分别为用户、用户组、角色列表;access是一个RangerPolicyItemAccess实例对象的列表,表示该策略条目包含哪些资源访问类型;conditions是一个RangerPolicyItemCondition实例对象的列表,表示该策略条目包含哪些自定义条件策略。
-
RangerPolicyItemAccess
描述一个具体的资源访问类型。其类成员type表示访问类型。
-
RangerPolicyItemCondition
自定义策略条件的策略条目。
【鉴权流程中的相关类】
上面几个类只是对权限相关的策略进行了描述,而仅靠这些描述,还不足以完成资源权限的访问控制。因此,在ranger插件的内部实现中,包含一个策略引擎来驱动完成具体的资源访问控制逻辑。
插件中的鉴权逻辑从上到下可以分为这么几层,每一层都对应一组相关的接口和实现类。
-
RangerBasePlugin
资源访问控制的入口,最终需要调用类的isAccessAllowed接口进行权限校验
-
RangerPolicyEngineImpl
策略引擎的具体实现类,实现了RangerPolicyEngine接口
-
RangerEngine
包含服务的各个策略仓库,并提供接口按类型、Tag、Zone获取对应的策略仓库。
-
RangerPolicyRepository
代表一个策略仓库,通常只有一个类实例。但是对于ranger的一些高级用法:SecurityZone、基于tag的权限校验,则会有对应的类实例。
-
RangerPolicyEvaluator
策略匹配表达式的抽象类,从策略的维度提供鉴权计算接口,内部通过调用不同的策略条目匹配表达式类实例的接口完成具体的鉴权逻辑。
-
RangerPolicyItemEvaluator
策略条目表达式的抽象类,从策略条目的维度提供鉴权计算接口。
【鉴权的处理流程】
鉴权之前,插件先需要初始化,初始化时会启动一个线程定期从ranger服务端拉取策略,每次拉取策略本质上是发送一个rest请求,ranger服务端收到请求后,将具体服务的所有策略信息按json格式组织发送给插件。
插件收到请求相应后,在本地磁盘缓存的同时,在内存中构造出上面提到的相关类的对象实例。
策略在本地保存后,其鉴权的流程如下图所示:
- 在我们的代码中只需要调用RangerBasePlugin提供的isAccessAllowed、evalDataMaskPolicies、evalRowFilterPolicy这些方法触发进行权限校验。
- 在RangerBasePlugin的这些方法内部中,统一调用RangerPolicyEngineImpl的evaluatePolicies方法进行权限校验。不同的入口,对应不同的策略类型(POLICY_TYPE_ACCESS、POLICY_TYPE_DATAMASK、POLICY_TYPE_ROWFILTER)
- 通过policyengine接口获取正确的策略仓库。
- 从策略仓库中,根据请求资源、获取匹配的policyEvaluator列表。
- 对policyEvaluator列表一次调用evaluator进行权限匹配,一旦有确定结果则返回(终止循环,不进行后续的调用)
- 在policyEvaluator的evaluator接口中,遍历不同策略条件中的策略条目,并调用对应接口(isMatch),获取与访问动作匹配的策略条目,然后判断是否允许访问,最终得出权限校验结果。
小结一下:本文主要介绍了ranger插件中策略与鉴权相关的实现类,以及鉴权的逻辑流程。在源码的研究过程中,发现其实还有很多小细节,这里没有展开说明。例如,包含同一个资源的多个策略如何进行排序,同一个策略中的不同策略条件如何相互作用(允许条件、否决条件、排除条件)等等。这些内容对整体的流程不构成影响,后续再抽空补充。
本文转载自hncscwc,原文链接:https://www.modb.pro/db/131555。