oracle label security(OLS)相关主体流程整理

一个OLS简单应用场景, 下面的列子将实现这样的功能:

  1. 创建4个level, 级别从高到低依次为: top, high, middle, low;
  2. 给stu表上所有数据添加标签;
  3. 如果用户被赋予第一个标签, 则能查看所有带标签数据;
  4. 如果用户被赋予第二个标签, 则能查看对应级别及其以下的数据;
  5. 用户在授权范围内调整会话label, 重新查看数据;

步骤:

  1. 准备2个账户, quzq和us1, quzq用来创建table及赋权label, us1用来作为特权账户给数据添加label:

create user quzq identified by lala123;

grant connect, resource, dba to quzq;

create user us1 identified by lala123;

grant connect, resource, dba to us1;

  1. 使用quzq账户创建stu表, 并添加数据:

create table stu(s1 nvarchar2(10));

insert into stu values(1);

insert into stu values(2);

insert into stu values(3);

insert into stu values(4);

  1. 连接lbacsys账户创建policy及其组件(此处创建了上面所说的4个level)

exec sa_sysdba.create_policy('my_policy', 'ols_name','ALL_CONTROL');          # 创建policy, 参数详见下方ols使用的3个阶段

exec sa_components.create_level('my_policy', 100, 'low', 'low_level');                # 创建policy的level组件

exec sa_components.create_level('my_policy', 200, 'middle', 'middle_level');

exec sa_components.create_level('my_policy', 300, 'high', 'high_level');

exec sa_components.create_level('my_policy', 400, 'top', 'top_level');

  1. 创建label

exec sa_label_admin.create_label('my_policy',40000,'top',true);

exec sa_label_admin.create_label('my_policy',30000,'high',true);

exec sa_label_admin.create_label('my_policy',20000,'middle',true);

exec sa_label_admin.create_label('my_policy',10000,'low',true);

  1. 应用policy到table

exec sa_policy_admin.apply_table_policy('my_policy','quzq','stu');

此时使用quzq和us1账户分别查看stu表结果如下:

image.png

 

image.png

查看表结构,如下:

image.png

  1. 给quzq用户赋权第一个label, 再次查看数据:

exec sa_user_admin.set_user_labels('my_policy','quzq','top');

重新登录查看结果如下:

image.png

  1. 使用lbacsys给us1账户赋特权, 绕开OLS验证, 重新登录us1账户查看数据, 并给数据行添加label

execute sa_user_admin.set_user_privs('my_policy','us1','FULL');

image.png

 

  1. 再次使用quzq账户查看stu表:

image.png

  1. 使用lbacsys账户给quzq用户赋权第二个标签, 登录quzq账户再次查看stu表:

exec sa_user_admin.set_user_labels('my_policy','quzq','high');

image.png

  1. 用户端在权限范围内修改会话的label, 再次查看stu表:

上一步的赋权用户label中第三个参数指定了用户的最高label为high, 最低默认为low, 会话label默认也是high,

所以当前用户的权限范围可在low, middle和high中随意指定, 而不能指定成范围之外的top:

exec sa_session.set_label('my_policy','top');

image.png

  1. 使用当前会话进行insert操作:

image.png

 

 

 

OLS使用流程可拆分为3个阶段, 以下通过对这3个阶段的描述来说明OLS的使用

一.定义阶段

    定义阶段包含定义policy及其组件,以及使用定义好的组件来创建label, 如下:

    1.创建policy

语法: exec sa_sysdba.create_policy(policy_name, 'ols_name','');

说明: policy是使用OLS的基础, 其相当于个容器, 该容器内包含有3个组件, 分别为level, compartment和group;

参数: policy_name参数用来给policy命名, policy的名称必须是唯一的;

  column_name参数用于定义将policy应用到table时, 表中生成的label列名;

  default_options参数用于设定默认的策略控制选项, 如将policy应用到table时不指定控制选项, 则此默认值生效;

 

    2.在policy中创建level

语法: exec sa_components.create_level(policy_name, level_num, short_name, long_name);

说明: level是policy中的必有组件, 其具有层级关系, level个数无明确限制, 但level_num必须唯一;

参数: policy_name参数用于指定该level属于哪个policy的组件;

  level_num参数取值0-9999, 数值越大表示其层级越高, 同一个policy中level_num值唯一;

  short_name参数用于给level设定简写名称, level被引用时使用该名称;

  long_name参数用于给level设定全名;

 

    3.在policy中创建compartment

