如何正确定义角色和权限(案例研究-PostgreSQL)?
不久前,我来到社区询问我正在开发的系统的触发器的定义。我仍然发现自己在开发同样的系统,现在我对角色产生了怀疑。我对使用PostgreSQL还不熟悉,即使在阅读文档之后,我也会遇到一些问题 为了开发我的系统,我创建了3个用户:如何正确定义角色和权限(案例研究-PostgreSQL)?,sql,database,postgresql,roles,privileges,Sql,Database,Postgresql,Roles,Privileges,不久前,我来到社区询问我正在开发的系统的触发器的定义。我仍然发现自己在开发同样的系统,现在我对角色产生了怀疑。我对使用PostgreSQL还不熟悉,即使在阅读文档之后,我也会遇到一些问题 为了开发我的系统,我创建了3个用户: dbadiretor(翻译成dbadirector):它的行为类似于DBA,仅由一个人使用 dbagerente(翻译成dbamanager):它是一个用户,能够在不需要更改表结构的情况下更改表结构 操纵它的数据。该用户还可以创建 触发器、函数、索引等 clisistem
- dbadiretor(翻译成dbadirector):它的行为类似于DBA,仅由一个人使用
- dbagerente(翻译成dbamanager):它是一个用户,能够在不需要更改表结构的情况下更改表结构 操纵它的数据。该用户还可以创建 触发器、函数、索引等
- clisistema(翻译成clisystem):它是具有 连接到数据库。该用户可以执行CRUD操作, 但无法在中创建、删除、修改或删除现有对象 数据库对于某些表,此用户已筛选其权限
ERROR: permission denied for relation tb_tabelas
CONTEXT: SQL statement "SELECT 1 FROM ONLY "regrast"."tb_tabelas" x WHERE "tab_id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
********** Error **********
ERROR: permission denied for relation tb_tabelas
SQL state: 42501
Context: SQL statement "SELECT 1 FROM ONLY "regrast"."tb_tabelas" x WHERE "tab_id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x"
我使用的是postgres用户,我不知道我做错了什么。我不是在说这些话(至少不是直接说):
以下是我的用户的创建:
-- DROP OWNED BY dbadiretor CASCADE;
DROP ROLE IF EXISTS dbadiretor;
CREATE ROLE dbadiretor WITH
SUPERUSER
CREATEDB
CREATEROLE
LOGIN
REPLICATION
CONNECTION LIMIT 1
PASSWORD 'dbadiretor';
-- DROP OWNED BY dbagerente CASCADE;
DROP ROLE IF EXISTS dbagerente;
CREATE ROLE dbagerente WITH
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
LOGIN
NOREPLICATION
CONNECTION LIMIT 3
PASSWORD 'dbagerente';
-- DROP OWNED BY clisistema CASCADE;
DROP ROLE IF EXISTS clisistema;
CREATE ROLE clisistema WITH
NOSUPERUSER
NOCREATEDB
NOCREATEROLE
NOINHERIT
LOGIN
NOREPLICATION
CONNECTION LIMIT 30
PASSWORD '12345';
下面是特权的分配:
-- #####################################
-- USUÁRIO: PUBLIC
-- #####################################
REVOKE ALL PRIVILEGES ON DATABASE "ELocadora" FROM PUBLIC;
-- #####################################
-- USUÁRIO: dbadiretor
-- #####################################
GRANT ALL PRIVILEGES ON SCHEMA regrast TO dbadiretor;
GRANT ALL PRIVILEGES ON DATABASE "ELocadora" TO dbadiretor;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA regrast TO dbadiretor;
-- #####################################
-- USUÁRIO: clisistema
-- #####################################
GRANT CONNECT ON DATABASE "ELocadora" TO clisistema;
GRANT USAGE ON SCHEMA regrast TO clisistema;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA regrast TO clisistema;
-- NÍVEL DE FILTRO 1
REVOKE TRUNCATE, REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA regrast FROM clisistema;
REVOKE CREATE ON SCHEMA regrast FROM clisistema;
REVOKE TEMP ON DATABASE "ELocadora" FROM clisistema;
-- NÍVEL DE FILTRO 2
-- Tabela: TB_TABELAS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_tabelas FROM clisistema;
-- Tabela: TB_DADOS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_dados FROM clisistema;
-- Tabela: TB_MODIFICACOES
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_modificacoes FROM clisistema;
-- Tabela: TB_TIPOS_DE_LOGS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_tipos_de_logs FROM clisistema;
-- Tabela: TB_LOGS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_logs FROM clisistema;
-- Tabela: TB_HISTORICO_DE_PRODUTOS
-- Revogação: CUD
REVOKE INSERT, UPDATE, DELETE ON TABLE regrast.tb_historico_de_produtos FROM clisistema;
-- Tabela: TB_CONFIGURACOES
-- Revogação: CD
REVOKE INSERT, DELETE ON TABLE regrast.tb_configuracoes FROM clisistema;
-- #####################################
-- USUÁRIO: dbagerente
-- #####################################
GRANT CONNECT ON DATABASE "ELocadora" TO dbagerente;
GRANT USAGE ON SCHEMA regrast TO dbagerente;
REVOKE INSERT, SELECT, UPDATE, DELETE ON ALL TABLES IN SCHEMA regrast FROM dbagerente;
GRANT CREATE ON SCHEMA regrast TO dbagerente;
GRANT REFERENCES, TRIGGER ON ALL TABLES IN SCHEMA regrast TO dbagerente;
我在中读到,如果我希望以任何方式修改表,我需要为表设置适当的所有者。例如,关于创建特权:
创造
对于架构,允许在架构内创建新对象到
重命名现有对象时,必须拥有该对象,并且
包含架构的权限
因此,我的所有表都有dbagerente用户作为所有者。作为dbagerente,我可以修改结构。但作为一名校长或博士后,我不能,这不是我想要的。对我来说,dbadiretor和postgres是超级用户,他们应该能够完成任何事情。。。还是不/
再往前看一点。。。我必须小心其他数据库对象,如函数、触发器等吗
注意:我使用的是PostgreSQL9.5,数据库名为ELocadora,模式名为regrast
解决这个问题,如果可能的话(如果你不介意的话),对于像我这样的初学者,你有什么关于角色正确分配的建议吗?任何链接或提示都可以帮助我 此外,是否存在仅为实现日志而创建新用户的禁忌症?系统事务(对于某些操作)可能最终必须使用两种类型的用户才能完成 谢谢你的关注 编辑 我怀疑这个错误是由于依赖关系而出现的 在桌子之间。在某些表中,对于某些外键,我使用 ON DELETE和ON UPDATE语句 第一次输入数据时,数据输入没有问题。 但是,如果删除它们以重新插入,则会出现此错误 这有什么关系吗 我错了,这个信息是没有根据的。请不要理它。我很抱歉 编辑2 我记录了整个过程,包括所有步骤和明显的问题。一切都是白手起家的。请看一看(4分钟): 打开的SQL文件表示正在进行的不同操作。它们按不同的步骤组织。再说一遍,我做错了什么 编辑3 我在代码中发现了一个小错误。非破坏性(最初)。在记录插入代码中,我更改了以下内容:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%'));
为此:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
@克里斯·特拉弗斯
[…]因此表所有者必须具有对
在任何人都可以从中删除之前,级联表
[…]所以这里的问题是表所有者没有访问权限
但我用的是超级账户。我是说,我用的是超级用户。理论上,这里没有限制,因为我是超级用户,不是吗?我作为超级用户正在尝试插入和删除表记录。但我却犯了这个错误
下面是给我带来错误的代码:
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('ID' , 'USU_ID' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Login' , 'USU_LOGIN' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Senha' , 'USU_SENHA' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Apelido' , 'USU_APELIDO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Nascimento' , 'USU_NASCIMENTO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Cadastro' , 'USU_CADASTRO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Gênero' , 'USU_GENERO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Privilégio' , 'USU_PRIVILEGIO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('CEP' , 'USU_CEP' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Número Residencial' , 'USU_NUMERO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
INSERT INTO regrast.TB_DADOS (DAD_NOME_VISUAL , DAD_NOME_COLUNA , DAD_TABELA) VALUES ('Complemento' , 'USU_COMPLEMENTO' , (SELECT tba_id FROM regrast.tb_tabelas WHERE tba_nome ILIKE 'tb_usu%' LIMIT 1));
如果我对此进行评论,一切正常。对。关于更改表的共享功能,您有几个选项
使用INHERIT NOLOGIN
)为该角色分配所有权,并将该角色授予需要修改结构的任何人。添加这些选项的原因是,这不是一个登录角色,而是一个管理共享权限的角色。授予此角色的权限(以及所有权!)在授予此权限的所有角色之间共享 CREATE USER myuser;
现在以myuser身份登录:
CREATE TABLE ctest1 (id int primary key);
INSERT INTO ctest1 (id) SELECT generate_series(0, 10);
CREATE TABLE ctest2 (id int references ctest1(id) on delete cascade);
INSERT INTO ctest2 (id) SELECT generate_series(0, 10);
REVOKE ALL ON ctest2 FROM myuser; -- nonsuperuser owner
现在以postgres(超级用户)身份登录:
您正在pgadmin中连接哪个用户?您是作为DBAGRENTE还是dbadirector连接的?您好@Isilva。如前所述,我使用的是PostgreSQL的默认用户,
postgres
user。我还尝试将dbadiretor
用作超级用户,但仍然失败。所有这些细节都在问题上。嗨@Isilva,我刚刚编辑了我的问题。嗨@Chris Travers。Th
CREATE USER myuser;
CREATE TABLE ctest1 (id int primary key);
INSERT INTO ctest1 (id) SELECT generate_series(0, 10);
CREATE TABLE ctest2 (id int references ctest1(id) on delete cascade);
INSERT INTO ctest2 (id) SELECT generate_series(0, 10);
REVOKE ALL ON ctest2 FROM myuser; -- nonsuperuser owner
DELETE FROM ctest1 WHERE id = 4;
-- throws the error
GRANT DELETE ON ctest2 TO myuser;
DELETE FROM ctest1 WHERE id = 4;
-- throws the error
GRANT SELECT ON ctest2 TO myuser;
DELETE FROM ctest1 WHERE id = 4; -- success