How do you create a read-only user in PostgreSQL?
我想在PostgreSQL中创建一个只能从特定数据库中进行选择的用户。在mysql中,命令是:
1 | GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy'; |
PostgreSQL中的等效命令或一系列命令是什么?
我试过…
1 2 | postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy'; postgres=# GRANT SELECT ON DATABASE mydb TO xxx; |
但在数据库上,您只能授予create、connect、temporary和temp。
向单个表授予使用/选择权限
如果只授予连接到数据库的权限,则用户可以连接,但没有其他权限。您必须在名称空间(模式)上授予使用权限,并在表和视图上分别进行选择,如下所示:
1 2 3 4 | GRANT CONNECT ON DATABASE mydb TO xxx; -- This assumes you're actually connected to mydb.. GRANT USAGE ON SCHEMA public TO xxx; GRANT SELECT ON mytable TO xxx; |
多个表/视图(PostgreSQL 9.0+)
在最新版本的PostgreSQL中,您可以使用单个命令授予模式中所有表/视图/etc的权限,而不必逐个键入它们:
1 | GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx; |
这只影响已经创建的表。更强大的是,您可以在将来自动将默认角色分配给新对象:
1 2 | ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO xxx; |
注意,默认情况下,这只会影响由发出此命令的用户创建的对象(表):尽管它也可以设置在发出用户所属的任何角色上。但是,在创建新对象时,您不会为您所属的所有角色获取默认权限…所以仍然有一些虚伪。如果采用数据库具有所属角色的方法,并且模式更改作为该所属角色执行,则应将默认权限分配给该所属角色。imho这一切都有点令人困惑,您可能需要进行实验,才能想出一个功能性的工作流。
多个表/视图(9.0之前的PostgreSQL版本)为了避免长时间、多表更改中的错误,建议使用以下"自动"过程为每个表/视图生成所需的
1 2 3 | SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;' FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S'); |
这应该输出相关的GRANT命令,以在公共的所有表、视图和序列上授予SELECT,以便进行复制粘贴操作。当然,这只适用于已经创建的表。
请注意,PostgreSQL 9.0(现在是beta测试版)将有一个简单的方法:
1 2 | test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser; GRANT |
以下是我找到的添加只读用户的最佳方法(使用PostgreSQL 9.0或更高版本):
1 2 3 | $ sudo -upostgres psql postgres postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE'; postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly; |
然后登录到所有相关的机器(master+read slave(s)/hot standby(s)等)并运行:
1 2 | $ echo"hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf $ sudo service postgresql reload |
引用自此日志:
创建只读用户的脚本:
1 2 | CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity'; |
将权限分配给此只读用户:
1 2 3 4 | GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User; GRANT USAGE ON SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User; |
默认情况下,新用户将具有创建表的权限。如果计划创建只读用户,这可能不是您想要的。
要使用PostgreSQL 9.0+创建真正的只读用户,请运行以下步骤:
1 2 3 4 5 6 7 8 9 10 | # This will prevent DEFAULT users FROM creating TABLES REVOKE CREATE ON SCHEMA public FROM public; # IF you want TO GRANT a WRITE USER permission TO CREATE TABLES # note that superusers will always be able TO CREATE TABLES anyway GRANT CREATE ON SCHEMA public TO writeuser; # Now CREATE the read-ONLY USER CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser; |
如果只读用户没有列出表的权限(即
1 2 3 4 5 | # You can either GRANT USAGE TO everyone GRANT USAGE ON SCHEMA public TO public; # OR GRANT it just TO your READ ONLY USER GRANT USAGE ON SCHEMA public TO readonlyuser; |
我已经为它创建了一个方便的脚本:pg_grant_read_to_db.sh。这个脚本将只读权限授予数据库架构中所有表、视图和序列的指定角色,并将其设置为默认值。
如果您的数据库在公共模式中,那么很容易(假设您已经创建了
1 2 3 4 5 6 | db=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser; GRANT db=> GRANT CONNECT ON DATABASE mydatabase TO readonlyuser; GRANT db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonlyuser; GRANT |
如果您的数据库正在使用
1 2 | db=> ALTER USER readonlyuser SET search_path=customschema, public; ALTER ROLE |
我读过所有可能的解决方案,这些都是好的,如果你记得连接到数据库之前,你授予的东西;)无论如何感谢所有其他的解决方案!!!!
1 | USER@server:~$ sudo su - postgres |
创建psql用户:
1 2 3 4 5 | postgres@server:~$ createuser --interactive Enter name OF ROLE TO ADD: readonly Shall the NEW ROLE be a superuser? (y/n) n Shall the NEW ROLE be allowed TO CREATE DATABASES? (y/n) n Shall the NEW ROLE be allowed TO CREATE more NEW roles? (y/n) n |
启动psql cli并为创建的用户设置密码:
1 2 3 4 5 6 | postgres@server:~$ psql psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14) TYPE"help" FOR help. postgres=# ALTER USER readonly WITH password 'readonly'; ALTER ROLE |
连接到目标数据库:
1 2 3 | postgres=# \c target_database psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14) You are now connected TO DATABASE"target_database" AS USER"postgres". |
授予所有需要的特权:
1 2 3 4 5 6 7 8 | target_database=# GRANT CONNECT ON DATABASE target_database TO readonly; GRANT target_database=# GRANT USAGE ON SCHEMA public TO readonly ; GRANT target_database=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly ; GRANT |
更改目标db public shema的默认权限:
1 2 | target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly; ALTER DEFAULT PRIVILEGES |
不简单的方法是在数据库的每个表上授予select:
1 | postgres=# GRANT SELECT ON db_name.table_name TO read_only_user; |
您可以通过从数据库元数据生成GRANT语句来实现自动化。
取自为响应Despesz链接而发布的链接。
Postgres9.x似乎具有执行请求的功能。见数据库对象授权段落:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
其中说:"在一个或多个模式中,还可以选择授予同一类型的所有对象特权。目前,只有表、序列和函数才支持此功能(但请注意,所有表都被视为包括视图和外部表)。"
本页还讨论角色的使用和称为"所有特权"的特权。
还提供了有关如何将Grant功能与SQL标准进行比较的信息。