语法: exec sa_components.create_compartment(policy_name, comp_num, short_name, long_name);

说明: compartment是可选组件, 没有级别或层级的区分, 个数无明确限制, 但comp_num必须唯一;

参数: policy_name参数用于指定该compartment属于哪个policy的组件;

  comp_num参数取值0-9999, 数值大小只影响显示时的排序, 同一个policy中comp_num值唯一;

  short_name参数用于给compartment设定简写名称, compartment被引用时使用该名称;

  long_name参数用于给compartment设定全名;

 

    4.在policy中创建group

语法: sa_components.create_group(policy_name, group_num, short_name, long_name, parent_name);

说明: group是可选组件, 有子集或父集区分, 个数无明确限制, 但group_num必须唯一;

参数: policy_name参数用于指定该group属于哪个policy的组件;

  group_num参数取值0-9999, 数值大小只影响显示时的排序, 同一个policy中group_num值唯一;

  short_name参数用于给group设定简写名称, group被引用时使用该名称;

  long_name参数用于给group设定全名;

  parent_name参数用户指定该group的父集, 该参数可选;

 

    5.创建label

语法: exec sa_label_admin.create_label(policy_name, label_tag, label_value, data_label);

说明: label有两方面用处, 一方面用于表中数据行, 另一方面用于赋给用户; 用于控制用户能访问到的数据;

参数: policy_name参数用于指定生成哪个policy的label;

  label_tag参数取值0-99999999,数值大小只影响显示时的排序,表中数据行添加label后会显示该值;

  label_value参数使用policy中的level,compartment,group来生成, 如: 'level:compartment:group';

  data_label参数取值为布尔型, TRUE表示该label可用于数据行;

 

二.应用阶段

    包含: 将policy应用到table或schema上, 将label赋给用户, 将表中原有数据添加label, 如下:

    1.将policy应用到table或schema(此处以应用到table来说明)

语法: exec sa_policy_admin.apply_table_policy(policy_name, schema_name, table_name, table_options,

  label_function, predicate);

说明: 将policy成功应用到table上, 所有访问该table的用户都获取不到任何数据, 对表的所有想要的控制也是在

  这个阶段设定的, 通过table_options的参数选项来实现,. 前3个参数是必选的.

参数: policy_name参数用于指定将被应用的policy名称;

  schema_name参数用于指定用户schema;

  table_name参数用于指定给哪张表添加policy;

  table_options参数用于设定对表的控制项, oracle提供有10个选项, 可按需选取;

  label_function参数用于设定生成label的函数;

  predicate参数配合options选项为READ_CONTROL时使用;

 

    2.将label赋给用户

将label赋给用户oracle提供有两类方法: 一类是按照组件给用户赋权, 一类是通过label string给用户赋权;

1.按照组件的赋权:

    1).赋权level给用户

    语法: exec sa_user_admin.set_levels(policy_name, user_name, max_level, min_level, def_level, row_level);

    说明: 可单独赋权level给用户;

    参数: policy_name参数用于指定生效的policy;

user_name参数用于指定赋给哪个用户;

max_level参数设置该用户能操控的最高level等级;

min_level参数设置该用户能操控的最低level等级;

def_level参数设置该用户默认的session所使用的level等级;

row_level参数设置该用户缺省insert操作时默认使用的level;

    2).赋权compartment给用户:

    语法:  exec sa_user_admin.set_compartments(policy_name, user_name, read_comps, write_comps,def_comps, row_comps );

    说明: 必须在赋权level给用户的基础上赋权compartment, 不能单独赋权compartment给用户;

    参数: policy_name参数用于指定生效的policy;

user_name参数用于指定赋给哪个用户;

read_comps参数可指定多个以逗号分隔的compartment;

write_comps参数默认为null, null时以read_comps为准;

def_comps参数默认为null, null时以read_comps为准, 设定时必须是read_comps的子集;

row_comps参数默认为null, null时以def_comps为准, 设定时必须是write_comps和def_comps的子集;

    3).赋权group给用户:

    语法: exec sa_user_admin.set_groups(policy_name, user_name, read_groups, write_groups, def_groups,row_groups);

    说明: 不能单独赋权group给用户, 必须是在赋权level的基础上才行;

    参数: policy_name参数用于指定生效的policy;

        user_name参数用于指定赋给哪个用户;

