全部產品
Search
文件中心

AnalyticDB:行安全性原則

更新時間:Jul 02, 2024

一般情況下,資料庫帳號擁有表的讀寫權限後,就可以對錶中所有的行進行查詢或更新。AnalyticDB for PostgreSQL7.0新增了行安全性原則特性(Row Security Policies),該特性可以約束資料庫帳號,使資料庫帳號只能查詢或更新指定行。

注意事項

  • 行安全性原則對高許可權帳號、擁有BYPASSRLS屬性的帳號不生效。

  • 使用ENABLE的方式開啟行安全性原則時,行安全性原則對錶的擁有者不生效。如需對錶的擁有者進行限制,需使用ALTER TABLE ... FORCE ROW LEVEL SECURITY語句。

  • 當表上同時存在多個行安全性原則時,多個策略會同時生效。例如A策略只允許返回1和2行,B策略只允許返回4行,查詢時會同時返回1、2和4行。

行安全性原則參數

行安全性原則的參數及說明具體資訊,請參見行安全性原則官方文檔建立策略官方文檔

配置表的行安全性原則

  1. 使用用戶端工具串連資料庫

  2. 建立一張測試表logtest,並插入測試資料。

    CREATE TABLE logtest (
         id serial primary key,
         username text,
         log_event text);
    
    INSERT INTO logtest VALUES (1,'report','DELETE issued'),
                               (2,'messaging', 'Message queue purged'),
                               (3,'messaging','Reset accounts'),
                               (4,'report', 'Reset accounts');
  3. 建立兩個普通帳號report和messaging,並授予表logtest的SELECT許可權。

    CREATE ROLE report WITH LOGIN ENCRYPTED PASSWORD '111111';
    CREATE ROLE messaging WITH LOGIN ENCRYPTED PASSWORD '111111';
    
    GRANT SELECT ON logtest TO report;
    GRANT SELECT ON logtest TO messaging;
  4. 建立一個行安全性原則,限制使用者只能看到表中username列中與當前資料庫帳號名一致的行。

    CREATE POLICY policy_user_log ON logtest
       FOR ALL
       TO PUBLIC
       USING (username = current_user);
  5. 在表logtest中開啟行安全性原則。開啟後,該表的所有行安全性原則都將生效。

    ALTER TABLE logtest ENABLE ROW LEVEL SECURITY;
    重要
    • 通過上述方法開啟行安全性原則不會對錶的擁有者生效,如果想要對錶的擁有者也生效,需使用ALTER TABLE ... FORCE ROW LEVEL SECURITY語句。

    • 同一張表可以定義多條行安全性原則。

  6. 分別使用普通帳號和高許可權帳號查詢表logtest。

    • 使用帳號report查詢表logtest。

      SELECT * FROM logtest;

      返回資訊中只返回了username列為report的行。

      id| username | log_event
      --+----------+--------------
      1 | report   | DELETE issued
      4 | report   | Reset accounts
      (2 rows)
    • 使用帳號messaging查詢表logtest。

      SELECT * FROM logtest;

      返回資訊中只返回了username列為messaging的行。

      id| username  | log_event
      --+-----------+---------------------
      2 | messaging | Message queue purged
      3 | messaging | Reset accounts
      (2 rows)
    • 使用高許可權帳號查詢表logtest。

      SELECT * FROM logtest;

      返回資訊返回了所有行。

      id| username  | log_event
      --+-----------+---------------------
      1 | report    | DELETE issued
      2 | messaging | Message queue purged
      3 | messaging | Reset accounts
      4 | report    | Reset accounts
      (4 rows)
  7. 再添加一個行安全性原則,僅返回id列為偶數的行。

     CREATE POLICY policy_even_ids_only ON logtest
       FOR ALL
       TO PUBLIC
       USING (id % 2 = 0);
  8. 使用帳號report查詢表logtest。

    SELECT * FROM logtest;

    返回資訊中不僅返回了id列為偶數的列,還返回了username列為report的列。

    id| username  | log_event
    --+-----------+---------------------
    1 | report    | DELETE issued
    2 | messaging | Message queue purged
    4 | report    | Reset accounts
    (3 rows)

