在上一篇文章中讨论了如何利用VPD对Oracle表中的行进行访问控制(见《[Oracle] 数据库安全之 - 虚拟私有数据库 (VPD)》),下面介绍一种比VPD复杂一点的访问控制技术——OLS (Oracle Label Security)。
如果你的数据库版本是10g,则需要额外安装OLS组件,但如果是11g,只要启用OLS即可,因为11g里OLS是默认安装的,下面是11g下启动OLS的语句:
C:\Users\xianzhu>chopt enable lbac
Writing to C:/app/xianzhu/product/11.2.0/dbhome_1/install/enable_lbac.log...
movefile C:\app\xianzhu\product\11.2.0\dbhome_1/bin/oralbac11.dll.dbl C:\app\xianzhu\product\11.2.0\dbhome_1/bin/oralbac11.dll
C:\Users\xianzhu>sqlplus test/test
SQL*Plus: Release 11.2.0.1.0 Production on 星期日 6月 9 09:40:17 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining
and Real Application Testing options
1)如果你照以上步骤,正确启用OLS之后,Oracle会创建一个用户lbacsys,但是该用户是被锁的,首次使用需要解锁并修改密码:
SQL> alter user lbacsys account unlock;
用户已更改。
SQL> alter user lbacsys identified by lbacsys;
用户已更改。
SQL> conn lbacsys/lbacsys
已连接。
SQL> exec sa_sysdba.create_policy(policy_name => 'ACCESS_LOCATIONS', column_name => 'OLS_COLUMNE');
PL/SQL 过程已成功完成。
SQL> select policy_name, status from dba_sa_policies;
POLICY_NAME STATUS
------------------------------ --------
ACCESS_LOCATIONS ENABLED
SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>1000,short_name=>'PUB',long_name=>'PUBLIC CITY');
PL/SQL 过程已成功完成。
SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>2000,short_name=>'CONF',long_name=>'CONFIDENTIAL CITY');
PL/SQL 过程已成功完成。
SQL> exec sa_components.create_level(policy_name=>'ACCESS_LOCATIONS',level_num=>3000,short_name=>'SENS',long_name=>'SENSITIVE CITY');
PL/SQL 过程已成功完成。
SQL> select * from dba_sa_levels order by level_num;
POLICY_NAME LEVEL_NUM SHORT_NAME LONG_NAME
-------------------- ---------- ---------- --------------------
ACCESS_LOCATIONS 1000 PUB PUBLIC CITY
ACCESS_LOCATIONS 2000 CONF CONFIDENTIAL CITY
ACCESS_LOCATIONS 3000 SENS SENSITIVE CITY
SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'1000',label_value=>'PUB',data_label=>TRUE);
PL/SQL 过程已成功完成。
SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'2000',label_value=>'CONF',data_label=>TRUE);
PL/SQL 过程已成功完成。
SQL> exec sa_label_admin.create_label(policy_name=>'ACCESS_LOCATIONS',label_tag=>'3000',label_value=>'SENS',data_label=>TRUE);
PL/SQL 过程已成功完成。
SQL> exec sa_policy_admin.apply_table_policy(policy_name=>'ACCESS_LOCATIONS',schema_name=>'HR',table_name=>'LOCATIONS',table_options=>'LABEL_DEFAULT,READ_CONTROL');
PL/SQL 过程已成功完成。
SQL> create user tom identified by tom;
用户已创建。
SQL> create user peter identified by peter;
用户已创建。
SQL> create user rose identified by rose;
用户已创建。
SQL> grant connect to tom, peter, rose;
授权成功。
SQL> grant select on hr.locations to tom, peter, rose;
授权成功。
SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'TOM',max_read_label=>'SENS');
PL/SQL 过程已成功完成。
SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'PETER',max_read_label=>'CONF');
PL/SQL 过程已成功完成。
SQL> exec sa_user_admin.set_user_labels(policy_name=>'ACCESS_LOCATIONS',user_name=>'ROSE',max_read_label=>'PUB');
PL/SQL 过程已成功完成。
SQL> execute sa_user_admin.set_user_privs(policy_name=>'ACCESS_LOCATIONS',user_name=>'HR',privileges=>'FULL');
PL/SQL 过程已成功完成。
SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','SENS') where upper(city) in ('BEIJING','TOKYO','SINGAPORE');
已更新3行。
SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','CONF') where upper(city) in ('MUNICH','OXFORD','ROME');
已更新2行。
SQL> update hr.locations set ols_columne=CHAR_TO_LABEL('ACCESS_LOCATIONS','PUB') where ols_columne is null;
已更新18行。