PostgreSQL权限管理实践

news/2025/11/26 23:10:36/文章来源:https://www.cnblogs.com/knlbase/p/19274917

基于user模型

模式和用户同名

只有一个模式

# postgres用户连接
psql -U postgres -c "create user test password 'test';"
psql -U postgres -c "create database testdb with owner=test;" 
psql -U postgres -d testdb -c "CREATE SCHEMA test AUTHORIZATION test;"
#test用户连接创建自定义对象:
psql -U test -d testdb -c "create table test_t(id int)"

这样的好处是,test用户连接testdb默认直接连接到了test模式,因为search_path默认值如下:

postgres=# select name,setting,unit,context from pg_settings where name ~* 'search_path';name     |     setting     | unit | context 
-------------+-----------------+------+---------search_path | "$user", public |      | user
(1 row)

test用户为读写用户,后期如果需要使用只读用户,直接创建用户授权即可

-- 1、创建用户及指定密码:
create user readonly with encrypted password 'readonly';
-- 2、设置用户默认事务只读:
alter user readonly set default_transaction_read_only=on;
-- 3、赋予用户连接数据库权限:
grant connect on database testdb to readonly;
-- 4、切换到指定数据库:
\c testdb
-- 5、赋予用户权限,查看public模式下所有表:
grant usage on schema public to readonly;
alter default privileges in schema public grant select on tables to readonly;
-- 6、赋予指定模式下用户表、序列查看权限:
grant usage on schema test to readonly;
grant select on all sequences in schema test to readonly;
grant select on all tables in schema test to readonly;
alter default privileges in schema test grant select on tables to readonly;

有多个模式

创建数据库

psql -U postgres -c "create user test password 'test';"
psql -U postgres -c "create database testdb with owner=test;"

创建业务用户和模式

psql -U postgres -c "create user user1 password 'user1';"
psql -U postgres -c "create user user2 password 'user2';"
psql -U postgres -d testdb -c "CREATE SCHEMA user1 AUTHORIZATION user1;"
psql -U postgres -d testdb -c "CREATE SCHEMA user2 AUTHORIZATION user2;"

给业务用户授权数据库权限

psql -U postgres -c "grant all privileges on database testdb to user1;"
psql -U postgres -c "grant all privileges on database testdb to user2;"

需要几个模式就创建几个用户,用户和模式同名,用户只允许在和自己同名的模式下创建自定义对象,可以授权其他模式的读权限

授权user2查询user1模式下的查询权限:

grant usage on schema user1 to user2;
grant select on all tables in schema user1 to user2;
alter default privileges in schema user1 grant select on tables to user2;

后期如果还需要创建只读用户,和只有一个模式创建只读用户的场景一样

模式和用户不同名

-- 创建父角色(不能登录,昨晚对象的属主)
create role test;
-- 业务用户
create user test1 password 'test1';
create user test2 password 'test2';
grant test to test1,test2;
-- 创建数据库
create database testdb with owner=test;
-- 创建模式
\c testdb
create schema test_schema authorization test;

业务用户test1连接testdb库,创建自定义对象

-- psql -U test1 -d testdb
create table test_schema.test_t(id int);

 注意此时test1用户创建的表test2用户无权访问(表的属主为test1)

可以把owner转为test用户即可

reassign owned by test1 to test;

基于role模型

权限管理设计模型

该模型简单有效,推荐绝大多数客户使用。

  • 1个RDS PostgreSQL高权限账号,具有所有权限,由少量资深DBA掌握。
  • 项目或者团队维度,1个资源owner账号,2个基本Role:{project}_role_readwrite{project}_role_readonly
  • 在Role的基础上创建业务账号:业务账号user = role + login权限
  • 1个项目或团队可以有多个Schema。权限分配尽量以Schema或Role为单位。
  • 业务表请勿放到schema public中。因为PostgreSQL默认所有用户对schema public都有CREATEUSAGE权限。

权限规划示例

本示例以项目维度进行权限管理示例,同样也适用于团队维度。

  • DBA拥有RDS PostgreSQL实例的高权限账号,名称是dbsuperuser。
  • 业务项目名称是rdspg,新建schema名称是rdspg、rdspg_1。

项目中新增的资源owner账号和Role规划如下:

