你如何在PostgreSQL中创build只读用户?
我想在PostgreSQL中创build一个只能从一个特定的数据库执行SELECT操作的用户。 在MySQL中,命令是:
GRANT SELECT ON mydb.* TO 'xxx'@'%' IDENTIFIED BY 'yyy';
什么是PostgreSQL中的等价命令或一系列命令?
我试过了…
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy'; postgres=# GRANT SELECT ON DATABASE mydb TO xxx;
但是看起来,您可以授予数据库的唯一东西是CREATE,CONNECT,TEMPORARY和TEMP。
将使用/select授予一个表
如果您只授予连接到数据库,用户可以连接,但没有其他权限。 你必须像这样分别在表和视图上的名字空间(模式)和SELECT上授予USAGE:
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的权限,而不必逐个input它们:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;
这只会影响已经创build的表。 更有力的是,您可以在将来自动将默认angular色分配给新对象 :
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO xxx;
请注意,默认情况下,这只会影响发出此命令的用户创build的对象(表):尽pipe它也可以在颁发用户所属的任何angular色上设置。 但是,在创build新对象时,您不会为您所属的所有angular色select默认权限…所以仍然存在一些问题。 如果您采用数据库拥有自己的angular色的方法,并且架构更改作为拥有angular色执行,那么您应该将默认权限分配给该拥有angular色。 恕我直言,这是有点混乱,你可能需要尝试提出一个function的工作stream程。
多个表/视图(9.0之前的PostgreSQL版本)
为了避免冗长的多表更改错误,build议使用以下“自动”过程为每个表/视图生成所需的GRANT SELECT
:
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命令GRANT SELECT在所有表,视图和序列在公共,复制粘贴爱。 当然,这只适用于已经创build的表格。
请注意,PostgreSQL 9.0(今天在betatesting中)将有一个简单的方法来做到这一点 :
test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser; GRANT
下面是我发现添加只读用户(使用PostgreSQL 9.0或更新版本)的最佳方式:
$ 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;
然后login到所有相关的机器(主机+读取从机/热备份等),然后运行:
$ 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
我为此创build了一个方便的脚本。 pg_grant_read_to_db.sh 。 此脚本将只读权限授予数据库模式中所有表,视图和序列上的指定angular色,并将其设置为默认值。
默认情况下,新用户将有权创build表。 如果您打算创build一个只读用户,这可能不是你想要的。
要使用PostgreSQL 9.0+创build一个真正的只读用户,请运行以下步骤:
# 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;
如果您的只读用户没有权限列出表(即\d
返回任何结果),则可能是因为您没有该模式的USAGE
权限。 USAGE
是允许用户实际使用已分配的权限的权限。 这是什么意思? 我不确定。 修理:
# 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;
从这个博客引用:
脚本创build只读用户:
CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234' NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
为此只读用户分配权限:
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;
不直接的做法是在数据库的每个表格上selectselect:
postgres=# grant select on db_name.table_name to read_only_user;
您可以通过从数据库元数据生成授权语句来自动执行该操作。
如果你的数据库处于公共模式,这很容易(假设你已经创build了readonlyuser
)
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
如果你的数据库使用的是customschema
,那么执行上面的命令但是再添加一个命令:
db=> ALTER USER readonlyuser SET search_path=customschema, public; ALTER ROLE
从一个链接张贴回应despesz'链接。
Postgres 9.x似乎有能力做到要求。 请参阅数据库对象授予段落:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
它说:“还有一个选项可以在一个或多个模式中为同一types的所有对象授予特权。这个function目前只支持表,序列和函数(但是请注意,所有的表都被认为包含了视图和外国表)“。
这个页面还讨论了ROLEs和称为“所有特权”的特权的使用。
还有关于GRANTfunction如何与SQL标准进行比较的信息。