【问题标题】:Prevent update of column except by trigger防止通过触发器更新列
【发布时间】:2015-06-20 19:11:12
【问题描述】:

是否可以配置 Postgres 数据库,使得特定列只能由触发器更新,同时仍允许触发器本身执行以响应角色的更新,而无需更新该列?如果有,怎么做?

例如,给定表和触发器如下:

CREATE TABLE a(
  id serial PRIMARY KEY,
  flag boolean NOT NULL DEFAULT TRUE,
  data text NOT NULL
);

CREATE TABLE b(
  id serial PRIMARY KEY,
  updated_on DATE NOT NULL DEFAULT CURRENT_DATE,
  a_id INTEGER NOT NULL,
  FOREIGN KEY (a_id) references a(id)
);

CREATE FUNCTION update_aflag() RETURNS trigger AS $update_aflag$
  BEGIN
    UPDATE a
    SET flag = FALSE
    WHERE id = NEW.a_id;
    RETURN NEW;
  END;
$update_aflag$ LANGUAGE plpgsql;

CREATE TRIGGER update_aflag_trigger
  AFTER INSERT ON b
  FOR EACH ROW
  EXECUTE PROCEDURE update_aflag()
;

我想定义一个角色,没有有权使用UPDATE 语句直接更新a.flag,但可以更新flag间接通过触发器。

【问题讨论】:

    标签: postgresql triggers permissions


    【解决方案1】:

    是的,这可以使用SECURITY DEFINER 触发函数来实现。触发功能作为有权修改flag 列的角色运行,但您没有GRANT 对普通用户的权限。您应该将触发器函数创建为您将授予所需权限的角色。

    这要求应用程序不能以拥有表的用户身份运行,当然也不能以超级用户身份运行。

    您可以将GRANT 列更新给用户对其他列的权限,只需省略flag 列。请注意,GRANTing UPDATE 在所有列上然后REVOKEing 在flag 上将不起作用,这不是一回事。

    【讨论】:

    • 哇,感谢克雷格的详细回答。现在要通读文档并尝试提出适当的SECURITY DEFINER 触发函数:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2021-11-05
    • 2021-02-25
    • 2020-09-13
    • 2010-09-05
    相关资源
    最近更新 更多