#强制访问控制

YashanDB支持基于标签的访问控制,可以实现行级的强访问控制,根据用户的标签以及数据的标签来控制数据访问,精准控制用户对表中各行数据的读写权限,保证读写数据的安全。

# 基本原理

LBAC是强访问控制的一种方式,通过向表应用标签策略自动在目标表中新增一列记录每行数据的标签(Label),以行为颗粒度对数据进行分级和分类,再为用户分配不同的标签限制其对数据的访问权限。策略与表的应用(关联)关系允许多对多,策略应用后立即生效。

  • 标签策略(Label Policy):用于定义标签的格式与验证规则,通过应用策略将标签与表、用户建立关联关系。

  • 标签:由等级(Level)和范围(Compartment)组成,通常表示为等级1,等级2…:范围1,范围2…

    • 等级:用于定义受保护数据的敏感度等级,数值越大表示敏感度越高,例如使用10表示“公共”、20表示“机密”。

    • 范围:用于对受保护数据进行分类,例如使用1表示“员工信息”、2表示“客户信息”。

当用户尝试访问受保护数据时,该用户的安全标签将与受保护数据的标签进行比较:

  • 对于读访问(SELECT):用户只允许查询被LBAC授权可读的行,须同时满足以下要求:

    • 用户的最大读标签中的等级值(DBA_SA_USER_LABELS视图中的MAX_READ_LABEL所对应的等级值) ≥ 目标数据行标签中的等级值

    • 用户标签中的范围集包含目标数据标签中的所有范围

  • 对于写访问(INSERT、UPDATE、DELETE):用户只允许修改、删除或插入被LBAC授权可写的行,须同时满足以下要求:

    • 用户的最小写标签中的等级值(DBA_SA_USER_LABELS视图中的MIN_WRITE_LABEL所对应的等级值) ≥ 目标数据行标签中的等级值

    • 用户标签中的范围集包含目标数据标签中的所有可写范围

# 配置行访问控制

行访问控制仅适用于HEAP表。

所有LBAC相关的配置操作均由具备LBAC_DBA角色的用户来执行。

配置行访问控制后,可以通过以下视图可获取LBAC标签策略相关信息:

  • DBA_SA_POLICIES:查看当前数据库中的所有LBAC标签策略

  • DBA_SA_LEVELS:查看LBAC标签策略中的等级

  • DBA_SA_COMPARTMENTS:查看LBAC标签策略中的范围

  • DBA_SA_LABELS:查看LBAC标签策略中的标签

  • DBA_SA_TABLE_POLICIES:查看所有已配置行访问控制的表及其对应的策略信息

  • DBA_SA_USER_LABELS:查看所有访问受控的用户及其对应的策略、标签信息

