PostgreSQL 用户权限管理 #

用户与角色概述 #

PostgreSQL 使用角色(Role)来管理权限,用户本质上是可以登录的角色。

text
┌─────────────────────────────────────────────────────────────┐
│                    角色类型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  角色(Role)                                               │
│  ├── 可以拥有数据库对象                                    │
│  ├── 可以拥有权限                                          │
│  └── 可以包含其他角色                                      │
│                                                             │
│  用户(可以登录的角色)                                      │
│  ├── 具有 LOGIN 属性                                       │
│  └── 可以连接数据库                                        │
│                                                             │
│  组角色(不能登录)                                          │
│  ├── 没有 LOGIN 属性                                       │
│  └── 用于权限分组                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

创建角色 #

CREATE ROLE 语法 #

sql
CREATE ROLE role_name [ WITH ] option [ ... ];

-- 常用选项:
-- LOGIN / NOLOGIN          - 是否可以登录
-- SUPERUSER / NOSUPERUSER  - 是否为超级用户
-- CREATEDB / NOCREATEDB    - 是否可以创建数据库
-- CREATEROLE / NOCREATEROLE - 是否可以创建角色
-- INHERIT / NOINHERIT      - 是否继承所属角色的权限
-- PASSWORD 'password'      - 设置密码
-- VALID UNTIL 'timestamp'  - 密码有效期
-- IN ROLE role_name        - 加入指定角色
-- ROLE role_name           - 包含指定角色

创建用户 #

sql
-- 创建可登录的用户
CREATE USER app_user WITH PASSWORD 'secure_password';

-- 等价于
CREATE ROLE app_user WITH LOGIN PASSWORD 'secure_password';

-- 创建带更多属性的用户
CREATE USER admin_user WITH
    PASSWORD 'admin_password'
    CREATEDB
    CREATEROLE
    VALID UNTIL '2026-12-31';

-- 创建超级用户(需要超级用户权限)
CREATE USER super_user WITH SUPERUSER PASSWORD 'super_password';

-- 创建只读用户
CREATE USER readonly_user WITH PASSWORD 'readonly_password';

创建组角色 #

sql
-- 创建组角色(不能登录)
CREATE ROLE read_only;
CREATE ROLE read_write;
CREATE ROLE admin;

-- 创建用户并加入组
CREATE USER analyst WITH PASSWORD 'analyst_password' IN ROLE read_only;
CREATE USER developer WITH PASSWORD 'dev_password' IN ROLE read_write;

修改角色 #

sql
-- 修改密码
ALTER USER app_user WITH PASSWORD 'new_password';

-- 添加属性
ALTER USER app_user WITH CREATEDB;

-- 移除属性
ALTER USER app_user WITH NOCREATEDB;

-- 设置密码有效期
ALTER USER app_user WITH VALID UNTIL '2026-06-30';

-- 重命名角色
ALTER USER app_user RENAME TO application_user;

-- 修改所有者
ALTER TABLE employees OWNER TO app_user;

删除角色 #

sql
-- 删除角色(必须先转移或删除其拥有的对象)
DROP ROLE app_user;

-- 如果存在则删除
DROP ROLE IF EXISTS app_user;

-- 查看角色拥有的对象
SELECT 
    n.nspname AS schema,
    c.relname AS object,
    c.relkind AS type
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relowner = (SELECT oid FROM pg_roles WHERE rolname = 'app_user');

-- 转移对象所有权
REASSIGN OWNED BY app_user TO postgres;

-- 删除角色拥有的对象
DROP OWNED BY app_user;

权限类型 #

权限分类 #

text
┌─────────────────┬─────────────────────────────────────────────┐
│ 权限            │ 说明                                        │
├─────────────────┼─────────────────────────────────────────────┤
│ SELECT          │ 查询数据                                    │
│ INSERT          │ 插入数据                                    │
│ UPDATE          │ 更新数据                                    │
│ DELETE          │ 删除数据                                    │
│ TRUNCATE        │ 清空表                                      │
│ REFERENCES      │ 创建外键引用                                │
│ TRIGGER         │ 创建触发器                                  │
│ CREATE          │ 创建对象(数据库/模式/表)                  │
│ CONNECT         │ 连接数据库                                  │
│ TEMPORARY       │ 创建临时表                                  │
│ EXECUTE         │ 执行函数/过程                               │
│ USAGE           │ 使用模式/序列/类型                          │
│ ALL             │ 所有权限                                    │
└─────────────────┴─────────────────────────────────────────────┘

授予权限 #

GRANT 语法 #

sql
-- 授予表权限
GRANT SELECT, INSERT, UPDATE, DELETE ON table_name TO role_name;
GRANT ALL PRIVILEGES ON table_name TO role_name;

-- 授予列权限
GRANT SELECT (column1, column2) ON table_name TO role_name;
GRANT UPDATE (column1) ON table_name TO role_name;

-- 授予序列权限
GRANT USAGE, SELECT ON SEQUENCE sequence_name TO role_name;

-- 授予数据库权限
GRANT CONNECT, TEMPORARY ON DATABASE database_name TO role_name;
GRANT ALL PRIVILEGES ON DATABASE database_name TO role_name;

-- 授予模式权限
GRANT USAGE, CREATE ON SCHEMA schema_name TO role_name;
GRANT ALL PRIVILEGES ON SCHEMA schema_name TO role_name;

-- 授予函数权限
GRANT EXECUTE ON FUNCTION function_name TO role_name;

-- 授予所有表的权限
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO read_write;

-- 授予所有序列的权限
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO read_write;

授予角色成员关系 #

