【问题标题】:How to allow user call stored procedure in Postgresql without granting additional rights?如何在不授予额外权限的情况下允许用户在 Postgresql 中调用存储过程?
【发布时间】:2019-10-03 17:12:13
【问题描述】:

我在 Postgresql 中有一个包含 COMMIT 语句的存储过程,我希望用户只访问这个过程而不赋予他们选择、插入等的权利。在函数中我会使用 SECURITY DEFINER,但来自官方文档https://www.postgresql.org/docs/11/sql-createprocedure.html

SECURITY DEFINER 过程不能执行事务控制语句(例如,COMMIT 和 ROLLBACK,取决于语言)。

据我了解,这意味着我不能使用 SECURITY DEFINER 并且必须授予用户存储过程中所需的任何权限以允许用户执行它,这完全违背了仅允许用户使用函数或过程的整个目的。

如何在不单独授予过程中所有语句的情况下调用包含 COMMIT 语句的存储过程?

【问题讨论】:

    标签: postgresql stored-procedures transactions


    【解决方案1】:

    您可以将权限授予特定过程,以便用户只能拥有该过程的事务控制权限。

    GRANT ALL ON PROCEDURE <procedure_name> TO <role>;
    

    【讨论】:

    • @J Spratt,谢谢你的回答,但它仍然抛出错误:“错误:表项目的权限被拒绝”
    • @niks 我以前没有尝试过,但您可以在存储过程中将GRANTREVOKE 特权授予CURRENT_USER。这样用户就只有存储过程范围的权限。
    • @J Spratt 还没有成功。任何有关如何实现此目的的提示将不胜感激。
    • CREATE PROCEDURE 仅在我的机器上没有的 postgres 11 中可用,并且 dbfiddle 不允许创建用户。从您引用的文档中,它说“取决于语言”。您是否尝试在过程定义中使用LANGUAGE PLPGSQLSECURITY DEFINER?为什么不能使用FUNCTION 或者为什么COMMIT 语句是必要的?
    • @J Spratt 抱歉这么晚才回复。我发现这是目前程序的一种限制。我还发现您放入函数中的所有内容都在内部包装在事务中,并且最终它是“全有或全无”,这就是我想使用过程的原因,以便我可以在最后提交更改。因此,我将使用该功能!感谢您提供有用的想法!
    【解决方案2】:

    有解决此限制的方法。

    SECURITY DEFINER 过程无法执行事务控制 语句(例如,COMMIT 和 ROLLBACK,取决于 语言)。

    可以从存储过程中使用 SECURITY DEFINER 调用(SELECT 或 PERFORM)函数。当然,用户必须对过程和函数都有 GRANT EXECUTE。

    CREATE OR REPLACE PROCEDURE procedure_test()
        LANGUAGE plpgsql
    AS $$
    begin
    
        PERFORM function_test();
        COMMIT;
        PERFORM function_test();
    
    end
    $$;
    
    CREATE OR REPLACE FUNCTION function_test(
    ) RETURNS void
        LANGUAGE plpgsql SECURITY DEFINER
    AS $$
    begin
    
        -- some code
    
    end
    $$;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多