Docs/数据库/postgresql/理解PostgreSQL中的权限.txt
2022-10-18 16:59:37 +08:00

356 lines
No EOL
13 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

在postgresql中database,schema,table之间关系
从逻辑上看schema、table都是位于database之下。在postgres数据库下建立表(相当于建立在public schema下)理解pg下的权限
\dp - lists table/view permissions
\dn+ - lists schema permissions
\l+ does not list all users that can access the database
using psql from postgres 8.4 and postgres 9.0, and the command \l or \l+ gives me column Access Privileges where I have entry:
<user_name>=c/<database_name>
\dp显示的项解释如下
角色名=xxxx -- 被授予给一个角色的特权
=xxxx -- 被授予给 PUBLIC 的特权
r -- SELECT ("读")
w -- UPDATE ("写")
a -- INSERT ("追加")
d -- DELETE
D -- TRUNCATE
x -- REFERENCES
t -- TRIGGER
X -- EXECUTE
U -- USAGE
C -- CREATE
c -- CONNECT
T -- TEMPORARY
arwdDxt -- ALL PRIVILEGES (对于表,对其他对象会变化)
* -- 用于前述特权的授权选项
/yyyy -- 授予该特权的角色
在PostgreSQL中可以把角色划分为如下几类
SELECT该权限用来查询表或是表上的某些列或是视图序列。
INSERT该权限允许对表或是视图进行插入数据操作也可以使用COPY FROM进行数据的插入。
UPDATE该权限允许对表或是或是表上特定的列或是视图进行更新操作。
DELETE该权限允许对表或是视图进行删除数据的操作。
TRUNCATE允许对表进行清空操作。
REFERENCES允许给参照列和被参照列上创建外键约束。
TRIGGER允许在表上创建触发器。
CREATE对于数据库允许在数据库上创建Schema对于Schema允许对Schema上创建数据库对象对于表空间允许把表或是索引指定到对应的表空间上。
CONNECT允许用户连接到指定的数据库上。
TEMPORARY或是TEMP允许在指定数据库的时候创建临时表。
EXECUTE允许执行某个函数。
USAGE对于程序语言来说允许使用指定的程序语言创建函数对于Schema来说允许查找该Schema下的对象对于序列来说允许使用currval和nextval函数对于外部封装器来说允许使用外部封装器来创建外部服务器对于外部服务器来说允许创建外部表。
ALL PRIVILEGES表示一次性给予可以授予的权限。
创建两个测试账号
create role web login connection limit 9 password 'web_app';
create role mobile login connection limit 9 password 'mob_ile';
ALTER DEFAULT PRIVILEGES IN SCHEMA dba GRANT SELECT ON TABLES TO mobile;
没有起到作用,用下面的语句:
GRANT SELECT ON ALL TABLES IN SCHEMA dba TO mobile;
从dba终端看是有权限的但mobile中用\dpp却看不到难道要重新登录一下
重新登录后也看不到,试试下面的规则:
GRANT CONNECT ON DATABASE dba TO mobile;
GRANT USAGE ON SCHEMA dba TO mobile;
GRANT SELECT ON ALL TABLES IN SCHEMA dba TO mobile;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA dba to mobile;
单表授权
GRANT SELECT,INSERT,UPDATE ON TABLE web9 TO web;
成功。
后来发现是search_path这个变量的问题在当前的变量中没有包含dba所以\dpp时看不见但从其中的表中取数据是可以的select * from dba.table limit 9;
If your read-only user doesn't have permission to list tables (i.e. \d returns no results), it's probably because you don't have USAGE permissions for the schema. USAGE is a permission that allows users to actually use the permissions they have been assigned. What's the point of this? I'm not sure. To fix:
# 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;
授权首先要能连接(connection)到数据库(pg_hba.conf)上,在模式上要有使用权限(usage),然后是其下的对象的操作权限(如果该对象可以再度分割,如表中有列,对列赋予不同的权限);可以对用户在给定的模式下设定权限(可批可零),或对给定的模式中指定默认的操作权限(批量)。
撤销权限
REVOKE CREATE ON SCHEMA public FROM public;
第一个 "public" 是模式,第二个 "public" 意思是"所有用户"。
GRANT SELECT ON ALL TABLES IN SCHEMA PUBLIC to freeoa_role; --赋予freeoa_role所有表的SELECT权限
特殊符号ALL代表所访问权限PUBLIC代表所有用户。
要把新的模式放到路径中来,我们用:
SET search_path TO myschema,"$user",public;
仅对本次会话有效,下次登录又要设置一下。
或者修改用户的搜索路径,这样即使下次登录也不用重新设置:
ALTER USER mobile SET search_path=dba, "$user",public;
修改模式默认的权限
alter default privileges in schema public grant select on tables to web;
比较通用的模式下对象授权方式多采用:先移除所有用户的所有权限,再有针对性的授权。
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM PUBLIC;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO user_name;
或者修改具体用户的默认权限
ALTER DEFAULT PRIVILEGES
FOR ROLE some_role -- Alternatively "FOR USER"
IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO user_name;
这是一个很开放的权限
grant all privileges on database dbname to dbuser;
grant是赋予用户schema下当前表的权限alter default privileges是赋予用户schema下表的默认权限这样以后新建表就不用再赋权限了。当我们创建只读账号的时候需要执行grant和alter default privileges。其次这样可很好地解决每次新建表就要赋一次权限的问题了。
alter default privileges in schema dba grant select,insert,update,delete on tables to mobile;
创建的普通用户默认是没有任何权限的。查看表等对象的权限可通过:\dpp来查看相当直观。
序列的权限与解决办法
在insert的时候指定列插入主键id是serial类型会默认走sequence的下一个值但前面只赋予了表的权限所以会出现下面的问题
postgres=> insert into t4 ( name ) values ( 'aa' );
ERROR: permission denied for sequence t4_id_seq
解决方法就是再赋一次sequence的值就行了
alter default privileges in schema public grant usage on sequences to user2;
删除用户
删除用户和组
删除用户和组很简单:
DROP ROLE role_name;
DROP ROLE IF EXISTS role_name;
删除组role只会删除组的role本身组的成员并不会被删除。
postgres=> \c - postgres
You are now connected to database "postgres" as user "postgres".
postgres=# drop role user2;
ERROR: role "user2" cannot be dropped because some objects depend on it
DETAIL: privileges for table t5
privileges for sequence t5_id_seq
privileges for default privileges on new sequences belonging to role postgres in schema public
privileges for table t4
privileges for default privileges on new relations belonging to role postgres in schema public
当我们删除用户的时候,会提示有权限依赖,所以我们要删除这些权限
postgres=# alter default privileges in schema public revoke usage on sequences from user2;
ALTER DEFAULT PRIVILEGES
postgres=# alter default privileges in schema public revoke select,insert,delete,update on tables from user2;
ALTER DEFAULT PRIVILEGES
postgres=# revoke select,insert,delete,update on all tables in schema public from user2;
REVOKE
postgres=# revoke usage on all sequences in schema public from user2;
REVOKE
postgres=# drop role user2;
DROP ROLE
Pg权限分为两部分一部分是“系统权限”或者数据库用户的属性可以授予role或user(两者区别在于login权限)一部分为数据库对象上的操作权限。对超级用户不做权限检查其它走acl。对于数据库对象开始只有所有者和超级用户可以做任何操作其它走acl。在pg里对acl模型做了简化组和角色都是role。数据库对象上的权限有SELECTINSERTUPDATEDELETERULEREFERENCESTRIGGERCREATETEMPORARYEXECUTE 和 USAGE等。
可以用特殊的名字 PUBLIC 把对象的权限赋予系统中的所有角色。 在权限声明的位置上写 ALL表示把适用于该对象的所有权限都赋予目标角色。
视图 pg_roles提供访问数据库角色有关信息的接口。 它只是一个 pg_authid 表的公开可读部分的视图,把口令字段用空白填充了。
pg_roles字段
名字
类型
引用
描述
rolname
name
角色名
rolsuper
bool
有超级用户权限的角色
rolcreaterole
bool
可以创建更多角色的角色
rolcreatedb
bool
可以创建数据库的角色
rolcatupdate
bool
可以直接更新系统表的角色。(除非这个字段为真,否则超级用户也不能干这个事情。)
rolcanlogin
bool
可以登录的角色,也就是说,这个角色可以给予初始化会话认证的标识符。
rolpassword
text
不是口令(总是 ********
rolvaliduntil
timestamptz
口令失效日期(只用于口令认证);如果没有失效期,为 NULL
rolconfig
text[]
运行时配置变量的会话缺省
角色属性(Role Attributes)
一个数据库角色可以有一系列属性,这些属性定义了他的权限。
属性 说明
login 只有具有 LOGIN 属性的角色可以用做数据库连接的初始角色名。
superuser 数据库超级用户
createdb 创建数据库权限
createrole 允许其创建或删除其他普通的用户角色(超级用户除外)
replication 做流复制的时候用到的一个用户属性,一般单独设定。
password 在登录时要求指定密码时才会起作用比如md5或者password模式跟客户端的连接认证方式有关
inherit 用户组对组员的一个继承标志,成员可以继承用户组的权限特性
在psql中的查看权限的快捷指令
\dn[S+] [PATTERN] 列出所有模式
\dp [模式] 列出表,视图和序列的访问权限,同\z
\du[S+] [PATTERN] 列出角色
\ddp [模式] 列出默认权限
\drds [模式1 [模式2]] 列出每个数据库的角色设置
database、schema、table_seq_view_etc、table_column 分4个级别来授权。
查看pg_hba.conf 文件在角色属性中关于password的说明在登录时要求指定密码时才会起作用比如md5或者password模式跟客户端的连接认证方式有关。
给已存在用户赋权限
使用ALTER ROLE 命令。
ALTER ROLE name RENAME TO new_name
ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT }
ALTER ROLE name [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT
ALTER ROLE name [ IN DATABASE database_name ] RESET configuration_parameter
ALTER ROLE name [ IN DATABASE database_name ] RESET ALL
为角色成员赋权
查看角色信息
psql 终端可以用\du 或\du+ 查看,也可以查看系统表
select * from pg_roles;
select * from pg_user;
在系统的角色管理中通常会把多个角色赋予一个组这样在设置权限时只需给该组设置即可撤销权限时也是从该组撤销。在PostgreSQL中首先需要创建一个代表组的角色之后再将该角色的membership 权限赋给独立的角色即可。
创建组角色
# CREATE ROLE father login nosuperuser nocreatedb nocreaterole noinherit encrypted password 'freeoa';
给father 角色赋予数据库test 连接权限和相关表的查询权限。
# GRANT CONNECT ON DATABASE test to father;
test=> GRANT USAGE ON SCHEMA public to father;
WARNING: no privileges were granted for "public"
test=> GRANT SELECT on public.emp to father;
创建成员角色
test=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
# CREATE ROLE son1 login nosuperuser nocreatedb nocreaterole inherit encrypted password 'freeoa.net';
这里创建了son1 角色并开启inherit 属性。PostgreSQL 里的角色赋权是通过角色继承(INHERIT)的方式实现的。
将father 角色赋给son1
# GRANT father to son1;
还有另一种方法,就是在创建用户的时候赋予角色权限。
# CREATE ROLE son2 login nosuperuser nocreatedb nocreaterole inherit encrypted password 'freeoa.net' in role father;
用户在public模式下创建的表对于其它用户能看到但查不了会报"对关系 prv 权限不够",除非你是这个库的属主。
可以通过函数来验证模式下的表的相应权限:
select has_table_privilege('public.table1','select');
select has_table_privilege('dba.webcon_cid_seq','update');
对sequence类型的授权
select 什么都做不了usage有currval,nextval这两个函数可用setval不可用要使用setval就必须有update权限。
grant usage on sequence web_cid_seq to some_user;
切换ROLE
SET ROLE role_name; --切换到role_name用户
RESET ROLE; --切换回最初的role
INHERIT权限该属性使组成员拥有组的所有权限
ALTER ROLE freeoa_user INHERIT;
通过以下方式禁止用户登录
ALTER ROLE username WITH NOLOGIN;
第三方的小工具
somebody created a convenient script for that; pg_grant_read_to_db.sh. This script grants read-only privileges to a specified role on all tables, views and sequences in a database schema and sets them as default.
url:https://gist.github.com/jirutka/afa3ce62b1430abf7572
参考来源
GRANT[http://postgres.cn/docs/9.5/sql-grant.html]
ALTER DEFAULT PRIVILEGES[http://postgres.cn/docs/9.5/sql-alterdefaultprivileges.html]