356 lines
No EOL
13 KiB
Text
356 lines
No EOL
13 KiB
Text
在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。数据库对象上的权限有:SELECT,INSERT,UPDATE,DELETE,RULE,REFERENCES,TRIGGER,CREATE,TEMPORARY,EXECUTE 和 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] |