user/Role schema中表权限 schema中存储过程权限
rdspg_owner (user),是唯一的项目资源owner账号 DDL:CREATE、DROP、ALTER
DQL:SELECT
DML:UPDATE、INSERT、DELETE
DDL:CREATE、DROP、ALTER
DQL:SELECT,调用存储过程
rdspg_role_readwrite (role) DQL:SELECT
DML:UPDATE、INSERT、DELETE
DQL(SELECT,调用存储过程) ,若存储过程有DDL操作,会抛出权限相关错误。
rdspg_role_readonly (role) DQL(SELECT) DQL(SELECT,调用存储过程),若存储过程有DDL或者DML操作,会抛出权限相关错误。

新增业务账号时,根据不同需求,采用如下管理模式创建:

  • rdspg_readwrite = rdspg_role_readwrite + login权限
  • rdspg_readonly = rdspg_role_readonly + login权限

配置步骤:

1、创建项目资源owner账号rdspg_owner和项目Role。DBA使用dbsuperuser高权限账号执行如下操作。

-- rdspg_owner 是项目管理账号
CREATE USER rdspg_owner WITH LOGIN PASSWORD 'asdfy181BASDfadasdbfas';
-- 创建业务数据库
create database testdb owner=rdspg_owner;
\c testdbCREATE ROLE rdspg_role_readwrite;
CREATE ROLE rdspg_role_readonly;-- 设置: 对于rdspg_owner 创建的表,rdspg_role_readwrite 有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON TABLES TO rdspg_role_readwrite;-- 设置: 对于rdspg_owner 创建的SEQUENCES,rdspg_role_readwrite 有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON SEQUENCES TO rdspg_role_readwrite;-- 设置: 对于 rdspg_owner 创建的表, rdspg_role_readonly 只有 DQL(SELECT)权限。
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT SELECT ON TABLES TO rdspg_role_readonly;

2、创建rdspg_readwrite、rdspg_readonly业务账号。DBA使用dbsuperuser高权限账号执行如下操作。

-- rdspg_readwrite只有 DQL(SELECT)、DML(UPDATE、INSERT、DELETE)权限。
CREATE USER rdspg_readwrite WITH LOGIN PASSWORD 'dfandfnapSDhf23hbEfabf';
GRANT rdspg_role_readwrite TO rdspg_readwrite;-- rdspg_readonly只有 DQL(SELECT)权限。
CREATE USER rdspg_readonly WITH LOGIN PASSWORD 'F89h912badSHfadsd01zlk';
GRANT rdspg_role_readonly TO rdspg_readonly;

3、创建schema rdspg,并授权给项目Role。DBA使用dbsuperuser高权限账号执行如下操作。

-- schema rdspg的owner是 rdspg_owner账号
CREATE SCHEMA rdspg AUTHORIZATION rdspg_owner;-- 授权ROLE相关SCHEMA访问权限。
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg TO rdspg_role_readonly;

**说明: **rdspg_readwrite和rdspg_readonly自动继承了相关Role的权限变更,不需要再额外操作。

应用场景示例

场景1:使用rdspg_owner账号:对schema rdspg中的表进行DDL(CREATE、DROP、ALTER)操作

\c testdb rdspg_owner
CREATE TABLE rdspg.test(id bigserial primary key, name text);
CREATE INDEX idx_test_name on rdspg.test(name);

场景2:使用 rdspg_readwrite/rdspg_readonly 账号进行业务开发

业务开发遵循最小权限原则,尽量使用rdspg_readonly账号,需要DML操作的地方才使用rdspg_readwrite账号。这样也方便在业务层做读写分离

说明:

  • 业务层做读写分离,避免了自动读写分离中间件proxy带来的额外成本和性能损耗。
  • 即使目前还没有使用只读实例,也建议区分 readonly客户端、readwrite客户端,为使用只读实例做准备。readonly客户端建议使用readonly账号,最小权限原则,规避权限误用。
  • readonly客户端,使用readonly账号,设置JDBC URL:只读实例1地址,只读实例2地址,读写实例地址
  • readwrite客户端,使用readwrite账号,设置JDBC URL:读写实例地址

使用rdspg_readwrite账号,对schema rdspg中的表进行DQL(SELECT)、DML(UPDATE、INSERT、DELETE)操作:

