PostgreSQL創建只讀賬戶


目前PostgreSQL並不能像MySQL一樣直接對某個數據庫賦予只讀權限,現實中有研發需要新建一個用戶然后賦予對某個數據庫只讀權限。

舉例說明如何創建

用edbstore用戶連接edbstore數據庫,並創建一個測試schema

$ psql -U edbstore edbstore
psql (9.6.4)
Type "help" for help.

edbstore=> create schema ota_data;
CREATE SCHEMA
edbstore=> \dn ota_data 
   List of schemas
   Name   |  Owner   
----------+----------
 ota_data | edbstore
(1 row)

在測試schema下創建一張測試表並插入部分數據

edbstore=> set search_path to ota_data ;
SET
edbstore=> show search_path ;
 search_path 
-------------
 ota_data
(1 row)

edbstore=> create table tb1(name varchar,age int);
CREATE TABLE
edbstore=> insert into tb1 values('chris',23);
INSERT 0 1
edbstore=> insert into tb1 values('tonny',25);
INSERT 0 1
edbstore=> select * from tb1;
 name  | age 
-------+-----
 chris |  23
 tonny |  25
(2 rows)

 現在新建一個readonly用戶並嘗試訪問edbstore用戶下新建的測試數據

postgres=# create role readonly password 'readonly' login;
CREATE ROLE
$ export PGPASSWORD=readonly
$ psql -h 172.16.101.66 -U readonly edbstore
psql (9.6.4)
Type "help" for help.

edbstore=> set search_path to ota_data ;
SET
edbstore=> \d
No relations found.

 可以看到默認情況下新用戶readonly是無法看到edbstore用戶下的數據的,現在賦予用戶readonly查看schema對象的權限

edbstore=> GRANT USAGE ON SCHEMA ota_data TO readonly;
GRANT

 readonly用戶再次查看

edbstore=> \d
         List of relations
  Schema  | Name | Type  |  Owner   
----------+------+-------+----------
 ota_data | tb1  | table | edbstore
(1 row)

edbstore=> select * from tb1 ;
ERROR:  permission denied for relation tb1

可以看到雖然用戶可以查看到該對象,但是沒用select權限,現在進行賦權

edbstore=> \dp
                             Access privileges
  Schema  | Name | Type  | Access privileges | Column privileges | Policies 
----------+------+-------+-------------------+-------------------+----------
 ota_data | tb1  | table |                   |                   | 
(1 row)

edbstore=> GRANT SELECT ON ALL TABLES IN SCHEMA ota_data TO readonly;
GRANT
edbstore=> \dp
                                 Access privileges
  Schema  | Name | Type  |     Access privileges     | Column privileges | Policies 
----------+------+-------+---------------------------+-------------------+----------
 ota_data | tb1  | table | edbstore=arwdDxt/edbstore+|                   | 
          |      |       | readonly=r/edbstore       |                   | 
(1 row)

 readonly用戶再次查看

edbstore=> select * from tb1 ;
 name  | age 
-------+-----
 chris |  23
 tonny |  25
(2 rows)

edbstore=> insert into tb1 values('tina',19);
ERROR:  permission denied for relation tb1

該命令只能對已經存在的對象(表,視圖等)賦權,新建立的表,readonly用戶是無法查看的,新建一張表

edbstore=> create table tb2 as select * from tb1;
SELECT 2
edbstore=> \dp
                                 Access privileges
  Schema  | Name | Type  |     Access privileges     | Column privileges | Policies 
----------+------+-------+---------------------------+-------------------+----------
 ota_data | tb1  | table | edbstore=arwdDxt/edbstore+|                   | 
          |      |       | readonly=r/edbstore       |                   | 
 ota_data | tb2  | table |                           |                   | 
(2 rows)

 readonly用戶再次查看

edbstore=> \d
         List of relations
  Schema  | Name | Type  |  Owner   
----------+------+-------+----------
 ota_data | tb1  | table | edbstore
 ota_data | tb2  | table | edbstore
(2 rows)

edbstore=> select * from tb2;
ERROR:  permission denied for relation tb2

為了讓readonly用戶可以有權限繼續查看新建的表,需要為該新建的schema指定default權限

edbstore=> ALTER DEFAULT PRIVILEGES IN SCHEMA ota_data GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES
edbstore=> \ddp
             Default access privileges
  Owner   |  Schema  | Type  |  Access privileges  
----------+----------+-------+---------------------
 edbstore | ota_data | table | readonly=r/edbstore
(1 row)

edbstore=> create table tb3 as select * from tb1;
SELECT 2
edbstore=> \dp
                                 Access privileges
  Schema  | Name | Type  |     Access privileges     | Column privileges | Policies 
----------+------+-------+---------------------------+-------------------+----------
 ota_data | tb1  | table | edbstore=arwdDxt/edbstore+|                   | 
          |      |       | readonly=r/edbstore       |                   | 
 ota_data | tb2  | table |                           |                   | 
 ota_data | tb3  | table | edbstore=arwdDxt/edbstore+|                   | 
          |      |       | readonly=r/edbstore       |                   | 
(3 rows)

可以看到新建的表tb3會自動繼承我們給該schema下的表預定義的select權限。

edbstore=> select * from information_schema.role_table_grants where grantee='readonly';
 grantor  | grantee  | table_catalog | table_schema | table_name | privilege_type | is_grantable | with_hierarchy 
----------+----------+---------------+--------------+------------+----------------+--------------+----------------
 edbstore | readonly | edbstore      | ota_data     | tb1        | SELECT         | NO           | YES
 edbstore | readonly | edbstore      | ota_data     | tb3        | SELECT         | NO           | YES
(2 rows)

如何取消該權限

alter default privileges in schema public revoke select on tables from readonly ;

 關於如何對整個輸幾局所有schema添加權限可以參考如下命令:

select 'grant usage on schema '|| schema_name || ' to readonly ;' from information_schema.schemata;

select 'GRANT SELECT ON ALL TABLES IN SCHEMA '|| schema_name || ' TO readonly ;' from information_schema.schemata;

select 'ALTER DEFAULT PRIVILEGES IN SCHEMA '|| schema_name || ' GRANT SELECT ON TABLES TO readonly ;' from information_schema.schemata;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM