引言

在当今数字化时代,数据已然成为企业和组织最为关键的资产之一 。数据库作为数据存储与管理的核心,其安全性至关重要。安全管理中的数据库权限管理,是保障数据安全的重要防线。合理的权限管理能够确保只有经过授权的用户可以访问和操作特定的数据,有效防止数据泄露、篡改以及非法访问等安全问题。

金仓数据库作为一款被广泛应用的数据库管理系统,其用户、角色与权限管理(GRANT/REVOKE)功能十分强大且灵活。熟练掌握金仓数据库的用户、角色与权限管理知识,对于开发者和数据库管理员而言,具有极高的价值。开发者可以借此确保应用程序对数据库的访问安全且合规,避免因权限不当引发的安全漏洞;数据库管理员则能够更精细地管理数据库访问,根据不同用户和业务需求,精准分配权限,提升数据库的安全性和稳定性。接下来,就让我们深入探索金仓数据库用户、角色与权限管理的奥秘。

一、金仓数据库基础概念

1.1 金仓数据库简介

金仓数据库(KingbaseES)是一款面向全行业、全客户关键应用的企业级大型通用融合数据库产品。它具备强大的事务处理能力,全面支持 ACID 事务特性,依托多核架构,能够轻松应对大规模并发交易的处理需求,在金融、电信等对高并发事务处理要求极高的行业中表现卓越。在安全方面,金仓数据库拥有全面的安全保障措施,涵盖纵深防御、数据加密、访问控制等,其透明数据加密技术将加密带来的性能影响控制在 3% 以内 ,并通过了国家信息安全产品认证以及信息技术产品安全分级评估证书(EAL4+)。

此外,金仓数据库在兼容性上也有着出色的表现,它支持多种操作系统和硬件平台,兼容各类主流应用软件,还支持多种数据库语法,如 Oracle、MySQL、SQL Server 等,能够实现快速、平稳、无损的迁移,显著降低企业的迁移成本。凭借这些优势,金仓数据库在政务、金融、能源、交通、医疗等众多关键行业中得到了广泛应用,为各行业的数字化转型提供了坚实的数据支撑。

1.2 用户、角色与权限的关系

在金仓数据库中,用户是数据库资源的使用者和共享者,包含管理员用户和普通用户,是直接与数据库进行交互的主体。例如,开发人员需要连接数据库执行数据查询和更新操作,他们就是以用户的身份进行操作。角色则是权限的集合,是一种管理权限的手段。通过创建角色,可以将一组相关的权限组合在一起,然后将角色授予不同的用户,从而简化权限管理过程。比如,在一个企业的数据库系统中,可以创建 “财务角色”,将对财务相关数据表的查询、插入、更新权限赋予这个角色。权限则决定了用户或角色对数据库对象(如表、视图、函数等)的操作能力,包括系统权限、对象权限和列级权限。系统权限用于控制数据库级别的操作,如创建数据库、创建角色等;对象权限用于控制对具体数据库对象的操作,如对表的查询、插入、删除等;列级权限则更细致,用于控制对表中特定列的操作。

以一个电商数据库系统为例,系统中可能有 “普通用户角色”,该角色被授予了对 “商品表” 的查询权限,这样所有被赋予 “普通用户角色” 的用户都可以查询商品信息;而 “管理员角色” 则拥有对所有数据库对象的全面操作权限,包括创建和删除数据库对象、修改数据等。通过合理地创建用户、角色并分配权限,可以确保不同的人员在数据库系统中只能进行其职责范围内的操作,从而保障数据库的安全性和数据的完整性。

二、用户管理

2.1 用户分类

在金仓数据库中,用户主要分为管理员用户和普通用户 。管理员用户通常具有全面的管理权限,能够对数据库进行各种管理操作,包括创建和删除数据库、创建和管理用户与角色、授予和回收权限等。以系统默认的数据库管理员(system)为例,它拥有对整个数据库系统的最高控制权,可以执行所有的数据库管理任务,比如创建新的数据库实例,对数据库进行备份和恢复操作等。普通用户则是根据具体的业务需求创建的,他们的权限相对受限,只能在被授予的权限范围内进行操作。例如,一个普通的业务用户可能只被授予了对特定业务表的查询和插入权限,只能执行与该业务相关的数据操作,无法进行数据库级别的管理操作。管理员用户的权限和管理范围决定了他们在数据库系统中的核心地位,负责维护数据库的整体运行和安全;而普通用户则专注于各自的业务任务,通过被授予的权限来访问和处理相关数据,两者相互配合,共同保障数据库系统的正常运行。

2.2 创建用户

创建用户在金仓数据库中是一个基础且重要的操作,其语法格式为:


CREATE USER username [ [ WITH ] option [ ... ] ]

这里的username表示要创建的用户名,它必须是唯一的,不能与已有的用户名重复,且要符合金仓数据库对命名的规范要求,通常由字母、数字和下划线组成,不能以数字开头。option是一系列可选参数,常用的参数有:

  • IDENTIFIED BY password:用于指定用户的密码,密码的设置应遵循一定的强度规则,包含字母、数字和特殊字符,长度适中,以提高安全性。
  • DEFAULT TABLESPACE tablespace_name:指定用户的默认表空间,如果不指定,将使用数据库的默认表空间。表空间用于存储数据库对象,不同的表空间可以设置不同的存储属性,通过指定默认表空间,可以更好地管理用户数据的存储位置。
  • QUOTA integer [ K | M | G ] ON tablespace_name:设置用户在指定表空间上的空间配额,限制用户在该表空间中可以使用的存储空间大小。K、M、G分别表示千字节、兆字节和吉字节。例如,QUOTA 100M ON userspace表示用户在userspace表空间上的配额为 100 兆字节。

下面通过几个示例来更直观地展示如何创建具有不同属性的用户:

  • 创建一个简单的用户testuser,并设置密码为Test@1234:

CREATE USER testuser IDENTIFIED BY 'Test@1234';

  • 创建用户devuser,设置密码为Dev@5678,并指定默认表空间为dev_tablespace:

CREATE USER devuser IDENTIFIED BY 'Dev@5678' DEFAULT TABLESPACE dev_tablespace;

  • 创建用户financeuser,设置密码为Finance@9012,指定默认表空间为finance_tablespace,并设置在该表空间上的空间配额为 500 兆字节:

CREATE USER financeuser IDENTIFIED BY 'Finance@9012' DEFAULT TABLESPACE finance_tablespace QUOTA 500M ON finance_tablespace;

通过这些示例可以看出,根据不同的业务需求,可以灵活地使用CREATE USER语句的参数来创建满足特定要求的用户,从而更好地管理数据库用户和控制数据存储。

2.3 修改用户

修改用户属性是对已创建用户的信息进行调整和更新的操作,在金仓数据库中,其语法为:


ALTER USER username [ [ WITH ] option [ ... ] ]

其中,username是要修改的用户名,option为可选参数,常见的操作有:

  • IDENTIFIED BY new_password:用于修改用户密码,为了保障数据库安全,定期修改密码是一个良好的安全实践。新密码同样要遵循密码强度规则,避免使用简单易猜的密码。
  • DEFAULT TABLESPACE new_tablespace_name:更改用户的默认表空间,当业务需求发生变化,需要将用户数据存储到其他表空间时,可使用此参数进行修改。
  • QUOTA new_integer [ K | M | G ] ON tablespace_name:调整用户在指定表空间上的空间配额。如果用户的业务数据量增长,需要增加存储空间,可以增大配额;反之,如果用户数据量减少,可适当减少配额,以优化存储空间的利用。

下面通过示例来演示这些常见操作:

  • 将用户testuser的密码修改为NewTest@5678:

ALTER USER testuser IDENTIFIED BY 'NewTest@5678';

  • 将用户devuser的默认表空间修改为new_dev_tablespace:

ALTER USER devuser DEFAULT TABLESPACE new_dev_tablespace;

  • 将用户financeuser在finance_tablespace表空间上的空间配额增加到 800 兆字节:

ALTER USER financeuser QUOTA 800M ON finance_tablespace;

通过这些修改用户属性的操作,可以根据实际业务的变化和需求,灵活地调整用户的相关设置,确保用户能够在合适的权限和资源配置下进行数据库操作,同时也有助于数据库的高效管理和安全维护。

2.4 删除用户

删除用户是从数据库中移除指定用户及其相关权限和关联数据的操作,在金仓数据库中,其语法为:


DROP USER [ IF EXISTS ] username [ , ... ]

其中,username是要删除的用户名,IF EXISTS是可选关键字,使用它可以避免在删除不存在的用户时抛出错误,只会给出一个提示信息。

在执行删除用户操作时,有一些重要的注意事项。如果用户拥有数据库对象(如表、视图、函数等),直接删除用户会导致这些对象失去所有者,可能引发数据不一致或其他问题。因此,在删除用户之前,需要先处理这些用户拥有的数据库对象。通常有两种处理方式:一是使用DROP OWNED BY语句删除用户拥有的所有对象;二是使用REASSIGN OWNED BY语句将用户拥有的对象重新分配给其他用户。

例如,假设要删除用户testuser,且该用户拥有一些表和视图:

  • 首先使用DROP OWNED BY语句删除testuser拥有的所有对象:

DROP OWNED BY testuser;

然后再删除用户:


DROP USER testuser;

  • 或者使用REASSIGN OWNED BY语句将testuser拥有的对象重新分配给newuser,然后再删除用户:

REASSIGN OWNED BY testuser TO newuser;

DROP USER testuser;

通过合理地使用DROP USER语句并遵循相关注意事项,可以安全、有效地删除不再需要的用户,确保数据库系统的整洁和数据的一致性,同时避免因不当删除操作而引发的潜在问题。

三、角色管理

3.1 角色的作用

角色在金仓数据库的权限管理体系中扮演着至关重要的角色,其主要作用在于简化权限管理流程 。在实际的企业数据库应用场景中,若没有角色的概念,当有大量用户且每个用户需要不同的权限组合时,权限管理工作将变得极为繁琐和复杂。例如,在一个大型企业中,财务部门可能有数十名员工,他们都需要对财务相关的数据库表进行查询、插入和更新操作。如果为每个员工单独授予这些权限,不仅操作量巨大,而且当权限发生变更时,需要逐一修改每个员工的权限,管理成本极高。

而通过引入角色,我们可以将这些财务相关的权限组合成一个 “财务角色” 。然后,只需将这个 “财务角色” 授予财务部门的所有员工,这些员工便自动拥有了该角色所包含的所有权限。当财务部门的权限需求发生变化时,例如需要增加对某个新的财务报表的查询权限,只需在 “财务角色” 上进行权限修改,所有被赋予该角色的员工的权限也会随之更新,大大提高了权限管理的效率和灵活性。此外,角色还方便了权限的回收操作。当某个员工离开财务部门时,只需将 “财务角色” 从该员工身上移除,该员工便失去了与财务相关的所有权限,无需逐个收回具体的权限,使得权限管理更加便捷和可控。

3.2 创建角色

在金仓数据库中,创建角色使用CREATE ROLE语句,其语法格式为:


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

其中,role_name是要创建的角色名称,必须是唯一的,且符合数据库命名规范。option为一系列可选参数,常见的参数有:

  • SUPERUSER | NOSUPERUSER:设置角色是否为超级用户,SUPERUSER表示具有超级权限,拥有所有系统权限,默认值为NOSUPERUSER。超级用户角色具有极高的权限,可以执行数据库的任何操作,如创建和删除数据库、管理用户和角色等,在使用时需谨慎分配。
  • CREATEDB | NOCREATEDB:决定角色是否拥有创建数据库的权限,默认值为NOCREATEDB。拥有CREATEDB权限的角色可以创建新的数据库,这在一些需要动态创建数据库的业务场景中很有用。
  • CREATEROLE | NOCREATEROLE:指定角色是否能够创建、修改和删除其他角色,默认值为NOCREATEROLE。具有CREATEROLE权限的角色可以管理其他角色,适用于需要进行角色层级管理的场景。
  • INHERIT | NOINHERIT:设置新角色是否继承其他角色的权限,默认值为INHERIT。如果一个角色被设置为INHERIT,且它是其他角色的成员,那么它将自动继承这些父角色的权限;若设置为NOINHERIT,则不会继承。
  • LOGIN | NOLOGIN:确定角色是否可以用于登录数据库,默认值为NOLOGIN。通常,角色主要用于权限管理,不直接用于登录,而用户则通过被赋予具有LOGIN权限的角色来获得登录权限。但在某些特殊情况下,也可以为角色设置LOGIN权限。
  • REPLICATION | NOREPLICATION:用于设置角色是否具有复制权限,默认值为NOREPLICATION。复制权限在数据库的主从复制架构中很重要,具有REPLICATION权限的角色可以参与数据库的复制过程。
  • BYPASSRLS | NOBYPASSRLS:表示角色是否可以绕过行级安全性(RLS)策略,默认值为NOBYPASSRLS。行级安全性策略用于控制对表中每一行数据的访问,BYPASSRLS权限允许角色跳过这些策略的限制。
  • CONNECTION LIMIT connlimit:限制角色的并发连接数,connlimit为具体的限制数量,默认值为-1,表示不限制。通过设置并发连接数,可以有效控制数据库的资源使用,避免因过多连接导致性能下降。
  • [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL:设置角色的密码,PASSWORD NULL表示不设置密码。密码仅用于具有LOGIN属性的角色,且密码应设置为高强度的组合,以保障安全性。加密方法由配置参数password_encryption确定,密码始终以加密方式存储在系统目录中。
  • VALID UNTIL 'timestamp':设置密码的有效期时间,不设置则表示永不过期。通过设置密码有效期,可以增强数据库的安全性,定期更新密码有助于防止密码被破解。
  • IN ROLE role_name [, ...]:新角色将立即添加为指定角色的成员。例如,IN ROLE admin表示新角色将成为admin角色的成员,从而继承admin角色的部分权限。
  • IN GROUP role_name [, ...]:与IN ROLE类似,将新角色添加为指定角色组的成员。
  • ROLE role_name [, ...]:将指定角色自动添加为新角色的成员,使新角色成为一个 “组”。例如,ROLE role1, role2表示role1和role2将成为新角色的成员。
  • ADMIN role_name [, ...]:与ROLE类似,但命名角色将添加到新角色WITH ADMIN OPTION,使他们有权将此角色的成员资格授予其他人。这在需要进行权限传递和管理的场景中很有用。
  • USER role_name [, ...]:与ROLE类似,将指定角色添加为新角色的成员。
  • SYSID uid:此参数为向后兼容性而存在,在创建角色时通常被忽略。

下面通过一些示例来展示如何创建具有不同权限和属性的角色:

  • 创建一个普通角色basic_role:

CREATE ROLE basic_role;

  • 创建一个具有登录权限和密码的角色login_role,密码为Login@1234:

CREATE ROLE login_role WITH LOGIN PASSWORD 'Login@1234';

  • 创建一个拥有创建数据库权限的角色createdb_role:

CREATE ROLE createdb_role WITH CREATEDB;

  • 创建一个超级用户角色super_role,并设置密码为Super@5678:

CREATE ROLE super_role WITH SUPERUSER LOGIN PASSWORD 'Super@5678';

  • 创建一个角色inherit_role,使其继承其他角色的权限,且具有创建角色的权限:

CREATE ROLE inherit_role WITH INHERIT CREATEROLE;

通过这些示例可以看出,根据不同的业务需求和安全策略,可以灵活地使用CREATE ROLE语句的参数来创建各种类型的角色,以满足数据库权限管理的多样化需求。

3.3 修改角色

修改角色在金仓数据库中主要用于调整角色的权限和属性,以适应不断变化的业务需求。修改角色的语法为:


ALTER ROLE role_name [ [ WITH ] option [ ... ] ]

其中,role_name是要修改的角色名称,option为可选参数,常见的操作有:

  • 权限相关修改:
    • 使用GRANT语句授予角色新的权限。例如,授予basic_role角色对test_table表的查询权限:

GRANT SELECT ON test_table TO basic_role;

  • 使用REVOKE语句回收角色已有的权限。比如,回收basic_role角色对test_table表的查询权限:

REVOKE SELECT ON test_table FROM basic_role;

  • 属性相关修改:
    • SUPERUSER | NOSUPERUSER:更改角色是否为超级用户。例如,将createdb_role角色设置为超级用户:

ALTER ROLE createdb_role WITH SUPERUSER;

  • CREATEDB | NOCREATEDB:改变角色创建数据库的权限。比如,移除createdb_role角色的创建数据库权限:

ALTER ROLE createdb_role WITH NOCREATEDB;

  • CREATEROLE | NOCREATEROLE:修改角色创建其他角色的权限。例如,赋予inherit_role角色创建其他角色的权限:

ALTER ROLE inherit_role WITH CREATEROLE;

  • INHERIT | NOINHERIT:调整角色的权限继承属性。比如,将inherit_role角色设置为不继承其他角色的权限:

ALTER ROLE inherit_role WITH NOINHERIT;

  • LOGIN | NOLOGIN:改变角色的登录权限。例如,为basic_role角色添加登录权限:

ALTER ROLE basic_role WITH LOGIN;

  • REPLICATION | NOREPLICATION:更改角色的复制权限。比如,授予login_role角色复制权限:

ALTER ROLE login_role WITH REPLICATION;

  • BYPASSRLS | NOBYPASSRLS:修改角色绕过行级安全性策略的权限。例如,允许createdb_role角色绕过行级安全性策略:

ALTER ROLE createdb_role WITH BYPASSRLS;

  • CONNECTION LIMIT new_connlimit:调整角色的并发连接数限制。比如,将login_role角色的并发连接数限制设置为 5:

ALTER ROLE login_role WITH CONNECTION LIMIT 5;

  • [ ENCRYPTED ] PASSWORD 'new_password' | PASSWORD NULL:修改角色的密码。例如,将login_role角色的密码修改为NewLogin@5678:

ALTER ROLE login_role WITH PASSWORD 'NewLogin@5678';

  • VALID UNTIL 'new_timestamp':更改角色密码的有效期。比如,将login_role角色的密码有效期设置为2025-12-31:

ALTER ROLE login_role WITH VALID UNTIL '2025-12-31';

  • 添加或移除角色成员:
    • 使用GRANT语句将其他角色或用户添加为当前角色的成员。例如,将basic_role角色添加为inherit_role角色的成员:

GRANT inherit_role TO basic_role;

  • 使用REVOKE语句移除角色的成员。比如,将basic_role角色从inherit_role角色的成员中移除:

REVOKE inherit_role FROM basic_role;

下面通过一个综合示例来演示修改角色权限和添加成员的操作:

假设已经创建了角色developer_role和test_role,以及表project_table:

  • 授予developer_role角色对project_table表的插入和更新权限:

GRANT INSERT, UPDATE ON project_table TO developer_role;

  • 将test_role角色添加为developer_role角色的成员:

GRANT developer_role TO test_role;

通过这些修改角色的操作,可以根据实际业务的变化,灵活地调整角色的权限和属性,确保数据库权限管理的有效性和适应性。

3.4 删除角色

删除角色是在不再需要某个角色及其相关权限时进行的操作,以清理数据库的权限管理结构。在金仓数据库中,删除角色使用DROP ROLE语句,其语法为:


DROP ROLE [ IF EXISTS ] role_name [ , ... ]

其中,role_name是要删除的角色名称,IF EXISTS是可选关键字,使用它可以避免在删除不存在的角色时抛出错误,只会给出一个提示信息。

在执行删除角色操作时,有一些重要的限制条件需要注意 。如果角色拥有数据库对象(如表、视图、函数等),直接删除角色会导致这些对象失去所有者,可能引发数据不一致或其他问题。因此,在删除角色之前,需要先处理这些角色拥有的数据库对象。通常有两种处理方式:一是使用DROP OWNED BY语句删除角色拥有的所有对象;二是使用REASSIGN OWNED BY语句将角色拥有的对象重新分配给其他角色或用户。

例如,假设要删除角色test_role,且该角色拥有一些表和视图:

  • 首先使用DROP OWNED BY语句删除test_role拥有的所有对象:

DROP OWNED BY test_role;

然后再删除角色:


DROP ROLE test_role;

  • 或者使用REASSIGN OWNED BY语句将test_role拥有的对象重新分配给new_role,然后再删除角色:

REASSIGN OWNED BY test_role TO new_role;

DROP ROLE test_role;

另外,如果角色是其他角色的成员,在删除该角色时,需要先将其从其他角色的成员列表中移除,否则删除操作会失败。例如,如果test_role是developer_role的成员,需要先执行以下操作:


REVOKE developer_role FROM test_role;

然后再删除test_role:


DROP ROLE test_role;

通过合理地使用DROP ROLE语句并遵循相关限制条件,可以安全、有效地删除不再需要的角色,确保数据库权限管理的整洁和数据的一致性,避免因不当删除操作而引发的潜在问题。

四、权限管理(GRANT/REVOKE)

4.1 权限分类

在金仓数据库中,权限主要分为系统权限、对象权限和列级权限,它们在数据库的安全管理中各自发挥着独特的作用,适用于不同的场景 。

系统权限是用于控制数据库级别的操作权限,这些权限决定了用户或角色是否能够执行特定的数据库管理任务。例如,CREATE DATABASE权限允许用户创建新的数据库,这在需要为不同项目或业务模块独立创建数据库时非常重要;CREATE ROLE权限则让用户可以创建新的角色,有助于灵活地进行权限管理和角色分配,当企业的组织架构发生变化,需要新增不同权限组合的角色时,就需要用到此权限。系统权限还包括DROP DATABASE(删除数据库)、ALTER DATABASE(修改数据库属性)等,这些权限通常只授予数据库管理员或具有高级管理职责的用户,因为它们对数据库的整体结构和运行有着重大影响 。

对象权限是针对具体数据库对象(如表、视图、函数等)的操作权限,用于控制用户对这些对象的访问和操作能力 。以表为例,常见的对象权限有SELECT(查询)、INSERT(插入)、UPDATE(更新)、DELETE(删除)等。在一个电商数据库中,普通用户角色可能被授予对 “商品表” 的SELECT权限,使其能够查询商品信息;而 “订单处理角色” 则可能被授予对 “订单表” 的SELECT、INSERT和UPDATE权限,以便处理订单相关的业务操作。对于视图,用户可能被授予SELECT权限,用于查看经过特定筛选和处理的数据;对于函数,EXECUTE权限允许用户执行函数,获取函数返回的结果。对象权限的设置非常灵活,可以根据不同的业务需求和用户角色,精确地控制对每个数据库对象的操作权限 。

列级权限是在对象权限的基础上,进一步细化到对表中特定列的操作权限 。当某些列包含敏感信息时,就需要使用列级权限来进行更精细的控制。比如,在一个员工信息表中,“工资” 列属于敏感信息,只有人力资源部门的特定用户或角色才被授予对该列的SELECT和UPDATE权限,而其他部门的用户即使对整个表有SELECT权限,也无法查看 “工资” 列的数据。列级权限的设置可以使用GRANT语句来实现,例如GRANT SELECT (column1, column2) ON table_name TO user_or_role;,这表示授予指定用户或角色对table_name表中column1和column2列的查询权限。通过列级权限的设置,可以更好地保护敏感数据,防止数据泄露,满足企业对数据安全的严格要求 。

4.2 GRANT 语法详解

在金仓数据库中,GRANT语句是用于授予用户或角色权限和角色的重要工具,其语法格式丰富且灵活,能够满足各种复杂的权限授予需求 。

授予权限的基本语法格式为:


GRANT {权限列表} ON {对象类型 对象名 | ALL 对象类型 IN SCHEMA schema_name} TO {用户/角色列表} [WITH GRANT OPTION]

其中,权限列表是要授予的具体权限,多个权限之间用逗号分隔。例如,SELECT, INSERT, UPDATE表示授予查询、插入和更新权限。对象类型可以是DATABASE(数据库)、SCHEMA(模式)、TABLE(表)、SEQUENCE(序列)、FUNCTION(函数)等。对象名是具体的数据库对象名称,如果要对某个模式下的所有表授予权限,可以使用ALL TABLES IN SCHEMA schema_name的形式,其中schema_name是模式名称。用户/角色列表是要被授予权限的用户或角色,可以是单个用户 / 角色,也可以是多个用户 / 角色,用逗号分隔。WITH GRANT OPTION是可选参数,若指定该参数,被授权的用户或角色将有权将这些权限再授予其他用户或角色 。

下面通过一些示例来演示授予不同权限的操作:

  • 授予用户testuser对test_table表的查询权限:

GRANT SELECT ON test_table TO testuser;

  • 授予角色developer_role对project_schema模式下所有表的插入和更新权限:

GRANT INSERT, UPDATE ON ALL TABLES IN SCHEMA project_schema TO developer_role;

  • 授予用户adminuser对test_sequence序列的使用和查询权限,并允许其转授权:

GRANT USAGE, SELECT ON test_sequence TO adminuser WITH GRANT OPTION;

授予角色的语法格式为:


GRANT {角色列表} TO {用户/角色列表} [WITH ADMIN OPTION]

这里的角色列表是要授予的角色,用户/角色列表是接收角色的用户或角色。WITH ADMIN OPTION同样是可选参数,若指定,被授权的用户或角色将有权将这些角色再授予其他用户或角色,并且可以使用ADMIN OPTION来传递管理权限 。

例如,将admin_role角色授予用户manageruser,并给予其管理权限传递的能力:


GRANT admin_role TO manageruser WITH ADMIN OPTION;

通过这些示例可以看出,GRANT语句能够根据不同的业务需求,精确地将权限和角色授予相应的用户或角色,同时还可以灵活地控制权限和角色的转授,为数据库的权限管理提供了强大的支持 。

4.3 REVOKE 语法详解

REVOKE语句在金仓数据库中用于撤销用户或角色已被授予的权限和角色,是权限管理中的重要操作,其语法格式如下 :

撤销权限的语法为:


REVOKE [GRANT OPTION FOR] {权限列表} ON {对象类型 对象名 | ALL 对象类型 IN SCHEMA schema_name} FROM {用户/角色列表} [CASCADE | RESTRICT]

其中,GRANT OPTION FOR是可选关键字,用于取消被授权者的转授权限,而不取消权限本身。若不使用该关键字,则同时取消权限和转授权限。权限列表、对象类型、对象名和用户/角色列表的含义与GRANT语句中相同。CASCADE和RESTRICT是可选参数,CASCADE表示递归取消,当被撤销权限的用户或角色已经将这些权限转授给其他用户或角色时,使用CASCADE会将这些被转授的权限也一并撤销;RESTRICT表示非递归取消,是默认选项,若被撤销权限的用户或角色已经将权限转授给其他用户或角色,使用RESTRICT时撤销操作将失败 。

下面通过示例来展示撤销权限的操作:

  • 撤销用户testuser对test_table表的查询权限:

REVOKE SELECT ON test_table FROM testuser;

  • 仅取消用户adminuser对test_sequence序列查询权限的转授权限,保留其查询权限:

REVOKE GRANT OPTION FOR SELECT ON test_sequence FROM adminuser;

  • 递归撤销角色developer_role对project_schema模式下所有表的插入和更新权限:

REVOKE INSERT, UPDATE ON ALL TABLES IN SCHEMA project_schema FROM developer_role CASCADE;

撤销角色的语法为:


REVOKE [ADMIN OPTION FOR] {角色列表} FROM {用户/角色列表} [CASCADE | RESTRICT]

ADMIN OPTION FOR用于取消被授权者的角色管理权限传递,不取消角色本身。角色列表是要撤销的角色,用户/角色列表是被撤销角色的用户或角色。CASCADE和RESTRICT的作用与撤销权限时相同 。

例如,撤销用户manageruser的admin_role角色,并递归取消其因该角色而传递给其他用户的相关权限:


REVOKE admin_role FROM manageruser CASCADE;

递归取消和非递归取消在实际应用中有着不同的使用场景。递归取消适用于需要全面收回权限的情况,比如当某个用户或角色的权限被滥用,需要彻底清除其所有相关权限时,使用CASCADE可以确保所有被转授的权限都被撤销,避免权限残留带来的安全隐患。非递归取消则适用于较为谨慎的权限回收操作,当不确定被撤销角色或权限的用户是否有转授行为,或者不希望影响到其他用户通过转授获得的权限时,使用RESTRICT可以防止误操作,保证数据库权限体系的稳定性 。

4.4 权限描述符

权限描述符是金仓数据库中用于表示用户或角色权限的一种特定格式,它直观地展示了权限的分配和转授权情况,对于理解和管理数据库权限具有重要意义 。

权限描述符的基本格式为:[被授权用户]=权限明细[*]/授权用户。其中,被授权用户是获得权限的用户或角色名称;权限明细是具体的权限表示,不同的字母代表不同的权限,例如r表示SELECT(查询)权限,a表示INSERT(插入)权限,w表示UPDATE(更新)权限,d表示DELETE(删除)权限等;*表示被授权用户拥有该权限的转授权,即可以将此权限再授予其他用户或角色;授权用户是授予该权限的用户或角色名称 。

例如,user01=ar*/system表示用户user01从system用户处获得了INSERT(a)和SELECT(r)权限,并且user01拥有SELECT权限的转授权。通过这样的描述符,我们可以清晰地了解到权限的来源、具体权限内容以及是否具有转授权,方便对数据库权限进行审查和管理 。

在实际应用中,通过查看权限描述符,可以快速判断用户或角色的权限范围和权限传递情况 。比如,在一个企业的数据库系统中,管理员可以通过权限描述符来检查各个部门用户的权限是否符合其业务需求和职责范围。如果发现某个用户拥有超出其职责的转授权限,管理员可以及时进行调整,收回不必要的转授权限,以增强数据库的安全性。权限描述符还可以帮助管理员在进行权限变更时,准确地了解当前的权限状态,避免因权限变更不当而导致的业务问题。例如,在撤销某个用户的权限时,通过查看权限描述符,管理员可以清楚地知道该用户是否有转授权限,从而决定是否需要使用递归取消(CASCADE)操作,确保权限的撤销操作准确无误 。

五、实战案例

5.1 场景一:企业部门权限分配

在一个大型企业中,存在多个部门,如销售部门、财务部门和研发部门,每个部门对数据库的访问需求各不相同 。销售部门需要对客户信息表、订单表进行查询、插入和更新操作,以管理客户信息和处理订单;财务部门则需要对财务报表相关的表进行全面的查询、插入、更新和删除操作,同时还需要执行一些财务相关的存储函数;研发部门主要关注产品研发相关的表,需要对其进行查询和修改操作。

针对这些需求,我们可以按照以下步骤进行用户、角色和权限的设置 :

  1. 创建角色

-- 创建销售角色

CREATE ROLE sales_role;

-- 创建财务角色

CREATE ROLE finance_role;

-- 创建研发角色

CREATE ROLE rnd_role;

  1. 授予角色权限

-- 授予销售角色对客户信息表和订单表的查询、插入和更新权限

GRANT SELECT, INSERT, UPDATE ON customer_info, order_table TO sales_role;

-- 授予财务角色对财务报表相关表的所有操作权限和执行财务函数的权限

GRANT ALL PRIVILEGES ON financial_statement_tables, financial_functions TO finance_role;

-- 授予研发角色对产品研发相关表的查询和更新权限

GRANT SELECT, UPDATE ON rnd_project_tables TO rnd_role;

  1. 创建用户并赋予角色

-- 创建销售部门用户并赋予销售角色

CREATE USER sales_user1 IDENTIFIED BY 'Sales@1234' IN ROLE sales_role;

CREATE USER sales_user2 IDENTIFIED BY 'Sales@5678' IN ROLE sales_role;

-- 创建财务部门用户并赋予财务角色

CREATE USER finance_user1 IDENTIFIED BY 'Finance@9012' IN ROLE finance_role;

CREATE USER finance_user2 IDENTIFIED BY 'Finance@3456' IN ROLE finance_role;

-- 创建研发部门用户并赋予研发角色

CREATE USER rnd_user1 IDENTIFIED BY 'Rnd@7890' IN ROLE rnd_role;

CREATE USER rnd_user2 IDENTIFIED BY 'Rnd@1357' IN ROLE rnd_role;

通过以上步骤,不同部门的用户只能在其被授予的权限范围内访问和操作数据库,有效地保障了数据的安全性和保密性 。

5.2 场景二:数据访问控制

假设一个电商平台,需要对不同类型的用户进行数据访问控制 。普通用户只能查询商品信息、订单信息和自己的个人信息;商家用户除了可以查询自己店铺的商品信息、订单信息外,还可以对自己店铺的商品信息进行修改和上架下架操作;管理员用户则拥有对所有数据的全面访问和管理权限,包括创建和删除用户、管理商品信息、处理订单等。

为实现这样的数据访问控制,我们可以采取以下措施 :

  1. 创建角色

-- 创建普通用户角色

CREATE ROLE normal_user_role;

-- 创建商家用户角色

CREATE ROLE merchant_user_role;

-- 创建管理员角色

CREATE ROLE admin_role;

  1. 授予角色权限

-- 授予普通用户角色对商品表、订单表和用户个人信息表的查询权限

GRANT SELECT ON product_table, order_table, user_profile_table TO normal_user_role;

-- 授予商家用户角色对自己店铺相关商品表和订单表的查询、更新以及上架下架操作权限

GRANT SELECT, UPDATE,上架下架操作权限 ON merchant_product_table, merchant_order_table TO merchant_user_role;

-- 授予管理员角色对所有数据库对象的全面操作权限

GRANT ALL PRIVILEGES ON ALL TABLES, ALL FUNCTIONS, ALL SEQUENCES TO admin_role;

  1. 创建用户并赋予角色

-- 创建普通用户并赋予普通用户角色

CREATE USER normal_user1 IDENTIFIED BY 'Normal@1234' IN ROLE normal_user_role;

CREATE USER normal_user2 IDENTIFIED BY 'Normal@5678' IN ROLE normal_user_role;

-- 创建商家用户并赋予商家用户角色

CREATE USER merchant_user1 IDENTIFIED BY 'Merchant@9012' IN ROLE merchant_user_role;

CREATE USER merchant_user2 IDENTIFIED BY 'Merchant@3456' IN ROLE merchant_user_role;

-- 创建管理员用户并赋予管理员角色

CREATE USER admin_user1 IDENTIFIED BY 'Admin@7890' IN ROLE admin_role;

通过这样的设置,不同类型的用户在电商平台数据库中拥有不同的访问权限,确保了数据的安全性和完整性,同时满足了不同用户的业务需求 。

六、安全注意事项

6.1 慎用超级权限

在金仓数据库中,超级权限(如SUPERUSER)赋予了用户对数据库进行全方位操作的能力,包括创建和删除数据库、管理用户与角色、执行任何数据库命令等。然而,这种强大的权限也伴随着极高的风险。一旦超级权限被滥用,可能会导致数据库的核心结构被破坏,数据丢失或泄露。例如,一个拥有超级权限的用户误操作删除了重要的系统表,可能会使整个数据库系统陷入瘫痪;或者恶意用户利用超级权限获取敏感数据,将对企业造成巨大的损失。

为了降低超级权限带来的风险,建议仅在必要时使用超级权限账户,并且严格控制超级权限的授予范围 。在日常的数据库管理和开发工作中,应尽量使用普通用户账户,并根据实际业务需求为其分配最小化的权限。如果需要执行某些需要超级权限的操作,可以采用临时切换权限的方式,操作完成后立即切换回普通用户权限。例如,在金仓数据库中,可以使用SET ROLE语句临时切换角色和权限,完成操作后再使用RESET ROLE语句恢复到原来的权限。同时,对于超级权限账户的操作,要进行详细的审计和日志记录,以便在出现问题时能够快速追溯和定位。

6.2 权限继承风险

在金仓数据库的权限管理中,权限继承是一个强大的功能,它允许角色自动获取其所属父角色的权限,大大简化了权限管理的过程。然而,权限继承也可能带来潜在的风险,其中最主要的问题是权限泄漏 。

当一个角色继承了过多不必要的权限时,就可能出现权限泄漏的情况 。例如,假设存在一个 “财务报表查看角色” 和一个 “财务数据修改角色”,如果某个普通业务角色错误地被添加为 “财务数据修改角色” 的成员,由于权限继承,该普通业务角色将获得财务数据修改的权限,这可能导致财务数据被误修改或恶意篡改,严重影响数据的准确性和安全性。

为了避免权限意外继承,可以采取以下措施 。在创建角色时,仔细规划角色的权限和继承关系,确保每个角色只继承其实际业务所需的权限。对于敏感权限,尽量避免通过继承的方式授予,而是直接明确地授予特定的角色或用户。定期审查角色的成员关系和权限继承情况,及时发现并纠正错误的权限继承。可以使用金仓数据库提供的系统视图(如sys_roles、sys_auth_members等)来查看角色的权限和成员信息,以便进行权限审查和管理 。

6.3 定期权限检查

定期检查权限分配在金仓数据库的安全管理中是至关重要的环节,它能够确保数据库的权限设置始终与业务需求和安全策略保持一致 。随着业务的发展和变化,用户的职责和权限需求也会相应改变,如果不定期检查和调整权限,可能会出现权限过多或过少的情况。权限过多会增加数据被滥用和泄露的风险,例如某个员工离职后,其账号的权限未及时收回,可能会被他人利用进行非法操作;权限过少则会影响业务的正常开展,导致员工无法完成其工作任务。

检查权限的方法主要有两种:一是使用系统视图查询,二是通过编写脚本进行自动化检查 。金仓数据库提供了多个系统视图,如sys_roles视图用于查看角色信息,包括角色名称、是否为超级用户、是否具有创建数据库等权限;sys_auth_members视图用于查看角色成员关系,即哪些用户属于哪些角色;information_schema.table_privileges视图用于查看表的权限分配情况,包括哪些用户或角色对哪些表拥有何种权限。通过查询这些系统视图,可以全面了解数据库的权限分配状态 。

例如,要查询所有具有创建数据库权限的角色,可以使用以下 SQL 语句:


SELECT rolname FROM sys_roles WHERE rolcreatedb = 't';

要查询用户testuser所拥有的所有权限,可以使用以下语句:


SELECT privilege_type, table_name

FROM information_schema.table_privileges

WHERE grantee = 'testuser';

编写脚本进行自动化检查可以提高检查效率和准确性 。可以使用 Python 等编程语言结合金仓数据库的 JDBC 驱动或命令行工具,编写脚本定期执行权限检查,并将检查结果生成报告。例如,使用 Python 的psycopg2库连接金仓数据库,编写脚本查询权限分配情况,并将结果保存到 CSV 文件中:


import psycopg2

import csv

# 连接数据库

conn = psycopg2.connect(database="your_database", user="your_user", password="your_password", host="your_host", port="your_port")

cur = conn.cursor()

# 查询权限分配

cur.execute("""

SELECT grantee, privilege_type, table_name

FROM information_schema.table_privileges

""")

results = cur.fetchall()

# 将结果保存到CSV文件

with open('permission_report.csv', 'w', newline='') as csvfile:

writer = csv.writer(csvfile)

writer.writerow(['Grantee', 'Privilege Type', 'Table Name'])

for row in results:

writer.writerow(row)

cur.close()

conn.close()

通过定期执行这样的脚本,可以方便地生成权限分配报告,及时发现权限异常情况并进行处理 。

七、常见问题解答

7.1 用户权限未生效

在金仓数据库中,有时会遇到用户权限未生效的情况。这可能是由于多种原因导致的 。首先,需要检查角色是否已正确赋予用户。可以通过查询sys_auth_members系统视图来确认角色与用户的关联关系。例如,要查询用户testuser所属的角色,可以使用以下 SQL 语句:


SELECT roleid, member

FROM sys_auth_members

WHERE member = (SELECT oid FROM sys_roles WHERE rolname = 'testuser');

如果查询结果中没有预期的角色,说明角色未正确赋予用户,需要使用GRANT语句重新授予角色。

另外,用户可能需要通过SET ROLE语句激活权限 。例如,如果用户testuser被赋予了developer_role角色,在使用该角色权限之前,需要执行SET ROLE developer_role;,这样才能激活developer_role角色所包含的权限。如果未执行此操作,用户可能无法使用该角色的权限。

7.2 分时段权限控制

在某些业务场景中,需要对用户或角色的权限进行分时段控制 。例如,在一个企业的数据库系统中,某些敏感操作只允许在工作时间内执行,或者某些用户的访问权限在特定时间段内有效。在金仓数据库中,可以使用VALID UNTIL参数来设置密码的有效期,从而间接实现分时段权限控制。

假设需要创建一个用户temp_user,其权限仅在2024-12-31之前有效,可以使用以下语句创建用户:


CREATE USER temp_user IDENTIFIED BY 'Temp@1234' VALID UNTIL '2024-12-31';

这样,在2024-12-31之后,temp_user用户将无法登录数据库,从而实现了权限在特定时间段内的控制 。

对于已经存在的用户,可以使用ALTER USER语句修改其密码有效期来实现分时段权限调整。例如,将testuser用户的权限有效期延长到2025-06-30,可以执行:


ALTER USER testuser VALID UNTIL '2025-06-30';

如果要实现更复杂的分时段权限控制,例如在一天中的特定时间段内限制或允许某些操作,可以结合数据库的触发器和时间函数来实现 。例如,创建一个触发器,在非工作时间(如晚上 6 点到早上 8 点)禁止用户对某些敏感表进行修改操作。具体实现步骤如下:

  1. 创建一个函数,用于判断当前时间是否在允许的时间段内:

CREATE OR REPLACE FUNCTION check_work_time() RETURNS BOOLEAN AS $$

BEGIN

RETURN EXTRACT(HOUR FROM CURRENT_TIME) BETWEEN 8 AND 18;

END;

$$ LANGUAGE plpgsql;

  1. 创建一个触发器,在对敏感表进行修改操作时调用上述函数进行时间检查:

CREATE OR REPLACE FUNCTION sensitive_table_update_trigger() RETURNS TRIGGER AS $$

BEGIN

IF NOT check_work_time() THEN

RAISE EXCEPTION '操作不允许在非工作时间进行';

END IF;

RETURN NEW;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER sensitive_table_update

BEFORE UPDATE ON sensitive_table

FOR EACH ROW

EXECUTE FUNCTION sensitive_table_update_trigger();

通过这种方式,可以根据具体的业务需求实现灵活的分时段权限控制 。

7.3 权限意外继承

权限意外继承是金仓数据库权限管理中可能出现的问题,它可能导致用户或角色拥有超出预期的权限,从而带来安全风险 。例如,当一个角色被错误地设置为继承了其他不必要的角色权限时,就会出现权限意外继承的情况。

为了避免权限意外继承,可以在创建角色时指定NOINHERIT属性,阻断权限继承链 。例如,创建一个角色isolated_role,使其不继承其他角色的权限,可以使用以下语句:


CREATE ROLE isolated_role WITH NOINHERIT;

这样,isolated_role角色将不会自动继承其他角色的权限,确保了其权限的独立性和可控性 。

如果已经出现了权限意外继承的情况,可以通过REVOKE语句回收不必要的权限 。例如,假设test_role角色意外继承了admin_role角色的某些权限,需要回收这些权限,可以使用以下语句:


REVOKE {意外继承的权限列表} FROM test_role;

如果不确定test_role角色具体继承了哪些不必要的权限,可以先查询sys_roles和sys_auth_members系统视图,了解角色的权限和成员关系,然后再针对性地进行权限回收操作 。

八、总结

在当今数字化时代,数据已然成为企业和组织最为关键的资产之一 。数据库作为数据存储与管理的核心,其安全性至关重要。安全管理中的数据库权限管理,是保障数据安全的重要防线。合理的权限管理能够确保只有经过授权的用户可以访问和操作特定的数据,有效防止数据泄露、篡改以及非法访问等安全问题。

金仓数据库作为一款被广泛应用的数据库管理系统,其用户、角色与权限管理(GRANT/REVOKE)功能十分强大且灵活。熟练掌握金仓数据库的用户、角色与权限管理知识,对于开发者和数据库管理员而言,具有极高的价值。开发者可以借此确保应用程序对数据库的访问安全且合规,避免因权限不当引发的安全漏洞;数据库管理员则能够更精细地管理数据库访问,根据不同用户和业务需求,精准分配权限,提升数据库的安全性和稳定性。接下来,就让我们深入探索金仓数据库用户、角色与权限管理的奥秘。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