\c testdb rdspg_readwrite
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
SELECT id,name FROM rdspg.test LIMIT 1;-- rdspg_readwrite没有 DDL(CREATE、DROP、ALTER)权限
CREATE TABLE rdspg.test2(id int);
ERROR:  permission denied for schema rdspg
LINE 1: create table rdspg.test2(id int);DROP TABLE rdspg.test;
ERROR:  must be owner of table testALTER TABLE rdspg.test ADD id2 int;
ERROR:  must be owner of table testCREATE INDEX idx_test_name on rdspg.test(name);
ERROR:  must be owner of table test

使用rdspg_readonly账号,对schema rdspg中的表进行DQL(SELECT)操作:

\c testdb rdspg_readonly
INSERT INTO rdspg.test (name) VALUES('name0'),('name1');
ERROR:  permission denied for table testSELECT id,name FROM rdspg.test LIMIT 1;id | name
----+-------1 | name0
(1 row)

场景3:不同项目交叉授权

有个新项目employee,创建role和user以及授权如下:

\c testdb dbsuperuser
CREATE ROLE employee_role_readwrite;
CREATE ROLE employee_role_readonly;ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON TABLES TO employee_role_readwrite;
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT ALL ON SEQUENCES TO employee_role_readwrite;
ALTER DEFAULT PRIVILEGES FOR ROLE rdspg_owner GRANT SELECT ON TABLES TO employee_role_readonly;CREATE USER employee_readwrite WITH LOGIN PASSWORD 'dfandfnapSDhf23hbEfabf';
GRANT employee_role_readwrite TO employee_readwrite;
CREATE USER employee_readonly WITH LOGIN PASSWORD 'F89h912badSHfadsd01zlk';
GRANT employee_role_readonly TO employee_readonly;

现在需要为账号employee_readwrite增加rdspg项目的表只读权限。DBA使用dbsuperuser高权限账号做如下操作:

-- 给账号 employee_readwrite 加上 rdspg_role_readonly 权限集合。
\c testdb dbsuperuser
GRANT rdspg_role_readonly TO employee_readwrite;

场景4:项目新增 schema rdspg_1,并授权给项目Role

rdspg_readwrite、rdspg_readonly、employee_readwrite账号自动继承了相关Role的权限变更,不需要再额外操作。DBA使用dbsuperuser 高权限账号做如下操作:

\c testdb dbsuperuser
CREATE SCHEMA rdspg_1 AUTHORIZATION rdspg_owner;-- 授权ROLE相关SCHEMA访问权限。
-- CREATE 使得 rdspg_owner 对schema rdspg_1中的表有 DDL(CREATE、DROP、ALTER)权限。
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readwrite;
GRANT USAGE ON SCHEMA rdspg_1 TO rdspg_role_readonly;

账号权限查询

psql客户端,使用元命令\du查看所有用户和拥有的角色:

image-20251126230011754

从上述查询结果示例中可以看出:employee_readwrite账号的Member of列中,内容为rdspg_role_readonly,employee_role_readwrite,因此,此账号对employee项目表具有DQL和DML权限,对rdspg项目表具有DQL权限。

使用SQL查询

SELECT r.rolname, r.rolsuper, r.rolinherit,r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,r.rolconnlimit, r.rolvaliduntil,ARRAY(SELECT b.rolnameFROM pg_catalog.pg_auth_members mJOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)WHERE m.member = r.oid) as memberof
, r.rolreplication
, r.rolbypassrls
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;

参考资料

https://help.aliyun.com/zh/rds/apsaradb-rds-for-postgresql/manage-permissions-in-an-apsaradb-rds-for-postgesql-instance

https://support.huaweicloud.com/bestpractice-rds-pg/rds_pg_0035.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/977749.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

预编译命令

本文介绍了C/C++中的预编译命令,重点讲解了`#include`、`#define`、`#if`和`#pragma`的使用方法与注意事项。`#include`用于文件包含,支持尖括号和双引号两种查找方式,并可嵌套包含;通过条件编译或`#pragma once`避…

2025 KEYDIY KD-MP: Add Keys for MLB MQB – Key Identification, Data, Calculation

