PostgreSQL 中的条件列级权限

问题描述 投票:0回答:1

让我们创建一个用户和包含一些数据的表:

CREATE ROLE admin;
CREATE TABLE employee (empno int, ename text, address text, salary int, account_number text);
INSERT INTO employee VALUES
  (1, 'john'  , '2 down str'   ,  20000, 'HDFC-22001')
, (2, 'clark' , '132 south avn',  80000, 'HDFC-23029')
, (3, 'soojie', 'Down st 17th' ,  60000, 'ICICI-19022')
;

现在,让我们创建列级权限:

postgres=> \c postgres edb
You are now connected to database "postgres" as user "edb".

postgres=# grant select (empno, ename, address) on employee to admin;
GRANT

postgres=# \c postgres admin
You are now connected to database "postgres" as user "admin".
postgres=> select empno, ename, address, salary from employee;
ERROR:  permission denied for table employee
postgres=> select empno, ename, address from employee;

 empno | ename  |    address    
-------+--------+---------------
     1 | john   | 2 down str
     2 | clark  | 132 south avn
     3 | soojie | Down st 17th

到目前为止一切正常。

但是在 PostgreSQL 中是否可以创建更复杂的规则——而不是完全限制

admin
用户查看
salary
列,例如,返回所有行的
NULL
值并显示实际值仅工资栏,例如,
ename = 'clark'

换句话说,不要像下面的示例那样返回错误:

postgres=> select empno, ename, address, salary from employee;
ERROR:  permission denied for table employee

返回如下结果:

 empno | ename  |    address    | salary 
-------+--------+---------------+--------
     1 | john   | 2 down str    |  NULL
     2 | clark  | 132 south avn |  80000 
     3 | soojie | Down st 17th  |  NULL

这很可能可以通过视图来完成,但我对使用如上所示的简单规则实现此结果特别感兴趣。

如果可能的话,我希望能举个例子。

postgresql security permissions rbac abac
1个回答
0
投票

正确的方法是视图:

CREATE VIEW emp_view WITH (security_barrier = on) AS
SELECT empno, ename, address,
       CASE WHEN ename = 'clark'
            THEN salary
       END AS salary
FROM employee;

GRANT SELECT ON emp_view TO admin;

然后

admin
就可以看到你想要的数据,而无需直接访问底层表。

security_barrier
对于防止
admin
访问她不应该看到的数据是必要的。有关详细信息,请参阅文档

© www.soinside.com 2019 - 2024. All rights reserved.