首批通过分布式安全可靠测评,为关键业务系统打造
行级访问权限控制
更新时间:2026-04-10 11:58:36
OceanBase 数据库兼容了 Oracle 的 Label Security 功能,可以在行级别对访问进行控制,保证读写数据的安全。基于 Label Security 可以构建对行级数据细粒度访问控制的安全策略。在创建策略后,将该策略应用于需要保护的表,并将标签授予用户。
Label Security 是强制访问控制的一种方式,通过在表中添加一个 Label 列来记录每行的 Label 值,在访问时通过比较用户的 Label 和数据的 Label,达到约束主体(用户)对客体(表中的数据)访问的目的。
OceanBase 数据库提供了内置的安全管理员 LBACSYS 来管理和使用该功能,安全管理员可以通过创建安全策略、定义策略中的 Label、设置用户的 Label,来定制自己的安全策略。一个安全策略可以应用到多张表上,一张表也可以应用多个安全策略。每当一个安全策略被应用,这张表上自动会添加一列,用于该安全策略的访问控制。
使用限制
目前仅 Oracle 模式支持 Label Security。
设置行级访问控制
使用
SYS用户登录到 Oracle 租户并解锁LBACSYS用户。OceanBase 数据库会默认创建
LBACSYS用户,该用户处于锁定状态,使用 Label Security 功能需要先启用该用户。obclient> ALTER USER LBACSYS ACCOUNT UNLOCK;修改
LBACSYS用户的登录密码。为了保障安全性,
LBACSYS用户的密码由SYS用户指定。如果后续需要修改该密码,重新指定一个新的密码即可。obclient> ALTER USER LBACSYS IDENTIFIED BY ***R***;设置
LBACSYS用户的权限。LBACSYS用户默认不带任何权限,为了执行行级访问权限相关的操作,需要通过GRANT语句给LBACSYS用户授予CREATE SESSION权限。obclient> GRANT CREATE SESSION TO LBACSYS;使用安全管理员
LBACSYS用户登录到 Oracle 租户。创建安全策略。
本示例创建了名为
MY_POLICY的安全策略。关于创建标签安全策略的详细信息,参见 SA_SYSDBA.CREATE_POLICY。
示例如下:
obclient> CALL SA_SYSDBA.CREATE_POLICY('MY_POLICY','MY_LABEL','');创建级别 Level 并指定其短名称和长名称。
关于创建级别的详细信息,参见 SA_COMPONENTS.CREATE_LEVEL。
示例如下:
obclient> CALL SA_COMPONENTS.CREATE_LEVEL('MY_POLICY', 100, 'PUBLIC','Public Level'); obclient> CALL SA_COMPONENTS.CREATE_LEVEL('MY_POLICY', 200, 'INTERNAL','Internal Level'); obclient> CALL SA_COMPONENTS.CREATE_LEVEL('MY_POLICY', 300, 'HIGH', 'High Level'); obclient> SELECT * FROM sys.ALL_VIRTUAL_TENANT_OLS_COMPONENT_REAL_AGENT; +-----------+-----------------------+--------------------+-----------+----------+------------+----------------+-------------+------------------------------+------------------------------+ | TENANT_ID | LABEL_SE_COMPONENT_ID | LABEL_SE_POLICY_ID | COMP_TYPE | COMP_NUM | SHORT_NAME | LONG_NAME | PARENT_NAME | GMT_CREATE | GMT_MODIFIED | +-----------+-----------------------+--------------------+-----------+----------+------------+----------------+-------------+------------------------------+------------------------------+ | 1004 | 500019 | 500018 | 0 | 100 | PUBLIC | PUBLIC LEVEL | NULL | 09-DEC-22 02.38.37.835729 PM | 09-DEC-22 02.38.37.835729 PM | | 1004 | 500020 | 500018 | 0 | 200 | INTERNAL | INTERNAL LEVEL | NULL | 09-DEC-22 02.38.49.336692 PM | 09-DEC-22 02.38.49.336692 PM | | 1004 | 500021 | 500018 | 0 | 300 | HIGH | HIGH LEVEL | NULL | 09-DEC-22 02.39.02.742233 PM | 09-DEC-22 02.39.02.742233 PM | +-----------+-----------------------+--------------------+-----------+----------+------------+----------------+-------------+------------------------------+------------------------------+ 3 rows in set (0.001 sec)创建数据标签 Label 并查看结果。
关于创建数据标签的详细信息,参见 SA_LABEL_ADMIN.CREATE_LABEL。
示例如下:
obclient> DELIMITER / obclient> BEGIN SA_LABEL_ADMIN.CREATE_LABEL('MY_POLICY',10000,'PUBLIC',TRUE); SA_LABEL_ADMIN.CREATE_LABEL('MY_POLICY',20000,'INTERNAL',TRUE); SA_LABEL_ADMIN.CREATE_LABEL('MY_POLICY',30000, 'HIGH',TRUE); END; / Query OK, 0 rows affected obclient> DELIMITER ; obclient> SELECT * FROM sys.ALL_VIRTUAL_TENANT_OLS_LABEL_REAL_AGENT; +-----------+-------------------+--------------------+-----------+----------+------+------------------------------+------------------------------+ | TENANT_ID | LABEL_SE_LABEL_ID | LABEL_SE_POLICY_ID | LABEL_TAG | LABEL | FLAG | GMT_CREATE | GMT_MODIFIED | +-----------+-------------------+--------------------+-----------+----------+------+------------------------------+------------------------------+ | 1004 | 500022 | 500018 | 10000 | PUBLIC | 1 | 09-DEC-22 04.25.59.611117 PM | 09-DEC-22 04.25.59.611117 PM | | 1004 | 500023 | 500018 | 20000 | INTERNAL | 1 | 09-DEC-22 04.25.59.636390 PM | 09-DEC-22 04.25.59.636390 PM | | 1004 | 500024 | 500018 | 30000 | HIGH | 1 | 09-DEC-22 04.25.59.651032 PM | 09-DEC-22 04.25.59.651032 PM | +-----------+-------------------+--------------------+-----------+----------+------+------------------------------+------------------------------+ 3 rows in set (0.001 sec)指定用户的 Label。
以
SYS用户登录到Oracle租户,创建用户user1并授予用户user1除GRANT OPTION以外所有当前用户拥有的权限。obclient> CREATE USER user1 IDENTIFIED BY *******; Query OK, 0 rows affected obclient> GRANT ALL PRIVILEGES TO user1; Query OK, 0 rows affected以安全管理员
LBACSYS登录,为用户user1指定 Label。关于为用户指定标签的详细信息,参见 SA_USER_ADMIN.SET_LEVELS。
obclient> CALL SA_USER_ADMIN.SET_LEVELS('MY_POLICY', 'user1', 'HIGH','PUBLIC', 'PUBLIC', 'PUBLIC'); Query OK, 0 rows affected obclient [LBACSYS]> SELECT * FROM sys.ALL_VIRTUAL_TENANT_OLS_USER_LEVEL_REAL_AGENT; +-----------+------------------------+---------+--------------------+---------------+---------------+---------------+-----------+------------------------------+------------------------------+ | TENANT_ID | LABEL_SE_USER_LEVEL_ID | USER_ID | LABEL_SE_POLICY_ID | MAXIMUM_LEVEL | MINIMUM_LEVEL | DEFAULT_LEVEL | ROW_LEVEL | GMT_CREATE | GMT_MODIFIED | +-----------+------------------------+---------+--------------------+---------------+---------------+---------------+-----------+------------------------------+------------------------------+ | 1004 | 500027 | 500025 | 500018 | 300 | 100 | 100 | 100 | 09-DEC-22 04.31.23.965076 PM | 09-DEC-22 04.31.23.965076 PM | +-----------+------------------------+---------+--------------------+---------------+---------------+---------------+-----------+------------------------------+------------------------------+ 1 row in set (0.002 sec)
应用策略到表上。
以
user1用户登录到 Oracle 租户,创建表tbl1。obclient> CREATE TABLE tbl1(col1 INT,col2 INT); Query OK, 0 rows affected以安全管理员
LBACSYS登录,将策略MY_POLICY应用到表tbl1上。关于将指定的策略添加到表中的详细信息,参见 SA_POLICY_ADMIN.APPLY_TABLE_POLICY。
obclient> CALL SA_POLICY_ADMIN.APPLY_TABLE_POLICY('MY_POLICY','user1', 'tbl1', '', '', ''); Query OK, 0 rows affected
插入数据,验证查询结果。
以
user1用户登录,在tbl1表中插入col1和MY_LABEL两列数据。obclient> INSERT INTO tbl1 VALUES(1,1,10000); Query OK, 1 row affected obclient> INSERT INTO tbl1(MY_LABEL) VALUES(20000); Query OK, 1 row affected obclient> INSERT INTO tbl1(col1) VALUES (2); Query OK, 1 row affected obclient> COMMIT; Query OK, 0 rows affected在
user1用户下设置SESSION LABEL和ROW LABEL。关于设置当前数据库会话标签的详细信息,参见 SA_SESSION.SET_LABEL。
关于设置当前数据库会话默认行标签值的详细信息,参见 SA_SESSION.SET_ROW_LABEL。
obclient> CALL SA_SESSION.SET_LABEL('MY_POLICY', 'INTERNAL'); Query OK, 0 rows affected obclient> CALL SA_SESSION.SET_ROW_LABEL('MY_POLICY', 'INTERNAL'); Query OK, 0 rows affected obclient> SELECT SA_SESSION.LABEL('MY_POLICY') FROM DUAL; +-------------------------------+ | SA_SESSION.LABEL('MY_POLICY') | +-------------------------------+ | INTERNAL | +-------------------------------+ 1 row in set obclient> SELECT SA_SESSION.ROW_LABEL('MY_POLICY') FROM DUAL; +-----------------------------------+ | SA_SESSION.ROW_LABEL('MY_POLICY') | +-----------------------------------+ | INTERNAL | +-----------------------------------+ 1 row in set进行查询,可以看到用户
user1可以访问到 Level 为INTERNAL以下级别的数据。obclient> SELECT * FROM tbl1; +------+------+----------+ | COL1 | COL2 | MY_LABEL | +------+------+----------+ | 1 | 1 | 10000 | | NULL | NULL | 20000 | | 2 | NULL | 10000 | +------+------+----------+ 3 rows in set修改 Label 后,再次查询,可以看到用户
user1只能访问到 Level 为PUBLIC级别的数据。obclient> CALL SA_SESSION.SET_LABEL('MY_POLICY', 'PUBLIC'); Query OK, 0 rows affected obclient> CALL SA_SESSION.SET_ROW_LABEL('MY_POLICY', 'PUBLIC'); Query OK, 0 rows affected obclient> SELECT * FROM tbl1; +------+------+----------+ | COL1 | COL2 | MY_LABEL | +------+------+----------+ | 1 | 1 | 10000 | | 2 | NULL | 10000 | +------+------+----------+ 2 rows in set