The Key Replacement Challenge: Why Modern Vehicles Are a Headache For European and American automotive repair shops and car owners, replacing keys for MLB and MQB systems in Volkswagen Group vehicles (…

把 CLI 搬上 Web:在内网打造“可二开”的 AI IDE,为什么这条路更现实? - 指南

把 CLI 搬上 Web:在内网打造“可二开”的 AI IDE,为什么这条路更现实? - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

[LangChain] 23. 回调机制

invoke/stream() 方法,方法签名如下: invoke/stream(input: Input,options?: RunnableConfig ): AsyncGenerator<StreamEvent<Output>>1. 输入参数 (input) 类型:Input 与 invoke() 方法保持一致:如果…

本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名

本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名本地环境自建的es重启,http和https访问es,nested数据类型及设置es别名 link:https接口的支持判断,http升级到https需求https://www.cnblogs.com/…

一文入门 LangChain 开发

2024-05-22 [[Ollama]] [[N_LangChain]] [[N_LangGraph]] LangChain github langchain 项目页 github langgraph 项目页 官方文档 introduction 官方文档 0.2 introductio 0.2 langserve 官方文档 0.1 Components La…

freedom of speech

but N cannot be bad. I think its just the difference between cultures.

七、设备模型

一、概述kobject内核抽象出来的通用对象,对应/sys目录下的一个文件 kset是kobject的一个扩展,一个kset尅包含多个kobject,将多个kobject通过parent进行关联,实现了层次化的结构 sysfs虚拟文件系统,向用户空间提供…

Scrum冲刺阶段 Day Three

一、站立会议纪要 1. 已完成工作 后端开发:设计用户与文件表结构 实现注册登录接口 实现文件上传接口 实现全局异常处理 封装请求拦截器前端开发:搭建前端基础框架 开发注册登录页面2. 今日计划工作实现文件列表查询…

鼎鉴时代锋芒 智启品牌新章 ——2025品牌智鉴榜荣耀登临

当全球产业重构与消费升级浪潮澎湃交汇,品牌早已成为衡量时代实力的核心标尺,更是穿越周期、引领变革的核心力量。2024 品牌智鉴榜,以 “智识为基、专业为刃、价值为魂”,历经百日全域筛查、多维体系核验、业界权威…

深入解析:MTK5G旗舰系列——天玑9500/9400/9300/9200/9000在AI和处理器性能、DDR频率及UFS的深度对比分析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

迈向人机共育的文明语法:AI元人文理论体系深度阐释——内观照叙事模型

迈向人机共育的文明语法:AI元人文理论体系深度阐释——内观照叙事模型 我们正站在一个文明史的奇点上。人工智能不再是遥远的科幻,而是深度介入社会运作、伦理决策与意义构建的“文明参与者”。传统的“价值对齐”范…

Day25综合案例一--CSS精灵--京东服务

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">…

Intellij扩展列表

开发idea插件,需要找到可用的扩展点,之前都是直接在网上搜索,最近详细看了下官方文档, 发现已经给我们列好了所有可用的扩展点 文档位置 https://plugins.jetbrains.com/docs/intellij/plugin-extensions.html#exp…

agentic terminal coding

opencode: https://github.com/sst/opencode The AI coding agent built for the terminalWhat is OpenCode? OpenCode is an open source agent that helps you write and run code directly from the terminal.[*] …

the badness of USA

it has no bad review. Maybe R/N/G can get the real worst some, but theres no even in the people they killed so much. so USA never changes. somehow.

Day3 Scrum冲刺博客

Day3 Scrum冲刺博客 1. 团队会议 todo补充会议照片 1)昨天已完成的工作前端实现个人设置弹窗以及问答模式静态页面,实现问答模式缓存 "关于我们"细节修正后端完成爬虫数据的数据清洗 增加爬虫程序适配的信…

完整教程:内核里常用宏BUG_ON/WARN_ON/WARN_ONCE

完整教程:内核里常用宏BUG_ON/WARN_ON/WARN_ONCE2025-11-26 22:27 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; displa…

贪心专题笔记(从b站左程云老师那上完后的笔记)

https://www.bilibili.com/video/BV1ST4y1s7XT/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=56781f0f92104550238c449cb1aebd72 关键:用对数器验证 1.如果要排序,保证排序具有…