read_groups参数可指定多个以逗号分隔的group;

write_groups参数默认为null, null时以read_groups为准;

def_groups参数默认为null, null时以read_groups为准, 设定时必须是read_groups的子集;

row_groups参数默认null, null时以def_groups为准, 设定时必须是write_groups和def_groups的子集;

 

2.通过label string给用户赋权:

语法: exec sa_user_admin.set_user_labels(policy_name, user_name, max_read_label, max_write_label,min_write_label, def_label, row_label);

说明: label string赋权是结合了policy中所有组件, 以字符形式的一种赋权, 两种赋权任选其一即可.

参数: policy_name参数用于指定生效的policy;

        user_name参数用于指定赋给哪个用户;

  max_read_label参数用于指定最大的read权限的label, 如: 'l : c : g1, g2';

  max_write_label参数默认null, null时以max_read_label为准;

  min_write_label参数默认null, null时为最低level, 无compartment和group;

  def_label参数取值必须是max_read_label的子集, null时以max_read_label为准;

  row_label参数指定默认的行label, 必须是max_write_label和def_label的子集;

 

3.为表中已有数据行添加label(可选操作, 视场景选用)

table上应用policy后,有且只有数据行label和用户label能匹配上的数据才能被访问到, 默认没有label的数据行永

远无法被访问. 如对表应用policy之前,表中就存有数据的场景, 在应用policy后需要为这部分数据添加label.

1).普通用户的特权管理:

语法: exec sa_user_admin.set_user_privs(policy_name, user_name, privileges);

说明: policy应用到table后, 普通用户在不赋权label时无法无法操控数据库, 要为原有数据添加label只能使用特权来绕过OLS的认证.

参数: policy_name参数用于指定特权对哪个policy生效;

  user_name参数用于指定对哪个用户授权;

  privileges参数用于指定授予什么样的特权, 此参数的取值oracle提供有7个选项, 可控制不同的特权范围;

2).特权设置成功即可绕开OLS相应的验证, 以update形式给数据添加label:

update stu set OLS_CNAME=CHAR_TO_LABEL('my_policy','internal:fin,hr:west,east');

 

三.使用阶段

    1.用户在权限范围内自定义session label

说明: 在给用户设置label时, 设定有用户默认的初始化连接数据库的label, 也设定有用户的最大和最小label.

         session label的取值决定着用户所能操作的数据范围, 某些场景需要在权限范围内调高或调低session权限;

语法: exec sa_session.set_label(policy_name, label);

参数: policy_name参数用于指定policy名称;

         label参数用于设定当前session使用的label, 此处取值不能超出设定的最高和最低label范围;

 

    2.用户在权限范围内自定义row label

说明: 在给用户设置label时, 设定有用户默认的row label. row babel用于insert时不指定label值时的默认使用值,

          在使用某些table_options选项来限制table时, row label的权限不能高于session label.

语法: exec sa_session.set_row_label(policy_name, label);

参数: policy_name参数用于指定policy名称;

         label参数用于设定不指定label时的insert默认值, 此处取值不能超出设定的最高和最低label范围;

 

总结:

  1. 以上为使用OLS的主体流程描述, 不包含所有的OLS功能.
  2. OLS使用过程中比较复杂的地方在应用policy到table时的table_options选项,不同选项控制着不同的OLS行为,也会影响着各种给用户赋权label时的参数选定, 以及用户使用过程中自定义的session label和row label的取值. 去理解单独的某个功能或参数的取值没有意义, 需要结合OLS整个流程中的上下文环境去设定合适的场景.
  3. OLS相关视图如下:

查看创建的policy:               select * from dba_sa_policies;

查看创建的level:                 select * from dba_sa_levels;

查看创建的compartments:  select * from dba_sa_compartments;

查看创建的groups:             select * from dba_sa_groups;

查看创建的labels:               select * from dba_sa_labels;

查看table上的policy:          select * from dba_sa_table_policies;

查看用户的label:                select * from dba_sa_user_labels;

查看当前session label:       select sa_session.label('MY_POLICY') from dual;

查看当前row label:            select sa_session.row_label('MY_POLICY') from dual;

  1. policy中level, compartment, group对数据进行逻辑分类的三个维度:

image.png

posted @ 2020-01-02 19:03  叶落kiss  阅读(760)  评论(0编辑  收藏  举报