如何在 DATABASE vs SCHEMA 上管理使用者的預設權限?
我想將一個相當簡單的、內部的、數據庫驅動的應用程序從 SQLite3 遷移到 PostgreSQL 9.3,並在我進行時收緊數據庫中的權限。
該應用程序目前包含一個更新數據的命令;和一個查詢它。當然,我還需要以其他方式維護數據庫(創建新表、視圖、觸發器等)。
雖然這個應用程序最初將是唯一託管在伺服器上的應用程序,但我更願意假設它將來可能會託管在具有其他數據庫的伺服器上,而不是在以後有必要時不得不爭先恐後未來。
我認為這些將是一組相當常見的要求,但我很難找到一個簡單的教程來解釋如何在 PostgreSQL 中設置一個新的數據庫,並使用這種使用者/權限分離。關於組、使用者、角色、數據庫、模式和域的參考資料很詳細;但我發現它們令人困惑。
這是我迄今為止嘗試過的(從內部
psql
作為’postgres’):CREATE DATABASE hostdb; REVOKE ALL ON DATABASE hostdb FROM public; \connect hostdb CREATE SCHEMA hostdb; CREATE USER hostdb_admin WITH PASSWORD 'youwish'; CREATE USER hostdb_mgr WITH PASSWORD 'youwish2'; CREATE USER hostdb_usr WITH PASSWORD 'youwish3'; GRANT ALL PRIVILEGES ON DATABASE hostdb TO hostdb_admin; GRANT CONNECT ON DATABASE hostdb TO hostdb_mgr, hostdb_usr; ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hostdb_mgr; ALTER DEFAULT PRIVILEGES IN SCHEMA hostdb GRANT SELECT ON TABLES TO hostdb_usr;
但我沒有得到預期的語義。我想對其進行配置,以便只有
hostdb_admin
可以創建(以及刪除和更改)表;預設情況下hostdb_mgr
可以對所有表進行讀取、插入、更新和刪除;並且hostdb_usr
只能讀取所有表(和視圖)。當我嘗試這個時,我發現我能夠以
hostdb
任何這些使用者的身份創建表;但是,對於每個使用者,我只能讀取或修改該使用者創建的表——除非我使用顯式的GRANT
.我猜在
CREATE DATABASE
and之間缺少CREATE SCHEMA
一些東西,可以應用SCHEMA
到DATABASE
?(隨著事情變得更先進,我也會有問題需要對
TRIGGERS
、儲存過程VIEWS
和其他對象應用類似的限制)。我在哪裡可以找到一個不錯的指南、教程或影片系列?
Postgres 14添加了預定義的角色
pg_read_all_data
和pg_write_all_data
,它允許使用快捷方式來實現名稱所暗示的目的。我在哪裡可以找到一個不錯的指南、教程或影片系列?
您會在手冊中找到*所有內容。*下面的連結。
誠然,這件事並非微不足道,有時甚至令人困惑。這是案例的配方:
食譜
我想對其進行配置,以便只有
hostdb_admin
可以創建(以及刪除和更改)表;預設情況下
hostdb_mgr
可以對所有表進行讀取、插入、更新和刪除;並且
hostdb_usr
只能讀取所有表(和視圖)。作為超級使用者
postgres
:CREATE USER schma_admin WITH PASSWORD 'youwish'; -- CREATE USER schma_admin WITH PASSWORD 'youwish' CREATEDB CREATEROLE; -- see below CREATE USER schma_mgr WITH PASSWORD 'youwish2'; CREATE USER schma_usr WITH PASSWORD 'youwish3';
如果你想要一個更強大的管理員,也可以管理數據庫和角色,添加角色屬性
CREATEDB
及CREATEROLE
以上。將每個角色授予下一個更高級別,因此所有級別都“繼承”至少來自下一個較低級別(級聯)的權限集:
GRANT schma_usr TO schma_mgr; GRANT schma_mgr TO schma_admin; CREATE DATABASE hostdb; REVOKE ALL ON DATABASE hostdb FROM public; -- see notes below! GRANT CONNECT ON DATABASE hostdb TO schma_usr; -- others inherit \connect hostdb -- psql syntax
我正在命名模式
schma
(不會hostdb
令人困惑)。選擇任何名稱。(可選)使schma_admin
架構的所有者:CREATE SCHEMA schma AUTHORIZATION schma_admin; SET search_path = schma; -- see notes ALTER ROLE schma_admin IN DATABASE hostdb SET search_path = schma; -- not inherited ALTER ROLE schma_mgr IN DATABASE hostdb SET search_path = schma; ALTER ROLE schma_usr IN DATABASE hostdb SET search_path = schma; GRANT USAGE ON SCHEMA schma TO schma_usr; GRANT CREATE ON SCHEMA schma TO schma_admin; ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin GRANT SELECT ON TABLES TO schma_usr; -- only read ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin GRANT INSERT, UPDATE, DELETE, TRUNCATE ON TABLES TO schma_mgr; -- + write, TRUNCATE optional ALTER DEFAULT PRIVILEGES FOR ROLE schma_admin GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO schma_mgr; -- SELECT, UPDATE are optional
請
and drop and alter
參閱下面的註釋。Postgres 14添加了預定義的非登錄角色
pg_read_all_data
,並pg_write_all_data
為所有模式中的所有對象提供只讀/只寫訪問權限。這超出了這裡的要求,但可能有用。看:隨著事情變得更先進,我也會有問題要對
TRIGGERS
、儲存過程VIEWS
和可能的其他對象應用類似的限制。觀點很特別。
…(但請注意,這
ALL TABLES
被認為包括視圖和外部表)。對於可更新視圖:
請注意,對視圖執行插入、更新或刪除操作的使用者必須對視圖具有相應的插入、更新或刪除權限。此外,視圖的所有者必須對基礎基礎關係具有相關權限,但執行更新的使用者不需要基礎基礎關係的任何權限(參見 第 38.5 節)。
觸發器也很特殊。您需要在
TRIGGER
桌子上的特權,並且:重要筆記
所有權
如果您想允許
schma_admin
(單獨)刪除和更改表,請讓角色擁有所有對象。文件:刪除對像或以任何方式更改其定義的權利不被視為可授予的特權;它是所有者固有的,不能授予或撤銷。(但是,通過授予或撤銷擁有該對象的角色的成員資格可以獲得類似的效果;見下文。)所有者也隱含地擁有該對象的所有授予選項。
ALTER TABLE some_tbl OWNER TO schma_admin;
或者創建具有角色
schma_admin
的所有對象,然後您無需顯式設置所有者。它還簡化了預設權限,您只需為一個角色設置:預先存在的對象
預設權限僅適用於新創建的對象,並且僅適用於創建它們的特定角色。您還需要調整現有對象的權限:
如果您創建具有未
DEFAULT PRIVILEGES
設置角色的對象(例如 superuser ),這同樣適用postgres
。手動重新分配所有權schma_admin
並設置權限 - 或同時設置權限DEFAULT PRIVILEGES
(postgres
連接到正確的數據庫時!):ALTER DEFAULT PRIVILEGES FOR ROLE postgres GRANT ... -- etc.
預設權限
ALTER DEFAULT PRIVILEGES
你錯過了命令的一個重要方面。除非另有說明,否則它適用於目前角色:預設權限僅適用於目前數據庫。所以你不會弄亂數據庫集群中的其他數據庫。文件:
對於在目前數據庫中創建的所有對象
您可能還想為
FUNCTIONS
andTYPES
(不僅僅是TABLES
andSEQUENCES
)設置預設權限,但可能不需要這些權限。預設權限
PUBLIC
授予的預設權限
PUBLIC
是基本的並且被某些人高估了。文件:PostgreSQL 將某些類型的對象的預設權限授予
PUBLIC
. **預設情況下,不會對錶、列、模式或表空間****授予任何權限。PUBLIC
**對於其他類型,授予的預設權限PUBLIC
如下:CONNECT
和CREATE TEMP TABLE
對於數據庫;EXECUTE
功能特權;和USAGE
語言的特權。大膽強調我的。通常,這一個命令(包括在頂部)就是您所需要的:
REVOKE ALL ON DATABASE hostdb FROM public;
特別是,沒有
PUBLIC
為新模式授予預設權限。名為“public”的預設模式ALL
以PUBLIC
. 這只是一個方便的功能,可以簡化新創建的數據庫的啟動。它不會以任何方式影響其他模式。您可以在模板數據庫中撤銷這些權限template1
,然後此集群中所有新創建的數據庫都將在沒有它們的情況下啟動:\connect template1 REVOKE ALL ON SCHEMA public FROM public;
特權
TEMP
由於我們撤銷了
hostdb
from 的所有權限PUBLIC
,因此普通使用者無法創建臨時表,除非我們明確允許。您可能想要也可能不想添加:GRANT TEMP ON DATABASE hostdb TO schma_mgr;
search_path
不要忘記設置
search_path
. 如果集群中只有一個數據庫,則可以在postgresql.conf
. 否則(更有可能)將其設置為數據庫的屬性,或者僅用於涉及的角色,甚至兩者的組合。細節:如果您也
schma, public
使用公共模式,或者甚至(不太可能)$user, schma, public
…
search_path
另一種方法是使用預設模式“public”,除非您更改它,否則它應該與預設設置一起使用。PUBLIC
在這種情況下,請記住撤銷權限。有關的