你应该知道的数仓安全:都是同名 Schema 惹的祸
本文分享自华为云社区《你应该知道的数仓安全——都是同名Schema惹的祸》,作者: zhangkunhn 。
典型场景
经常遇到小伙伴问到:
我是管理员账号,怎么还没有权限?
管理员给我赋权了啊,怎么还没有权限?
当小伙伴询问的时候,我第一时间就会想到都是用户同名 Schema 惹的祸。
同名 Schema 是私有 Schema
我们知道,CREATE USER 语法在创建用户的同时会在当前数据库中创建一个与用户同名的 SCHEMA。这个 Schema 很特殊,只有两种用户能在这个 Schema 下面创建表、视图、函数等对象:
用户自己
管理员
然而,不管谁创建的,对象的所有者(Owner)都是用户自己。基于这个事实,我们可以称用户同名 Schema 为私有 Schema。私有表明了当前 Schema 的特殊性,在这个 Schema 下面的所有对象都是这个用户自己的,不管是谁创建的。
我们来看一个例子。数据库中有三个用户,如表所示。
使用管理员 dbadmin 执行以下 SQL:
可以看到:
系统管理员在普通用户同名 schema 下创建的对象,所有者为 schema 的同名用户
让我们来总结第一点:同名 Schema 是私有 Schema,这个 Schema 下面的所有对象的所有者都是用户自己,不管是谁创建的。管理员在私有 Schema 下创建的表等对象会发生 Owner 切换。
视图规则:按照 view 的 owner 做权限检查
再来谈视图和视图封装的基表的权限。视图对基表的权限检查是按照视图的 Owner 做权限检查。例如
create view v1 as select * from t1;
用户执行 select * from v1 时做权限检查分为两步:
首先检查当前用户对视图 v1 的 SELECT 权限;
然后检查视图 v1 的 owner 对基表 t1 的 SELECT 权限。
而不是直接检查当前用户对基表 t1 的 SELECT 权限。
总结第二点:视图会按照视图的 Owner 对基表做权限检查。
私有 Schema 与视图规则导致莫名其妙的权限报错
由于私有 Schema 会造成 Owner 切换,而视图规则要求对基表按照视图 Owner 做权限检查。那么在私有 Schema 下面创建视图就会导致莫名其妙的现象:
私有 Schema + view 规则 --> 管理员无权限访问自己创建的视图。
我们以管理员用户在用户 ua 的私有 schema 下创建表 ta, 之后在用户 ub 的 schema 下创建了视图 vb, 视图 vb 的基表是 ua.ta。管理员执行对视图 vb 的查询,报错无权限。
对于这个莫名其妙的现象,我们仔细捋一捋其中的来龙去脉。
根据私有 Schema 切换 Owner 的法则,尽管是管理员创建的,ta 的 owner 切换到 ua, 同样 vb 的 owner 应该是 u2.
结合 view 规则,对基表按照视图 Owner 做权限检查,视图 vb 的 owner 对基表 ua.ta 是否具有 select 权限。视图 vb 的 owner 是 ub,而 ub 对 ua.ta 无 select 权限,因此查询报错。
权限报错消除
如何解决这种权限报错呢?从上述梳理中,其实已经明白了如何赋权来消除这种报错。那就是给视图的 owner 用户 ub 赋予基表 ua.ta 的 SELCT 权限:管理员或者用户 ua 执行下面的赋权语句即可。
有小伙伴 问了,我每次都这么仔细捋一捋,感觉很浪费时间,有没有简单的方法。答案是有的,只需从查询的权限报错着手,不需要每次都捋一捋。
我们当前的权限报错有着非常完备的提醒,会给用户显示如下提示:
SELECT permission denied to user “user_name” for relation “ schema_name.table_name“
可以看到,权限报错包括哪个权限、哪个用户、哪个 schema 的哪个对象。那么看到这个之后,可以直接找管理员或者 Owner 来执行授予操作就可以了。
对于上述报错,直接就对应到赋权语句:
grant SELECT on schema_name.table_name to user_name;
当然这个赋权跟我们前面的分析是殊途同归的。
现在来回想下,是不是一切都清晰了。那么我们再来看一遍示例。以管理员 dbadmin 执行以下 SQL 语句。
补充知识:
CREATE USER 语法在创建用户的同时会在当前数据库中,为该用户创建一个同名的 SCHEMA;其他数据库中,则不会创建同名的 SCHEMA;如果需要,可使用 create schema authorization user_name 语法,该语法会根据用户名来创建同名 schema。
为什么用户同名 Schema 这么特殊,别的 Schema 没有这些特点?因为:a) 在创建用户时同时创建了与用户同名的 Schema,并将 Schema 的 owner 设置为同名用户;b) 在创建对象时,如果创建对象的 schema 是用户同名 Schema,就会将对象的 Owner 切换为同名用户,而不是执行 SQL 语句的当前用户。
总结
遇到权限报错第一时间想到是否涉及同名 schema。同名 Schema 是用户的私有 Schema。私有 Schema 中所有的对象 Owner 都是用户自己,不管是谁创建的。在私有 Schema 中创建对象,对象 Owner 会切换到同名用户。视图规则是按照视图 Owner 来检查对基表的权限。由于私有 Schema 的 Owner 切换机制和视图规则导致了同名 Schema 的权限报错。根据报错的提示,授予用户相应的权限就可以解决权限报错问题。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/0577af13b83b9dc11593b8982】。文章转载请联系作者。
评论