sql
-- 将用户加入角色
GRANT read_only TO analyst;
GRANT read_write TO developer;
GRANT admin TO admin_user;

-- 授予多个角色
GRANT read_only, read_write TO power_user;

-- 授予 WITH ADMIN OPTION(可以再将此角色授予他人)
GRANT admin TO admin_user WITH ADMIN OPTION;

撤销权限 #

REVOKE 语法 #

sql
-- 撤销表权限
REVOKE SELECT, INSERT ON table_name FROM role_name;
REVOKE ALL PRIVILEGES ON table_name FROM role_name;

-- 撤销列权限
REVOKE SELECT (column1) ON table_name FROM role_name;

-- 撤销数据库权限
REVOKE CONNECT ON DATABASE database_name FROM role_name;

-- 撤销模式权限
REVOKE USAGE ON SCHEMA schema_name FROM role_name;

-- 撤销所有表的权限
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM role_name;

-- 撤销角色成员关系
REVOKE read_only FROM analyst;

-- 撤销 WITH ADMIN OPTION
REVOKE ADMIN OPTION FOR admin FROM admin_user;

默认权限 #

ALTER DEFAULT PRIVILEGES #

sql
-- 设置默认权限(新创建的对象自动获得权限)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO read_only;

ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO read_write;

ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE ON SEQUENCES TO read_write;

-- 查看默认权限
SELECT 
    pg_get_userbyid(defaclrole) AS role,
    n.nspname AS schema,
    defaclobjtype AS object_type,
    defaclacl AS privileges
FROM pg_default_acl d
JOIN pg_namespace n ON n.oid = d.defaclnamespace;

角色继承 #

INHERIT 属性 #

sql
-- 创建带 INHERIT 属性的角色
CREATE ROLE child_role INHERIT;
CREATE ROLE parent_role;

GRANT parent_role TO child_role;

-- child_role 自动继承 parent_role 的权限

-- 创建不继承的角色
CREATE ROLE no_inherit_role NOINHERIT;
GRANT parent_role TO no_inherit_role;

-- no_inherit_role 不会自动继承权限
-- 需要使用 SET ROLE 显式切换
SET ROLE parent_role;

SET ROLE #

sql
-- 切换到指定角色
SET ROLE read_only;

-- 执行操作
SELECT * FROM employees;

-- 恢复原角色
RESET ROLE;

-- 查看当前角色
SELECT current_role;
SELECT current_user;
SELECT session_user;

查看权限 #

查看角色信息 #

sql
-- 查看所有角色
SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin
FROM pg_roles;

-- 使用 psql 命令
\du
\du+ role_name

查看权限 #

sql
-- 查看表权限
SELECT 
    grantee,
    table_schema,
    table_name,
    privilege_type
FROM information_schema.table_privileges
WHERE table_name = 'employees';

-- 查看列权限
SELECT 
    grantee,
    table_name,
    column_name,
    privilege_type
FROM information_schema.column_privileges
WHERE table_name = 'employees';

-- 查看数据库权限
SELECT 
    datname,
    datacl
FROM pg_database;

-- 查看模式权限
SELECT 
    nspname,
    nspacl
FROM pg_namespace;

-- 使用 psql 命令
\dp table_name
\l+  -- 数据库权限
\dn+ -- 模式权限

权限最佳实践 #

最小权限原则 #

sql
-- 创建只读角色
CREATE ROLE read_only;
GRANT CONNECT ON DATABASE mydb TO read_only;
GRANT USAGE ON SCHEMA public TO read_only;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT SELECT ON TABLES TO read_only;

-- 创建读写角色
CREATE ROLE read_write;
GRANT read_only TO read_write;
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO read_write;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO read_write;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT INSERT, UPDATE, DELETE ON TABLES TO read_write;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE ON SEQUENCES TO read_write;

-- 创建用户并分配角色
CREATE USER app_readonly WITH PASSWORD 'xxx' IN ROLE read_only;
CREATE USER app_readwrite WITH PASSWORD 'xxx' IN ROLE read_write;

行级安全 #

sql
-- 启用行级安全
ALTER TABLE employees ENABLE ROW LEVEL SECURITY;

-- 创建策略:用户只能看到自己部门的数据
CREATE POLICY department_policy ON employees
    USING (department_id = current_user_department());

-- 创建策略函数
CREATE FUNCTION current_user_department() RETURNS INTEGER AS $$
    SELECT department_id FROM users WHERE name = current_user;
$$ LANGUAGE SQL SECURITY DEFINER;

-- 管理员可以看到所有数据
CREATE POLICY admin_all_access ON employees
    USING (current_user IN (SELECT name FROM users WHERE is_admin = TRUE));

-- 禁用行级安全
ALTER TABLE employees DISABLE ROW LEVEL SECURITY;

-- 删除策略
DROP POLICY department_policy ON employees;

密码管理 #

sql
-- 使用 scram-sha-256 加密(推荐)
-- 在 postgresql.conf 中设置:
-- password_encryption = 'scram-sha-256'

-- 设置密码
ALTER USER app_user WITH PASSWORD 'secure_password';

-- 设置密码有效期
ALTER USER app_user WITH VALID UNTIL '2026-12-31';

-- 强制用户下次登录修改密码
ALTER USER app_user WITH PASSWORD 'temp_password' VALID UNTIL 'now';

学习路径 #

text
运维阶段
├── 用户权限管理(本文)
├── 备份与恢复
└── 性能优化

下一步 #

掌握了用户权限管理后,接下来学习 备份与恢复,了解如何保护数据安全!

最后更新:2026-03-29