Postgres 列级安全性

smu*_*ard 5 postgresql security postgresql-11

我在数据库testdb中有一个模式Snow。我正在努力为我的用户实现列级安全性。我的用户是老板经理实习生我以超级用户me的身份设置了该表的所有内容。他们都在集团公司

我的表是这样的:snow.company_table

 property_id |     property_address     |     city     | zip_code | state
-------------+--------------------------+--------------+----------+-------
           1 | 2564 Wescam Court        | Reno         |    89511 | NV    
           2 | 1732 Rubaiyat Road       | Grand Rapids |    49603 | MI    
           3 | 4094 Francis Mine        | Standish     |    96128 | CA    
           4 | 3193 Ashton Lane         | Briggs       |    78608 | TX    
           5 | 1519 North Street        | Alamosa      |    81102 | CO    
Run Code Online (Sandbox Code Playgroud)

我创造了这样的角色,老板经理实习生都在公司内部。

CREATE ROLE company WITH LOGIN CONNECTION LIMIT 0;  
CREATE ROLE boss WITH LOGIN CONNECTION LIMIT 1 PASSWORD '1234' IN ROLE company;
CREATE ROLE manager WITH LOGIN CONNECTION LIMIT 1 PASSWORD '1234' IN ROLE company;
CREATE ROLE intern WITH LOGIN CONNECTION LIMIT 1 PASSWORD '1234 IN ROLE company;
Run Code Online (Sandbox Code Playgroud)

我希望老板能够选择所有列,经理只能选择property_id、zipcodestate,而实习生只能选择property_idstate。我使用这些命令来创建角色及其授予:为了授予列权限,我首先撤销所有权限,然后再授予它们。

REVOKE ALL ON snow.property_table FROM snow; --remove all privileges automatically assigned to everybody
GRANT ALL ON snow.company_table TO boss; --boss has the ability to do anything to this table
GRANT SELECT( property_id, zip_code, state) ON snow.company_table TO manager;
GRANT SELECT( property_id, state) ON snow.company_table TO intern;  
Run Code Online (Sandbox Code Playgroud)

有关详细信息,运行\dn+会给出结果:

  Name  |    Owner     |      Access privileges       |
--------+--------------+------------------------------
 snow   |     me       | me=UC/me                    +|
        |              | boss=U/me                   +|
        |              | company=U/me                +|
        |              | manager=U/me                +|
        |              | intern=U/me                  |
Run Code Online (Sandbox Code Playgroud)

我的问题是:当我连接到用户(例如intern)时,我无权访问上面显示的表。我仍然想保留列权限,但我只希望我的用户看到我指定的列,而不授予他们对整个company_table 的完全权限。

这是错误:

STATEMENT:  select * from snow.company_table;
ERROR:  permission denied for table company_table
Run Code Online (Sandbox Code Playgroud)

jja*_*nes 5

作为管理员或老板,您可以创建特定于用户的视图,其中仅包含您希望该用户能够查看的列。然后授予用户对其特定视图的访问权限,而不是基础表的访问权限。如果您这样做,那么您首先不需要使用列权限,因为列访问已经通过视图受到限制。如果您不小心将不希望包含的列包含到视图中,则列权限不会保存您,因为该视图是作为视图所有者而不是视图调用者执行的,因此无论如何都会提供这些列。

确保始终security_barrier = on在视图的定义中进行设置,这些视图用于授予某人对用户不应完整查看的表的有限访问权限。

或者每个用户可以为了自己的方便而创建自己的视图,在这种情况下,基础表中的列权限仍然会被强制执行。

请注意,许多人认为“select *”只是开发和测试的拐杖,无论如何都不应该在生产代码中使用。