从继承的角色中撤销 SELECT

Revoke SELECT from inherited role

我在获得按我希望的方式工作的权限时遇到了一个小问题。

我有一个角色,通常应该允许 SELECT 到处都是,这个角色有很多成员。不应允许其中之一从某个 table.

select

我认为这可以通过将角色成员资格授予一般 reader 角色并从受限 table 中撤销 SELECT 来实现。

似乎父角色的权限适用,而不是特定权限。有没有办法解决这个问题而不必维护更受限制的角色的权限,或者我是否以错误的方式在 PostgreSQL 中应用了角色概念?

这是一个示例脚本:

-- as superuser
CREATE DATABASE permission_test;

\c permission_test

CREATE ROLE r_general_select;
CREATE ROLE r_restricted_select IN ROLE r_general_select;

-- set the default permissions
ALTER DEFAULT PRIVILEGES IN SCHEMA "public" GRANT SELECT ON TABLES TO "r_general_select";

CREATE TABLE "open"(
    id SERIAL,
    payload TEXT
);
insert into "open"(payload) values ('test');

-- covered by default privileges
GRANT SELECT ON "open" TO PUBLIC;

-- Tests
-- this is good
SET ROLE r_general_select;
SELECT * FROM "open";
RESET ROLE;

-- this is good
SET ROLE r_restricted_select;
SELECT * FROM "open";
RESET ROLE;

CREATE TABLE "restricted" (
    id SERIAL,
    payload TEXT
);
insert into "restricted"(payload) values ('test');

-- the role and it's members should be able to read
GRANT SELECT ON "restricted" TO r_general_select;
-- except for this one!
REVOKE SELECT ON "restricted" FROM r_restricted_select;

-- Tests
-- this is good
SET ROLE r_general_select;
SELECT * FROM restricted;
RESET ROLE;

-- this should barf with a permission violation
SET ROLE r_restricted_select;
SELECT * FROM restricted;
RESET ROLE;

--- CLEANUP
DROP OWNED BY "r_restricted_select" CASCADE;
DROP ROLE r_restricted_select ;
DROP OWNED BY "r_general_select" CASCADE;
DROP ROLE r_general_select ;

在 PostgreSQL 中,角色权限是纯附加的。在这样的模型中,无法从继承角色的后代撤销对继承角色授予的权限。

要解决此问题,您需要更改您的权限方法并将其基于总是 一起出现的权限。我通常通过同时查看功能依赖性和操作依赖性来做到这一点。