行安全性原則透傳視圖

前提條件

  • 本功能僅支援AnalyticDB for PostgreSQL執行個體V7.0.6.0及以上版本。

  • 聲明為security_invoker的視圖內部的所有查詢將以調用者的許可權執行,因此調用者需要具備視圖內部涉及到的全部內容的SELECT許可權。

功能介紹

使用者可能會有對基表建立視圖的需求,但在基表上的行安全性原則對普通帳號不會生效。您需要建立安全視圖,安全視圖會繼承基表的行安全性原則。

行安全性原則對普通帳號不生效的樣本

  1. 對上表logtest建立視圖v1,並授予帳號report SELECT許可權。

    CREATE VIEW v1 as SELECT * FROM logtest;
    GRANT SELECT ON v1 TO report;
  2. 使用帳號report查詢檢視v1。

    SELECT * FROM v1;
  3. 基表logtest上的行級許可權不生效。

    id| username  | log_event
    --+-----------+---------------------
    1 | report    | DELETE issued
    2 | messaging | Message queue purged
    3 | messaging | Reset accounts
    4 | report    | Reset accounts
    (4 rows)

建立安全視圖

如果要將行安全性原則透傳到視圖,必須在建立視圖時指定選項security_invoker,以提高資料安全性。當啟用security_invoker時,意味著視圖內部的所有查詢將以調用者的許可權而非視圖定義者的許可權來執行。

CREATE VIEW v1 WITH (security_invoker) AS SELECT * FROM logtest;

修改視圖的行安全性原則

您可以修改已有視圖的行安全性原則,開啟或關閉行安全性原則。

-- 開啟行安全性原則
ALTER VIEW v1 SET (security_invoker = on);

-- 關閉行安全性原則
ALTER VIEW v1 SET (security_invoker = off);

查詢安全視圖

開啟行安全性原則後,再使用帳號report查詢檢視v1。

SELECT * FROM v1;

基表logtest上的行級許可權已經生效。

id| username  | log_event
--+-----------+---------------------
1 | report    | DELETE issued
2 | messaging | Message queue purged
4 | report    | Reset accounts
(3 ROWS)

配置物化視圖的行安全性原則

  1. 對上述測試表logtest建立一個物化視圖mv_logtest,並授權SELECT給report帳號。

CREATE MATERIALIZED VIEW mv_logtest
AS
  SELECT * FROM logtest;

GRANT SELECT ON mv_logtest TO report;
  1. 使用report帳號查詢物化視圖mv_logtest,可以看到所有行。

SELECT * FROM mv_logtest;

 id | username  | log_event
----+-----------+----------------------
  2 | messaging | Message queue purged
  3 | messaging | Reset accounts
  4 | report    | Reset accounts
  1 | report    | DELETE issued
(4 ROWS)
  1. 對物化視圖mv_logtest建立一個行安全性原則,限制使用者只能看到其中username列中與當前資料庫帳號名一致的行。

CREATE POLICY policy_user_log ON mv_logtest
   FOR ALL
   TO PUBLIC
   USING (username = current_user);
  1. 在物化視圖mv_logtest中開啟行安全性原則。開啟後,該物化視圖的所有行安全性原則都將生效。

ALTER MATERIALIZED VIEW mv_logtest ENABLE ROW LEVEL SECURITY;
說明
  • 通過上述方法開啟行安全性原則不會對物化視圖的擁有者生效,如果想要對物化視圖的擁有者也生效,需使用ALTER MATERIALIZED VIEW ... FORCE ROW LEVEL SECURITY語句。

  • 一個物化視圖可以定義多條行安全性原則。

  • 行安全性原則支援物化視圖和即時物化視圖。

  1. 再次使用report帳號查詢物化視圖mv_logtest。

SELECT * FROM mv_logtest;

返回資訊中只返回了username列為report的行。

id| username | log_event
--+----------+--------------
1 | report   | DELETE issued
4 | report   | Reset accounts
(2 ROWS)