OceanBase 数据库提供了内置的安全管理员 LBACSYS 来管理和使用该功能,安全管理员可以通过创建安全策略、定义策略中的 Label、设置用户的 Label,来定制自己的安全策略。一个安全策略可以应用到多张表上,一张表也可以应用多个安全策略。每当一个安全策略被应用,这张表上自动会添加一列,用于该安全策略的访问控制。
注意: 目前仅Oracle模式支持Label Security。
环境:ob323
需求:按照文档步骤进行级别权限控制设置
文档: https://www.oceanbase.com/docs/enterprise-oceanbase-database-cn-10000000000354662
问题1:LABCSYS用户无权
解决方案:
1.解锁LABCSYS用户后,需要授予其create session权限
GRANT CREATE SESSION TO LBACSYS;
2.不能使用 conn 切换到LABCSYS,要使用以下命令登录
obclient -hip -uLABCSYS@tenantname#clustername -pPassword
最后按照文档再次进行测试可以成功进行行级权限访问控制
具体步骤如下:
步骤一:解锁用户并授权
OceanBase 数据库提供了内置的安全管理员 LBACSYS 来管理和使用该功能,安全管理员可以通过创建安全策略、定义策略中的 Label、设置用户的 Label,来定制自己的安全策略。一个安全策略可以应用到多张表上,一张表也可以应用多个安全策略。每当一个安全策略被应用,这张表上自动会添加一列,用于该安全策略的访问控制。
使用 sys 用户登录到 Oracle 租户。
解锁 LBACSYS 用户。
OceanBase 数据库默认创建了 LBACSYS 用户,其密码固定为 LBACSYS。该用户处于锁定状态,使用 Label Security 功能需要先启用该用户。
1.1obclient> ALTER USER LBACSYS ACCOUNT UNLOCK;
1.2.修改 LBACSYS 用户的登录密码。
为了保障安全性,LBACSYS 用户的密码由 SYS 用户指定。如果后续需要修改该密码,重新指定一个新的密码即可。
obclient> ALTER USER LBACSYS IDENTIFIED BY ***R***;
设置 LBACSYS 用户的权限。
1.3.LBACSYS 用户默认不带任何权限,为了执行行级访问权限相关的操作,需要通过 GRANT 语句给 LBACSYS 用户授予 CREATE SESSION 权限。
obclient> GRANT CREATE SESSION TO LBACSYS;
步骤二:创建标签安全策略
2.1使用安全管理员 LBACSYS 用户登录到 Oracle 租户。
注意不是使用其他用户登录后再切换到LBACSYS用户,是直接使用LBACSYS用户登录。
obclient -hip -uLABCSYS@tenantname#clustername -pPassword
创建策略 MY_POLICY。
2.2.obclient> CALL SA_SYSDBA.CREATE_POLICY('MY_POLICY','MY_LABEL','');
步骤三:为标签安全策略创建级别
使用安全管理员 LBACSYS 用户登录到 Oracle 租户。
obclient -hip -uLABCSYS@tenantname#clustername -pPassword
3.1创建级别 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_AGENT;
+-----------+-----------------------+------------------------------+------------------------------+--------------------+-----------+----------+------------+----------------+-------------+
| TENANT_ID | LABEL_SE_COMPONENT_ID | GMT_CREATE | GMT_MODIFIED | LABEL_SE_POLICY_ID | COMP_TYPE | COMP_NUM | SHORT_NAME | LONG_NAME | PARENT_NAME |
+-----------+-----------------------+------------------------------+------------------------------+--------------------+-----------+----------+------------+----------------+-------------+
| 1002 | 1101710651032553 | 30-DEC-21 02.35.19.069966 PM | 30-DEC-21 02.35.19.069966 PM | 1101710651032553 | 0 | 100 | PUBLIC | PUBLIC LEVEL | NULL |
| 1002 | 1101710651032554 | 30-DEC-21 02.35.25.787711 PM | 30-DEC-21 02.35.25.787711 PM | 1101710651032553 | 0 | 200 | INTERNAL | INTERNAL LEVEL | NULL |
| 1002 | 1101710651032555 | 30-DEC-21 02.35.31.772544 PM | 30-DEC-21 02.35.31.772544 PM | 1101710651032553 | 0 | 300 | HIGH | HIGH LEVEL | NULL |
+-----------+-----------------------+------------------------------+------------------------------+--------------------+-----------+----------+------------+----------------+-------------+
步骤四:创建数据标签 Label
4.1使用安全管理员 LBACSYS 用户登录到 Oracle 租户。
obclient -hip -uLABCSYS@tenantname#clustername -pPassword
创建数据标签 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_AGENT;
+-----------+-------------------+------------------------------+------------------------------+--------------------+-----------+----------+------+
| TENANT_ID | LABEL_SE_LABEL_ID | GMT_CREATE | GMT_MODIFIED | LABEL_SE_POLICY_ID | LABEL_TAG | LABEL | FLAG |
+-----------+-------------------+------------------------------+------------------------------+--------------------+-----------+----------+------+
| 1002 | 1101710651032553 | 30-DEC-21 02.41.06.668980 PM | 30-DEC-21 02.41.06.668980 PM | 1101710651032553 | 10000 | PUBLIC | 1 |
| 1002 | 1101710651032554 | 30-DEC-21 02.42.09.740930 PM | 30-DEC-21 02.42.09.740930 PM | 1101710651032553 | 20000 | INTERNAL | 1 |
| 1002 | 1101710651032555 | 30-DEC-21 02.42.09.750423 PM | 30-DEC-21 02.42.09.750423 PM | 1101710651032553 | 30000 | HIGH | 1 |
+-----------+-------------------+------------------------------+------------------------------+--------------------+-----------+----------+------+
步骤五:指定用户的 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。
obclient> CALL SA_USER_ADMIN.SET_LEVELS('MY_POLICY', 'user1', 'HIGH','PUBLIC', 'PUBLIC', 'PUBLIC');
Query OK, 0 rows affected
obclient> SELECT * FROM sys.ALL_VIRTUAL_TENANT_OLS_USER_LEVEL_AGENT;
+-----------+------------------------+------------------------------+------------------------------+------------------+--------------------+---------------+---------------+---------------+-----------+
| TENANT_ID | LABEL_SE_USER_LEVEL_ID | GMT_CREATE | GMT_MODIFIED | USER_ID | LABEL_SE_POLICY_ID | MAXIMUM_LEVEL | MINIMUM_LEVEL | DEFAULT_LEVEL | ROW_LEVEL |
+-----------+------------------------+------------------------------+------------------------------+------------------+--------------------+---------------+---------------+---------------+-----------+
| 1002 | 1101710651032553 | 30-DEC-21 04.04.06.712035 PM | 30-DEC-21 04.04.06.712035 PM | 1101710651032553 | 1101710651032553 | 300 | 100 | 100 | 100 |
+-----------+------------------------+------------------------------+------------------------------+------------------+--------------------+---------------+---------------+---------------+-----------+
步骤六:将标签策略应用到表上
以 user1 用户登录到 Oracle 租户,创建表 tbl1。
obclient> CREATE TABLE tbl1(col1 INT,col2 INT);
Query OK, 0 rows affected
以安全管理员 LBACSYS 登录,将策略 MY_POLICY 应用到表 tbl1 上。
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。
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 |
+------+------+----------+
修改 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 |
+------+------+----------+