说明:以下操作postgres用户是超级用户
1 建立自己的业务库(我这里root用户执行)
-- 用户:postgres(或具有CREATEDB权限的用户)
CREATE DATABASE myapp_db
ENCODING 'UTF8'
OWNER root; -- 设置所有者
2 创建业务库的用户(我这里root用户执行)
-- 用户:postgres(或具有CREATEROLE权限的用户)
CREATE USER app_admin WITH
PASSWORD 'AdminPass123!'
NOSUPERUSER
NOCREATEDB -- 不能创建数据库
NOCREATEROLE -- 不能创建用户
LOGIN;
3 授予用户对数据库的连接权限(我这里root用户执行)
-- 用户:数据库所有者或超级用户执行
GRANT CONNECT ON DATABASE myapp_db TO app_admin;
复制代码
4 连接/切换到业务数据库(myapp_db )继续授权
我这里是DBeaver工具上新建连接以root用户登录,连接到新建的myapp_db库进行操作。也就是执行授权的用户还是root.
-- 操作:授予schema权限(必须在目标数据库中执行,这里就是myapp_db)
-- 用户:postgres(或schema所有者)(我这里root用户执行,root拥有public模式[SCHEMA])
GRANT CREATE, USAGE ON SCHEMA public TO app_admin;
5 设置新建用户的默认权限
-- 操作:设置默认权限(影响未来创建的对象)
-- 用户:postgres(我这里root用户执行)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON TABLES TO app_admin;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT ALL ON SEQUENCES TO app_admin;
个人记录:这里的授权貌似一种继承关系,用户A拥有的权限才有可能授予给B。
3. 建表及测试
复制代码
1 用新用户(app_admin)登录
新建一个DBeaver连接,使用app_admin用户登录myapp_db库。
2 创建表
-- 用户:app_admin执行
CREATE TABLE test_table (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
--添加数据, 用户:app_admin执行
INSERT INTO test_table (name) VALUES ('测试数据');
SELECT * FROM test_table;
3 测试越权操作(应该失败)
-- 用户:app_admin执行
CREATE DATABASE my_db2; -- 失败:无CREATEDB权限
CREATE USER my_user2; -- 失败:无CREATEROLE权限
4. 更细粒度的权限控制
复制代码
-- 创建不同权限级别的用户
-- 只读用户
CREATE USER app_readonly WITH PASSWORD 'ReadonlyPass!';
GRANT CONNECT ON DATABASE myapp_db TO app_readonly;
\c myapp_db --这是命令行指令,不是SQL语句
GRANT USAGE ON SCHEMA public TO app_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;
-- 读写用户(应用使用)
CREATE USER app_rw WITH PASSWORD 'RwPass!';
GRANT CONNECT ON DATABASE myapp_db TO app_rw;
\c myapp_db --这是命令行指令,不是SQL语句
GRANT USAGE ON SCHEMA public TO app_rw;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_rw;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO app_rw;
-- 创建专门的 schema 进行隔离(不同业务模块使用不同 schema)
\c myapp_db postgres -- 用超级用户连接,这是命令行指令,不是SQL语句
CREATE SCHEMA finance;
GRANT USAGE ON SCHEMA finance TO app_admin;
-- 5.3 权限委派(app_admin 可以授权给他人)
-- 超级用户执行:
GRANT app_admin TO some_other_user; -- 让其他用户继承 app_admin 角色