权限控制系统基础
权限控制系统设计在OA系统,数据系统中其实都差不多,离不开三级体系设计: Role, User, Principal. 具体叫法在各个系统的实现上会有差别。
- Role : 多个User 属于一个Role,User 用于Role 的所有权限。
- User : 系统用户,User 一般我们会做登录鉴权,在权限控制体系中,一般都是用于获取Role 的相关信息
- Principal : 这个中文不知道怎么翻译,我的理解就是一个具体权限的描述,包括
<Role, Object, Privilege>
这样的三元组,表示某一角色,在某一实体上,对指定权限 Privilege 的描述。
权限体系的设计目标: 获取用户需要鉴权的行为需要的权限(List<Principal>
) 和 用户当前拥有的权限(List<Principal>
) 做比较,进行鉴权。
Spark SQL 数据权限控制设计
具体到Spark SQL中,数仓的权限控制,在Hive的MetaStore中已经存储。我们需要扩展Spark SQL的 QueryExecution
,在Spark SQL的AnalyzePlan之后,OptimzePlan之前(具体物理执行之前)进行权限校验即可。
- 获取系统用户, 这个主要通过
SparkContext
中的sparkUser
属性来表示,这个值通过系统环境变量SPARK_USER
来获取;如果环境变量为空,取当前程序的运行用户UserGroupInformation.getCurrentUser().getShortUserName()
- 根据
sparkUser
构造CatalogPrincipal<sparkUser, USER>
调用HiveClient.getRoleGrantsForPrincipal(CatalogPrincipal): Seq[CatalogRoleGrant]
方法,获取当前用户的 Role权限。 - 进入
checkPrivileges(plan, sparkSession.sessionState.catalog)
开始校验用户对 SparkPlan 中 Input 和 Output 类型数据实体的权限。
3.1 通过PrivilegesBuilder.build(sessionCatalog, plan)
返回Spark 中对 Input 和 Output 类型数据实体操作需要的权限
Operation2Privilege.getRequiredPrivs(hiveOpType, po, ioType)
获取对 po 对象操作需要的权限HiveClient.getPrivilegeGrants(privilegeObject, user, groupNames)
来获取user用户对指定的数据库或者表的拥有权限。在AuthorizationUtils.getPrivilegesFromMetaStore()
中默认如果当前用户就是表的创建者,增加OWNER权限, 如果是管理员的话,增加 Admin 权限。- 上面我们获取到了 requiredPrivs 和 availPrivs, 如果我们缺少 requiredPrivs 中的部分权限,则权限校验失败