Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确定义角色和权限(案例研究-PostgreSQL)?_Sql_Database_Postgresql_Roles_Privileges - Fatal编程技术网

如何正确定义角色和权限(案例研究-PostgreSQL)?

如何正确定义角色和权限(案例研究-PostgreSQL)?,sql,database,postgresql,roles,privileges,Sql,Database,Postgresql,Roles,Privileges,不久前,我来到社区询问我正在开发的系统的触发器的定义。我仍然发现自己在开发同样的系统,现在我对角色产生了怀疑。我对使用PostgreSQL还不熟悉,即使在阅读文档之后,我也会遇到一些问题 为了开发我的系统,我创建了3个用户: dbadiretor(翻译成dbadirector):它的行为类似于DBA,仅由一个人使用 dbagerente(翻译成dbamanager):它是一个用户,能够在不需要更改表结构的情况下更改表结构 操纵它的数据。该用户还可以创建 触发器、函数、索引等 clisistem

不久前,我来到社区询问我正在开发的系统的触发器的定义。我仍然发现自己在开发同样的系统,现在我对角色产生了怀疑。我对使用PostgreSQL还不熟悉,即使在阅读文档之后,我也会遇到一些问题

为了开发我的系统,我创建了3个用户:

  • dbadiretor(翻译成dbadirector):它的行为类似于DBA,仅由一个人使用
  • dbagerente(翻译成dbamanager):它是一个用户,能够在不需要更改表结构的情况下更改表结构 操纵它的数据。该用户还可以创建 触发器、函数、索引等
  • clisistema(翻译成clisystem):它是具有 连接到数据库。该用户可以执行CRUD操作, 但无法在中创建、删除、修改或删除现有对象 数据库对于某些表,此用户已筛选其权限
创建用户、表、简单数据和设置权限后,pgAdmin向我显示以下消息:

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));

如果我对此进行评论,一切正常。

对。关于更改表的共享功能,您有几个选项

  • 您可以将dba用户设置为超级用户(这将绕过此用户的权限检查)或

  • 您可以创建另一个角色(
    使用INHERIT NOLOGIN
    )为该角色分配所有权,并将该角色授予需要修改结构的任何人。添加这些选项的原因是,这不是一个登录角色,而是一个管理共享权限的角色。授予此角色的权限(以及所有权!)在授予此权限的所有角色之间共享

  • 对于select用户被拒绝的权限,您使用的是dbagerente用户吗?如果是这样的话,那是因为您撤销了对此的权限。如果不是,您使用的是哪个用户名

    编辑。请注意,这种类型的RI触发器作为表所有者运行,因此表所有者必须具有对级联表的写访问权限,才能从中删除

    您可以通过以下方式进行测试(在回滚的事务中):

    所以这里的问题是表所有者没有访问权限。根据我的经验,我必须添加授予表所有者的select和delete特权(如果您也有on update,则可能需要update)\

    EDIT2:如何复制

     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