Oracle VPD数据细粒度访问实现方法(下)

原创|其它|编辑:郝浩|2010-02-21 13:26:30.000|阅读 531 次

概述:虚拟专用数据库 (VPD) 提供了角色和视图无法提供的行级访问控制。对于互联网访问,虚拟专用数据库可以确保在线银行的客户只能看到他们自己的帐户。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  4. 建立安全策略


  view plaincopy to clipboardprint?
  CONNECT schemaowner/schemaowner@service;
  CREATE OR REPLACE PACKAGE Security_Package AS
  FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname VARCHAR2)
  RETURN VARCHAR2;
  FUNCTION User_Data_Select_Security(Owner VARCHAR2, Objname VARCHAR2)
  RETURN VARCHAR2;
  END Security_Package;
  /
  CREATE OR REPLACE PACKAGE BODY Security_Package IS
  FUNCTION User_Data_Select_Security(Owner VARCHAR2, Objname VARCHAR2)RETURN VARCHAR2 IS
  Predicate VARCHAR2(2000);
  BEGIN
  Predicate := '1=2';
  IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'SCHEMAOWNER') THEN
  Predicate := NULL;
  ELSE
  Predicate := 'USER_ID = SYS_CONTEXT(''SCHEMAOWNER'',''USER_ID'')';
  END IF;
  RETURN Predicate;
  END User_Data_Select_Security;
  FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2 IS
  Predicate VARCHAR2(2000);
  BEGIN
  Predicate := '1=2';
  IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'SCHEMAOWNER') THEN
  Predicate := NULL;
  ELSE
  Predicate := 'USER_ID = SYS_CONTEXT(''SCHEMAOWNER'',''USER_ID'')';
  END IF;
  RETURN Predicate;
  END User_Data_Insert_Security;
  END Security_Package;
  /
  SHOW ERRORS
  GRANT EXECUTE ON SCHEMAOWNER.Security_Package TO PUBLIC;
  CREATE PUBLIC SYNONYM Security_Package FOR SCHEMAOWNER.Security_Package;
  CONNECT schemaowner/schemaowner@service;
  CREATE OR REPLACE PACKAGE Security_Package AS
  FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname VARCHAR2)
  RETURN VARCHAR2;
  FUNCTION User_Data_Select_Security(Owner VARCHAR2, Objname VARCHAR2)
  RETURN VARCHAR2;
  END Security_Package;
  /
  CREATE OR REPLACE PACKAGE BODY Security_Package IS
  FUNCTION User_Data_Select_Security(Owner VARCHAR2, Objname VARCHAR2)RETURN VARCHAR2 IS
  Predicate VARCHAR2(2000);
  BEGIN
  Predicate := '1=2';
  IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'SCHEMAOWNER') THEN
  Predicate := NULL;
  ELSE
  Predicate := 'USER_ID = SYS_CONTEXT(''SCHEMAOWNER'',''USER_ID'')';
  END IF;


  RETURN Predicate;
  END User_Data_Select_Security;
  FUNCTION User_Data_Insert_Security(Owner VARCHAR2, Objname VARCHAR2) RETURN VARCHAR2 IS
  Predicate VARCHAR2(2000);
  BEGIN
  Predicate := '1=2';
  IF (SYS_CONTEXT('USERENV','SESSION_USER') = 'SCHEMAOWNER') THEN
  Predicate := NULL;
  ELSE
  Predicate := 'USER_ID = SYS_CONTEXT(''SCHEMAOWNER'',''USER_ID'')';
  END IF;
  RETURN Predicate;
  END User_Data_Insert_Security;
  END Security_Package;
  /
  SHOW ERRORS
  GRANT EXECUTE ON SCHEMAOWNER.Security_Package TO PUBLIC;
  CREATE PUBLIC SYNONYM Security_Package FOR SCHEMAOWNER.Security_Package;

  5. 应用策略到相应的表,使用RDBMS_RLS


  view plaincopy to clipboardprint?
  BEGIN
  DBMS_Rls.Add_Policy('SCHEMAOWNER', 'USER_DATA', 'USER_DATA_INSERT_POLICY',
  'SCHEMAOWNER', 'SECURITY_PACKAGE.USER_DATA_INSERT_SECURITY',
  'INSERT', TRUE);
  DBMS_Rls.Add_Policy('SCHEMAOWNER', 'USER_DATA', 'USER_DATA_SELECT_POLICY',
  'SCHEMAOWNER', 'SECURITY_PACKAGE.USER_DATA_SELECT_SECURITY',
  'SELECT');
  END;
  /
  BEGIN
  DBMS_Rls.Add_Policy('SCHEMAOWNER', 'USER_DATA', 'USER_DATA_INSERT_POLICY',
  'SCHEMAOWNER', 'SECURITY_PACKAGE.USER_DATA_INSERT_SECURITY',
  'INSERT', TRUE);
  DBMS_Rls.Add_Policy('SCHEMAOWNER', 'USER_DATA', 'USER_DATA_SELECT_POLICY',
  'SCHEMAOWNER', 'SECURITY_PACKAGE.USER_DATA_SELECT_SECURITY',
  'SELECT');
  END;
  /

  6. VPD测试


  view plaincopy to clipboardprint?
  CONNECT user1/user1@service;
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 1', 1);
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 2', 2);
  COMMIT;
  CONNECT user2/user2@service
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 1', 1);
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 2', 2);


  COMMIT;
  CONNECT schemaowner/schemaowner@service
  SELECT * FROM schemaowner.user_data;
  CONNECT user1/user1@Service;
  SELECT * FROM schemaowner.user_data;
  CONNECT user2/user2@Service
  SELECT * FROM schemaowner.user_data;
  CONNECT user1/user1@service;
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 1', 1);
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 2', 2);
  COMMIT;
  CONNECT user2/user2@service
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 1', 1);
  INSERT INTO schemaowner.user_data (column1, user_id) VALUES ('User 2', 2);
  COMMIT;
  CONNECT schemaowner/schemaowner@service
  SELECT * FROM schemaowner.user_data;
  CONNECT user1/user1@Service;
  SELECT * FROM schemaowner.user_data;
  CONNECT user2/user2@Service
  SELECT * FROM schemaowner.user_data;

  测试结果:

  (1) user1用户登陆的: 只用第一条insert成功

  (2) user2用户登陆的: 只用第二条insert成功

  (3) 关于查询:

  user1和user2都只能看到自己的资料,而schemaowner可以看到所有的资料。这里重点是所添加的谓词不同,在安全策略中的

  Predicate := 'USER_ID = SYS_CONTEXT(''SCHEMAOWNER'',''USER_ID'')';


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP