你应该知道的数仓安全——默认权限实现共享schema

滞波迭代
• 阅读 1497
摘要: 一种典型客户场景是一些用户是数据的生产方,需要在schema中创建表并写入数据;而另一些用户是数据的消费方,读取schema中的数据做分析。使用Alter default privilege语法可以实现这种共享schema的权限管理问题。通过简单示例演示了Alter default privilege语法处理这种典型场景的细节和有效性。

前言

最近遇到一个客户场景,涉及共享schema的权限问题。场景简单可以描述为:一些用户是数据的生产方,需要在schema中创建表并写入数据;另一些用户是数据的消费方,读取schema中的数据做分析。对于该schema权限管理的一种实现方法是数据生产方在每次创建新表后告知管理员用户使用grant select on all tables in schema语法来授予消费方权限。这种方法有一定的局限性。如果生产方在schema下面又创建了一些新表,为了授权消费方使用这些新表还需要告知管理员用户再次使用grant select on all tables in schema来授权。有没有简单的应对方案?答案是肯定的,可以使用Alter default privilege。Alter default privilege用于将来创建的对象的权限的授予或回收。

你应该知道的数仓安全——默认权限实现共享schema

语法介绍

ALTER DEFAULT PRIVILEGES

 [ FOR { ROLE | USER } target_role [, ...] ]
 [ IN SCHEMA schema_name [, ...] ]
 abbreviated_grant_or_revoke;

其中abbreviated_grant_or_revoke子句用于指定对哪些对象进行授权或回收权限。对表授权语法是:

GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES }

 [, ...] | ALL [ PRIVILEGES ] }
 ON TABLES 
 TO { [ GROUP ] role_name | PUBLIC } [, ...]

参数说明

  • target_role
    已有角色的名称。如果省略FOR ROLE/USER,则缺省值为当前角色/用户。
    取值范围:已有角色的名称。
  • schema_name
    现有模式的名称。
    target_role必须有schema_name的CREATE权限。
    取值范围:现有模式的名称。
  • role_name
    被授予或者取消权限角色的名称。
    取值范围:已存在的角色名称。

详见https://support.huaweicloud.com/devg-dws/dws_04_0241.html

场景示例

testdb=# create user creator1 password 'Gauss_234';
CREATE USER
testdb=# create user creator2 password 'Gauss_234';
CREATE ROLE
testdb=# create user user1 password 'Gauss_234';
CREATE USER --创建共享schema,授予creator1和creator2创建权限,授予user1使用权限
testdb=# create schema shared_schema;
CREATE SCHEMA
testdb=> grant create, usage on schema shared_schema to creator1;
GRANT
testdb=> grant create, usage on schema shared_schema to creator2;
GRANT
testdb=# grant usage on schema shared_schema to user1;
GRANT --将creator1和creator2在shared_schema中创建表的select权限授予user1
testdb=# alter default privileges for user creator1, creator2 in schema shared_schema grant select on tables to user1;
ALTER DEFAULT PRIVILEGES --切到creator1,建表
testdb=# c testdb creator1
You are now connected to database "testdb" as user "creator1".
testdb=> create table shared_schema.t1 (c1 int);
CREATE TABLE --切到creator2,建表
testdb=> c testdb creator2
You are now connected to database "testdb" as user "creator2".
testdb=> create table shared_schema.t2 (c1 int);
CREATE TABLE --切到user1,查询OK
testdb=> c testdb user1
You are now connected to database "testdb" as user "user1".
testdb=> select from shared_schema.t1 union select from shared_schema.t2;
c1 ---- (0 rows)

查看默认权限的授予现状

查询系统表pg_default_acl可以查看当前哪些schema被授予了默认权限。从defaclacl字段可以看到creator1和creator2分别授予了user1对shared_schema中对象的select权限(r表示read)。

testdb=# select r.rolname, n.nspname, a.defaclobjtype, a.defaclacl from testdb-# pg_default_acl a, pg_roles r, pg_namespace n
testdb-# where a.defaclrole=r.oid and a.defaclnamespace=n.oid;
rolname | nspname | defaclobjtype | defaclacl ----------+---------------+---------------+-------------------- creator1 | shared_schema | r | {user1=r/creator1}
creator2 | shared_schema | r | {user1=r/creator2}
(2 rows)

一些细节

所有在共享schema中创建对象的用户都应该出现在_alter default privileges for user_之后的列表中。否则,如果有用户creator3没有在列表中,其在共享schema中创建的对象或者说那些Owner是creator3的对象将不能被user1查询。因为共享schema中creator3用户创建的表没有授予user1默认权限。

testdb=# create user creator3 password 'Gauss_234';
CREATE USER
testdb=# grant create, usage on schema shared_schema to creator3;
GRANT
testdb=# c testdb creator3
You are now connected to database "testdb" as user "creator3".
testdb=> create table shared_schema.t3 (c1 int);
CREATE TABLE
testdb=> c testdb user1
You are now connected to database "testdb" as user "user1".
testdb=> select * from shared_schema.t3;
ERROR: permission denied for relation t3

管理员可以通过_alter default privileges for user_将creator3放入列表中为user1授予访问creator3用户创建表的默认权限,也可以由creator3用户自己通过_alter default privileges_授权给user1. 前面语法参数说明中有如果省略FOR ROLE/USER,则缺省值为当前用户。

