重要
此功能在以下区域中为公共预览版:westus、westus2、eastus、eastus2、centralus、southcentralus、northeurope、westeurope、australiaeast、brazilsouth、canadacentral、centralindia、southeastasia、uksouth。
本页介绍何时以及如何向 Azure Databricks 用户和标识授予对数据库实例的权限。
若要允许其他用户使用 PostgreSQL 访问数据库实例, databricks_superuser 必须为其创建相应的 Postgres 角色。 有关如何创建 Postgres 角色的详细信息,请参阅 “管理 Postgres 角色”。
何时以及如何检查权限
使用 Postgres 语法或通过 PostgreSQL 接口进行连接时,Lakebase 使用以下方法强制实施特定于 PostgreSQL 的访问控制:
- Postgres 角色
- 角色成员资格
- Postgres 授予的权限
在所有其他场景中,Lakebase 实施 Databricks 专属的访问控制。
- Azure Databricks 标识(用户、组和服务主体)
- Azure Databricks 组成员资格
- 工作区访问控制列表(ACL)
- Unity Catalog 特权
注释
Azure Databricks 标识和成员身份以及 Postgres 角色和成员身份之间没有自动同步。
| 用例/权限或标识 | 管理数据库实例 | 创建或删除同步表 | 管理同步表管道 | 从 SQL 仓库查询 Postgres 表 | 功能和模型服务中的查询联机功能 | 在 PostgreSQL 中查询 Postgres 表 |
|---|---|---|---|---|---|---|
| Azure Databricks 标识 | ✅ | ✅ | ✅ | ✅ | ✅ | 需要相应的 Postgres 角色 |
| Databricks 组成员身份 | ✅ | ✅ | ✅ | ✅ | ✅ | 只有在以组身份登录时才进行检查 |
| 实例 ACL | ✅ | ✅ | ||||
| 管道 ACL | 在重用现有管道或删除同步表(这会导致管道被编辑)时,需要成为管道所有者。 | ✅ | ||||
| UC 权限 | ✅ | ✅ | ✅ | |||
| Postgres 角色 | ✅ | |||||
| Postgres 角色成员身份 | ✅ | |||||
| Postgres 权限 | ✅ |
数据库实例权限
用户必须对数据库实例具有特定权限才能管理实例,并从 Azure Databricks UI、API 或 SDK 执行表作。 工作区管理员和实例创建者可以向 数据库实例 概述页中的任何所需用户、组或服务主体分配其他权限。
- 在工作区边栏中单击 “计算 ”。
- 单击 “OLTP 数据库”。
- 单击“权限”选项卡。
- 单击右上角的“ 管理实例权限 ”。
- 输入要向其授予其他权限的用户、组或服务主体。
- 选择要授予标识的权限。 请参阅 数据库实例 ACL。
- 单击“ + 添加”。
- 任何工作区用户可以查看或列出数据库实例。 数据库目录和同步表的权限进一步由 Unity Catalog 的元存储、目录、架构和表权限所管理。 有关详细信息,请参阅 “管理 Unity 目录中的权限”。
- 单击“ 保存”。
Postgres 权限
若要读取或写入 Postgres 中的表,用户在 Postgres 中需要以下权限:
-
CONNECT在数据库上 -
USAGE在架构中操作(或CREATE用于创建新表) -
SELECT、INSERT、UPDATE或DELETE在桌子上
有关 Postgres 权限的完整列表,请参阅 PostgreSQL 文档。
检查 Postgres 中特定表的用户权限
运行以下 SQL 语句以创建一个用于检查用户权限(包括继承权限)的函数 pg_temp.check_permissions 。
CREATE OR REPLACE FUNCTION pg_temp.check_permissions(TEXT, TEXT, TEXT, TEXT)
RETURNS TABLE(database_connect BOOLEAN, schema_usage BOOLEAN, table_select BOOLEAN,
table_insert BOOLEAN, table_update BOOLEAN, table_delete BOOLEAN) AS $$
SELECT
has_database_privilege($1, $2, 'CONNECT'),
has_schema_privilege($1, $3, 'USAGE'),
has_table_privilege($1, $4, 'SELECT'),
has_table_privilege($1, $4, 'INSERT'),
has_table_privilege($1, $4, 'UPDATE'),
has_table_privilege($1, $4, 'DELETE')
$$ LANGUAGE sql
;
若要使用该函数,请使用以下查询:
SELECT * FROM pg_temp.check_permissions('<your_user>', '<your_database>', '<your_schema>', '<your_table>');
-- Example:
SELECT * FROM pg_temp.check_permissions('joe@acme.org', 'databricks_postgres', 'public', 'table1');
查看 Postgres 中数据库、架构和表的所有权限
以下 SQL 语句创建一个名为 pg_temp.make_owner_acl 的函数,该函数返回所有用户的所有已授予权限的详细视图,不包括继承的权限:
CREATE OR REPLACE FUNCTION pg_temp.make_owner_acl(owner_oid OID)
RETURNS TABLE(grantor OID, grantee OID, privilege_type TEXT, is_grantable BOOLEAN) AS $$
SELECT owner_oid, owner_oid,'OWNER'::TEXT, True
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION pg_temp.get_all_permissions(TEXT, TEXT, TEXT)
RETURNS TABLE(type TEXT, name TEXT, role TEXT, acl TEXT, can_grant TEXT) AS $$
SELECT type, name,
CASE WHEN grantee = 0 THEN 'PUBLIC' ELSE pg_get_userbyid(grantee) END AS role, privilege_type,
CASE WHEN privilege_type = 'OWNER' THEN 'YES, ALL' WHEN is_grantable THEN 'YES' ELSE 'NO' END AS can_grant
FROM (
SELECT 'DATABASE' type, datname as name, (pg_temp.make_owner_acl(datdba)).*
FROM pg_database
WHERE datname = $1
UNION ALL
SELECT 'DATABASE' type, datname as name, (aclexplode(datacl)).*
FROM pg_database
WHERE datname = $1
UNION ALL
SELECT 'SCHEMA' type, nspname as name, (pg_temp.make_owner_acl(nspowner)).*
FROM pg_namespace
WHERE nspname = $2
UNION ALL
SELECT 'SCHEMA' type, nspname as name, (aclexplode(nspacl)).*
FROM pg_namespace
WHERE nspname = $2
UNION ALL
SELECT 'TABLE' type, relname as name, (pg_temp.make_owner_acl(relowner)).*
FROM pg_class
WHERE relname = $3
UNION ALL
SELECT 'TABLE' type, relname as name, (aclexplode(relacl)).*
FROM pg_class
WHERE relname = $3
)
$$ LANGUAGE SQL
;
若要使用该函数,请使用以下查询:
SELECT * FROM pg_temp.get_all_permissions('<your_database>', '<your_schema>', '<your_table>');
-- Example:
SELECT * FROM pg_temp.get_all_permissions('databricks_postgres', 'public', 'table1');
检查 Postgres 中的角色继承层次结构
在 Postgres 中,角色可以是另一个角色的成员,成员身份指定权限是否继承自父角色。 若要查看特定角色所属的所有角色,请使用以下 SQL 语句创建 SQL 函数 pg_temp.get_inherited_roles:
CREATE OR REPLACE FUNCTION pg_temp.get_inherited_roles(
role_name TEXT
)
RETURNS TABLE(inherited_roles TEXT, member_via TEXT, inherits_permissions TEXT) AS $$
WITH RECURSIVE role_tree AS (
SELECT
m.roleid,
pg_get_userbyid(m.roleid) rolname,
'DIRECT' COLLATE "C" as member_via,
m.inherit_option as inherits_permissions
FROM pg_auth_members m
WHERE m.member = (SELECT oid FROM pg_roles WHERE rolname = $1)
UNION ALL
SELECT
m.roleid,
pg_get_userbyid(m.roleid) rolname,
rt.rolname::text as member_via,
(rt.inherits_permissions AND m.inherit_option) as inherits_permissions
FROM pg_auth_members m
JOIN role_tree rt ON m.member = rt.roleid
)
SELECT
rolname AS inherited_roles,
member_via,
CASE WHEN inherits_permissions THEN 'YES' ELSE 'NO' END as inherits_permissions
FROM role_tree
GROUP BY inherited_roles, member_via, inherits_permissions
ORDER BY inherits_permissions DESC
$$ LANGUAGE sql
;
若要使用该函数,请将 Azure Databricks 用户名 <your_user>替换为:
SELECT * FROM pg_temp.get_inherited_roles('<your role>');
在 Postgres 中查找角色管理员
若要查看角色的管理员,请使用以下 SQL 查询,并将角色名称 <target_role>替换为:
SELECT pg_get_userbyid(m.member) admin
FROM pg_auth_members m
WHERE m.roleid = (SELECT oid FROM pg_roles WHERE rolname = '<target_role>')
AND m.admin_option = true;