# 准备测试用户与数据表

  1. 以DBA用户连接并登录数据库。

    $ yasql sales/********@192.168.1.2:1688
    YashanDB SQL Enterprise Edition Release {version_number} x86_64
    
    Connected to:
    YashanDB Server Enterprise Edition Release {version_number} x86_64 - Linux
    
    SQL> 
    
  2. 准备LBAC_DBA角色的用户和2个业务用户。

    CREATE USER LBACDBA IDENTIFIED BY Yr_pswd0;
    GRANT LBAC_DBA,DBA TO LBACDBA;
    
    CREATE USER sales1 IDENTIFIED BY Yr_pswd1;
    GRANT CONNECT,CREATE ANY TABLE,SELECT ANY TABLE,INSERT ANY TABLE TO sales1;
    
    CREATE USER sales2 IDENTIFIED BY Yr_pswd2;
    GRANT CONNECT,CREATE ANY TABLE,SELECT ANY TABLE,INSERT ANY TABLE,UPDATE ANY TABLE TO sales2;
    
  3. 切换登录测试用户sales1,并准备数据表。

    conn sales1/********
    
    DROP TABLE IF EXISTS product_lbac;
    CREATE TABLE product_lbac
    (product_no CHAR(5) PRIMARY KEY,
    product_name VARCHAR2(30),
    cost NUMBER,
    price NUMBER
    );
    INSERT INTO product_lbac VALUES ('10001','product001',8,10);
    
    SELECT product_no,product_name,cost,price FROM product_lbac;
    PRODUCT_NO PRODUCT_NAME                             COST       PRICE
    ---------- --------------------------------- ----------- -----------
    11001      product001                                  8          10
    

# 开启行访问控制功能

  1. 切换登录LBAC_DBA角色的用户。

    conn LBACDBA/********
    
  2. 查询DBA_YLS_STATUS视图获取行访问控制功能的状态。

    SELECT name,status FROM DBA_YLS_STATUS;
    NAME                                                             STATUS
    ---------------------------------------------------------------- --------- 
    YLS_ENABLE_STATUS                                                FALSE
    
  3. 若暂未开启行访问控制功能,需调用YLS_ENFORCEMENT.ENABLE_YLS开启该功能。

    CALL YLS_ENFORCEMENT.ENABLE_YLS;
    
    SELECT name,status FROM DBA_YLS_STATUS;
    
    NAME                                                             STATUS
    ---------------------------------------------------------------- --------- 
    YLS_ENABLE_STATUS                                                TRUE
    

# 为数据配置标签策略

  1. 调用SA_SYSDBA.CREATE_POLICY创建LBAC标签策略。

    CALL SA_SYSDBA.CREATE_POLICY ('product_lbac', 'policy_col', 'READ_CONTROL,WRITE_CONTROL');
    
    SELECT policy_name,column_name,status,policy_options FROM DBA_SA_POLICIES WHERE POLICY_NAME = 'PRODUCT_LBAC';
    POLICY_NAME          COLUMN_NAME            STATUS    POLICY_OPTIONS
    -------------------- ---------------------- --------- ----------------------------------------------------------------
    PRODUCT_LBAC         POLICY_COL             ENABLED   READ_CONTROL, INSERT_CONTROL, UPDATE_CONTROL, DELETE_CONTROL
    
  2. 调用SA_COMPONENTS.CREATE_LEVEL为LBAC标签策略创建等级。

    CALL SA_COMPONENTS.CREATE_LEVEL ('product_lbac', 100, 'low', 'low_level');
    CALL SA_COMPONENTS.CREATE_LEVEL ('product_lbac', 200, 'mid', 'middle_level');
    CALL SA_COMPONENTS.CREATE_LEVEL ('product_lbac', 300, 'high', 'high_level');
    CALL SA_COMPONENTS.CREATE_LEVEL ('product_lbac', 500, 'top', 'top_level');
    
    SELECT policy_name,level_num,short_name FROM DBA_SA_LEVELS  WHERE POLICY_NAME = 'PRODUCT_LBAC';
    POLICY_NAME                  LEVEL_NUM SHORT_NAME                                                    
    ---------------------------- --------- ---------------------
    RODUCT_LBAC                  100       LOW
    PRODUCT_LBAC                 200       MID
    PRODUCT_LBAC                 300       HIGH
    PRODUCT_LBAC                 500       TOP
    
  3. 调用SA_COMPONENTS.CREATE_COMPARTMENT为LBAC标签策略创建范围。

    CALL SA_COMPONENTS.CREATE_COMPARTMENT ('product_lbac', 100, 'MNG', 'MANAGER');
    CALL SA_COMPONENTS.CREATE_COMPARTMENT ('product_lbac', 200, 'QA', 'QAT');
    CALL SA_COMPONENTS.CREATE_COMPARTMENT ('product_lbac', 300, 'RD', 'RDB');
    CALL SA_COMPONENTS.CREATE_COMPARTMENT ('product_lbac', 500, 'EG', 'EGA');
    
    SELECT policy_name,comp_num,short_name FROM DBA_SA_COMPARTMENTS WHERE POLICY_NAME = 'PRODUCT_LBAC';
    POLICY_NAME                  COMP_NUM SHORT_NAME           
    ---------------------------- -------- --------------------- 
    PRODUCT_LBAC                 100      MNG
    PRODUCT_LBAC                 200      QA
    PRODUCT_LBAC                 300      RD
    PRODUCT_LBAC                 500      EG
    
  4. 调用SA_LABEL_ADMIN.CREATE_LABEL,为LBAC标签策略创建标签。

    CALL SA_LABEL_ADMIN.CREATE_LABEL ('product_lbac', 100000, 'low');
    CALL SA_LABEL_ADMIN.CREATE_LABEL ('product_lbac', 200200, 'mid:QA');
    CALL SA_LABEL_ADMIN.CREATE_LABEL ('product_lbac', 300300, 'high:RD');
    CALL SA_LABEL_ADMIN.CREATE_LABEL ('product_lbac', 500500, 'top:MNG,QA,RD,EG');
    
    SELECT policy_name,label,label_tag,label_type FROM DBA_SA_LABELS WHERE POLICY_NAME = 'PRODUCT_LBAC';
    POLICY_NAME                  LABEL                 LABEL_TAG             LABEL_TYPE
    ---------------------------- --------------------- --------------------- -----------------
    PRODUCT_LBAC                 LOW                   100000                USER/DATA LABEL
    PRODUCT_LBAC                 MID:QA                200200                USER/DATA LABEL
    PRODUCT_LBAC                 HIGH:RD               300300                USER/DATA LABEL
    PRODUCT_LBAC                 TOP:MNG,QA,RD,EG      500500                USER/DATA LABEL
    
  5. 调用SA_POLICY_ADMIN.APPLY_TABLE_POLICY将LBAC标签策略应用至目标数据表。

    CALL SA_POLICY_ADMIN.APPLY_TABLE_POLICY ('product_lbac', 'sales1', 'product_lbac');
    
    SELECT policy_name,schema_name,table_name,status,table_options FROM DBA_SA_TABLE_POLICIES WHERE POLICY_NAME = 'PRODUCT_LBAC';
    POLICY_NAME                  SCHEMA_NAME    TABLE_NAME     STATUS    TABLE_OPTIONS                                                                                                        
    ---------------------------- -------------- -------------- --------- ----------------------------------------------------------------  
    PRODUCT_LBAC                 SALES1         PRODUCT_LBAC   ENABLED   READ_CONTROL, INSERT_CONTROL, UPDATE_CONTROL, DELETE_CONTROL
    
    -- 查看目标表的结构
    desc sales1.product_lbac
    NAME                           NULL?     DATATYPE
    ------------------------------ --------- ---------------------------------
    PRODUCT_NO                     NOT NULL  CHAR(5)
    PRODUCT_NAME                             VARCHAR(30)
    COST                                     NUMBER
    PRICE                                    NUMBER
    POLICY_COL                               BIGINT
    

    从回显信息可知,目标表中已自动增加策略列policy_col。后续插入表数据时,可为每行数据自定义配置不同的标签值,但必须使用与关联策略中已存在的标签值。

# 为用户配置标签策略

  1. 调用SA_USER_ADMIN.SET_USER_LABELS向目标用户应用标签策略,设置目标用户的标签。

    CALL SA_USER_ADMIN.SET_USER_LABELS ('product_lbac', 'sales1', 'high:RD');
    CALL SA_USER_ADMIN.SET_USER_LABELS ('product_lbac', 'sales2', 'mid:QA');
    
    SELECT user_name,policy_name,max_read_label,max_write_label,min_write_label FROM DBA_SA_USER_LABELS WHERE POLICY_NAME = 'PRODUCT_LBAC';
    USER_NAME      POLICY_NAME                  MAX_READ_LABEL        MAX_WRITE_LABEL       MIN_WRITE_LABEL
    -------------- ---------------------------- --------------------- --------------------- --------------------- 
    SALES1         PRODUCT_LBAC                 HIGH:RD               HIGH:RD               LOW               
    SALES2         PRODUCT_LBAC                 MID:QA                MID:QA                LOW
    

# 检验访问控制效果

  • 验证用户sales1的访问控制是否生效。

    1. )切换登录测试用户sales1。

      conn sales1/********
      
    2. )查看测试表product_lbac的数据。

      SELECT product_no,product_name,cost,price,policy_col FROM product_lbac;
      -- 无法再查看历史数据(11001,product001,8,10)
      

      策略应用到表时,不会为表中已存在的历史数据行指定标签值,该类数据将无法被普通用户读写(仅sys可读写)。

    3. )插入数据至测试表product_lbac。

      -- 正确示例
      INSERT INTO product_lbac VALUES ('10002','product002',13,16,100000);
      INSERT INTO product_lbac VALUES ('10003','product003',199,200,300300);
      
      -- 错误示例:不允许指定比用户标签等级高的标签值
      INSERT INTO product_lbac VALUES ('10004','product004',199,200,500500);
      
      -- 错误示例:不允许指定为不存在的标签值
      INSERT INTO product_lbac VALUES ('10005','product005',1995,2200,600000);
      
      COMMIT;
      
    4. )再次查看测试表product_lbac的数据。

      SELECT product_no,product_name,cost,price,policy_col FROM product_lbac;
      PRODUCT_NO PRODUCT_NAME                             COST       PRICE            POLICY_COL
      ---------- --------------------------------- ----------- ----------- ---------------------
      10002      product002                                 13          16                100000
      10003      product003                                199         200                300300
      
  • 验证用户sales2的访问控制是否生效。

    1. )切换登录测试用户sales2。

      conn sales2/********
      
    2. )查看测试表product_lbac的数据。

      SELECT product_no,product_name,cost,price,policy_col FROM sales1.product_lbac;
      PRODUCT_NO PRODUCT_NAME                             COST       PRICE            POLICY_COL
      ---------- --------------------------------- ----------- ----------- ---------------------
      10002      product002                                 13          16                100000
      

      sales2用户的标签为MID:QA,只能查看等级比MID低且范围属于QA子集(空集亦为子集)的数据行。

    3. )对测试表product_lbac执行写操作。

      -- 正确示例
      INSERT INTO sales1.product_lbac VALUES ('10007','product007',80,120,200200);
      UPDATE sales1.product_lbac SET PRICE = 25 WHERE PRODUCT_NO = 10002;
      
      -- 错误示例:不允许更新不具有读写权限的现有数据行
      UPDATE sales1.product_lbac SET PRICE = 269 WHERE PRODUCT_NO = 10003;
      
      COMMIT;
      
    4. )再次查看测试表product_lbac的数据。

      SELECT product_no,product_name,cost,price,policy_col FROM sales1.product_lbac;
      
      PRODUCT_NO PRODUCT_NAME                             COST       PRICE            POLICY_COL
      ---------- --------------------------------- ----------- ----------- ---------------------
      10002      product002                                 13          25                100000
      10007      product007                                 80         120                200200
      
    5. )切换登录LBAC_DBA角色的用户,更新sales2的标签。

      conn LBACDBA/********
      
      CALL SA_USER_ADMIN.SET_USER_LABELS ('product_lbac', 'sales2', 'top:MNG,QA,RD,EG');
      
    6. )切换登录测试用户sales2,对测试表product_lbac进行读写操作。

      conn sales2/********
      
      SELECT product_no,product_name,cost,price,policy_col FROM sales1.product_lbac;
      PRODUCT_NO PRODUCT_NAME                             COST       PRICE            POLICY_COL
      ---------- --------------------------------- ----------- ----------- ---------------------
      10002      product002                                 13          16                100000
      10003      product003                                199         200                300300
      10007      product007                                 80         120                200200
      
      UPDATE sales1.product_lbac SET PRICE = 269 WHERE PRODUCT_NO = 10003;
      
      SELECT product_no,product_name,cost,price,policy_col FROM sales1.product_lbac;
      PRODUCT_NO PRODUCT_NAME                             COST       PRICE            POLICY_COL
      ---------- --------------------------------- ----------- ----------- ---------------------
      10002      product002                                 13          16                100000
      10003      product003                                199         269                300300
      10007      product007                                 80         120                200200
      

      sales2用户的标签权限范围扩大后,可读写的数据行变多。

edit-icon
反馈
coperate-icon
coperate
合作
communication-icon
communicate
交流