testdb=> c testdb creator3
You are now connected to database "testdb" as user "creator3".
testdb=> alter default privileges in schema shared_schema grant select on tables to user1;
ALTER DEFAULT PRIVILEGES
testdb=> c testdb user1
You are now connected to database "testdb" as user "user1".
testdb=> select * from shared_schema.t3;
ERROR: permission denied for relation t3
testdb=> c testdb creator3
testdb=> create table shared_schema.t4 (c1 int);
CREATE TABLE
testdb=> c testdb user1
You are now connected to database "testdb" as user "user1".
testdb=> select * from shared_schema.t4;
c1 ---- (0 rows)

上述代码第3行为当前用户在shared_schema下面创建的表的select权限授予user1。第7行user1查询shared_schema.t3报权限不足,是因为_alter default privileges_只处理将来的对象。shared_schema.t3在是之前创建的。我们新建表shared_schema.t4,user1用户查询正常。

如果要处理已有表的权限,使用_grant_语句。参见https://support.huaweicloud.com/devg-dws/dws_04_0334.html

testdb=> c testdb creator3
You are now connected to database "testdb" as user "creator3".
testdb=> grant select on all tables in schema shared_schema to user1;
ERROR: permission denied for relation t1
testdb=> grant select on table shared_schema.t3 to user1;
GRANT
testdb=> c testdb user1
You are now connected to database "testdb" as user "user1".
testdb=> select * from shared_schema.t3;
c1 ---- (0 rows)

代码第3行中shared_schema中包含有3个用户创建的表,而creator3只是表t3的创建者(Owner)。所以授予整个schema的权限会报错,只授予creator3是Owner的表t3之后,user1用户查询正常。

总结

_alter default privileges_只处理将来的对象,_grant_只处理已有的对象。进一步的,这两种语法授予权限时涉及的对象仅包括Owner是当前用户的对象。如果要为共享schema下面所有Owner的对象授予权限,需要使用管理员用户使用_alter default privileges for user_语法和_grant_语法。

本文分享自华为云社区《你应该知道的数仓安全——默认权限实现共享schema》,作者:zhangkunhn

点击关注,第一时间了解华为云新鲜技术~

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
4年前
MySQL5.6的4个自带库详解
1.information\_schema详细介绍:  information\_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。什么是元数据呢?元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。有些时候用于表述该信息的其他术语包括“数据词典”和“系统目录”。
可莉 可莉
4年前
20180610_navicat premium使用Root用户连接上mysql后只能看到information_schema数据库
navicatpremium使用Root用户连接上mysql后只能看到information\_schema库这是权限不足导致的,尽管是用root账户登录,navicat登录相当于是远程ip登录数据库,仍会出现权限不足只能看到information\_schema临时库。连接测试没有问题: !(https://oscimg.oschina.
Stella981 Stella981
4年前
PostgreSQL查询系统信息
整理一下,一方面备用,一方面分享1.查询数据表信息可通过information_schema.tables或pg_tablesselecttbs.frompg_tablestbswheretablename'tablename';
Wesley13 Wesley13
4年前
mysql 库简介与操作
mysql系统库information\_schema:虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等performance\_schema:MySQL5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各种事件、锁等现象mys
Wesley13 Wesley13
4年前
MySQL 基本语法
MySQL基本语法\TOC\MySQL本身自带4张表:information\_schema:数据库又称为信息架构,数据表保存了MySQL服务器所有数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。performance\_schema:数据库主要用于收集数据库服务器性能参数,
Stella981 Stella981
4年前
Bypass ngx_lua_waf SQL注入防御(多姿势)
0x00前言ngx\_lua\_waf是一款基于ngx\_lua的web应用防火墙,使用简单,高性能、轻量级。默认防御规则在wafconf目录中,摘录几条核心的SQL注入防御规则:select.(from|limit)(?:(union(.?)select))(?:from\Winformation_schema\W)这边
Wesley13 Wesley13
4年前
Oracle使用实例:创建只读用户
Oracle使用实例:创建只读用户原创L.Lawliet发布于2017080419:02:36阅读数12529收藏展开场景:数据库dbtest(服务名)下,创建reader只读用户访问查询scott普通用户下的表及数据   这里先只介绍使用命令操作的一种方法1\.管理员权限登陆sqlplus打开cmd,登陆方法
Stella981 Stella981
4年前
Hibernate映射文件结构
映射文件的根元素为<hibernatemapping,其下有多个<class子元素,每个<class代表多个持久化类的映射。该<hibernatemapping有如下属性:1)schema:指定所映射的数据库Schema名,如果指定了该属性,则表名会自动添加该Schema前缀。2)catalog:指定所映射的数据库的Catalog名,如果
Stella981 Stella981
4年前
20180610_navicat premium使用Root用户连接上mysql后只能看到information_schema数据库
navicatpremium使用Root用户连接上mysql后只能看到information\_schema库这是权限不足导致的,尽管是用root账户登录,navicat登录相当于是远程ip登录数据库,仍会出现权限不足只能看到information\_schema临时库。连接测试没有问题: !(https://oscimg.oschina.