暂无图片
暂无图片
14
暂无图片
暂无图片
暂无图片

OceanBase设置行级访问权限控制

OceanBase,数据库 2022-09-15
990

OceanBase 数据库兼容了 Oracle 的 Label Security 功能,可以在行级别对访问进行控制,保证读写数据的安全。

Label Security 是强制访问控制的一种方式,通过在表中添加一个 Label 列来记录每行的 Label 值,在访问时通过比较用户的 Label 和数据的 Label,达到约束主体(用户)对客体(表中的数据)访问的目的。

OceanBase 数据库提供了内置的安全管理员 LBACSYS 来管理和使用该功能,安全管理员可以通过创建安全策略、定义策略中的 Label、设置用户的 Label,来定制自己的安全策略。一个安全策略可以应用到多张表上,一张表也可以应用多个安全策略。每当一个安全策略被应用,这张表上自动会添加一列,用于该安全策略的访问控制。

使用限制

目前仅 Oracle 模式支持 Label Security。

示例

  1. 使用 sys 用户登录到 Oracle 租户。

  2. 解锁 LBACSYS 用户。

    OceanBase 数据库默认创建了 LBACSYS 用户,其密码固定为 LBACSYS。该用户处于锁定状态,使用 Label Security 功能需要先启用该用户。

    obclient> ALTER USER LBACSYS ACCOUNT UNLOCK;
    
  3. 使用安全管理员 LBACSYS 用户登录到 Oracle 租户。

  4. 创建策略 MY_POLICY。有关创建新的标签安全策略的详细信息,请参见 SA_SYSDBA.CREATE_POLICY

    示例如下:

    obclient> CALL SA_SYSDBA.CREATE_POLICY('MY_POLICY','MY_LABEL','');
    
  5. 创建级别 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_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        |
    +-----------+-----------------------+------------------------------+------------------------------+--------------------+-----------+----------+------------+----------------+-------------+
    3 rows in set
    
  6. 创建创建数据标签 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_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 |
    +-----------+-------------------+------------------------------+------------------------------+--------------------+-----------+----------+------+
    3 rows in set
    
  7. 指定用户的 Label。

    1. 以 sys 用户登录到 Oracle 租户,创建用户 user1 并授予用户 user1 除 GRANT OPTION 以外所有当前用户拥有的权限。

      obclient> CREATE USER user1 IDENTIFIED BY ***1***;
      Query OK, 0 rows affected
      
      obclient> GRANT ALL PRIVILEGES TO user1;
      Query OK, 0 rows affected
      
    2. 以安全管理员 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> 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 |
      +-----------+------------------------+------------------------------+------------------------------+------------------+--------------------+---------------+---------------+---------------+-----------+
      1 row in set
      
  8. 应用策略到表上。

    1. 以 user1 用户登录到 Oracle 租户,创建表 tbl1

      obclient> CREATE TABLE tbl1(col1 INT,col2 INT);
      Query OK, 0 rows affected
      
    2. 以安全管理员 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
      
  9. 插入数据,验证查询结果。

    1. 以 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
      
    2. 在 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
      
    3. 进行查询,可以看到用户 user1 可以访问到 Level 为 INTERNAL 以下级别的数据。

      obclient> SELECT * FROM tbl1;
      +------+------+----------+
      | COL1 | COL2 | MY_LABEL |
      +------+------+----------+
      |    1 |    1 |    10000 |
      | NULL | NULL |    20000 |
      |    2 | NULL |    10000 |
      +------+------+----------+
      3 rows in set
      
    4. 修改 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
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论