当前位置: 代码迷 >> CGI >> ArcGIS权限分析-如何对同一要素类对不同要素设置权限(Oracle)
  详细解决方案

ArcGIS权限分析-如何对同一要素类对不同要素设置权限(Oracle)

热度:711   发布时间:2013-04-05 10:24:33.0
ArcGIS权限分析-怎么对同一要素类对不同要素设置权限(Oracle)

今天又接到用户来咨询怎么对同一要素类对不同要素设置权限的问题,看来这个需求大家都是非常迫切。


重新解释一下用户的要求,比如说我有一个整个北京市宗地的要素类,所有地区的要素类都在一起,但是有一个要求,用户只想在一个要素类里面进行操作,而且朝阳区国土局的工作人员只能编辑所属朝阳区的数据,海淀区国土局工作人员只能编辑所属海淀区的宗地,其实也就是一个同一要素类对不同要素设置权限的问题。


之所以有这个需求,大家都是所有数据在同一个要素类,而不是分区域要素类,那么对一个要素类的不同要素权限就显得需求迫切了。

在以前我也写过类似的文章,但是那些方法还是有不足之处,不是特别符合要求:http://blog.csdn.net/linghe301/article/details/7053965


今天在Esri中国论坛看到了一个帖子,启发很大,借助于他的建议,自己做了相关实验,还是可以满足相关需求的。

这里感谢@GAT5的分享精神:http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=125974&page=1&extra=#pid1067570

他的帖子细节写的不多,下面我就对我的这次测试,以及在测试中遇到的问题跟大家做分享。


预前知识:VPD
概述

虚拟专用数据库(Virtual Private Database,VPD)将服务器实施的细粒度访问控制和安全应用程序上下文结合起来。支持上下文的函数返回一个谓词,即where子句,该子句自动附加到所有的select语句或其他DML语句。换句话说,由VPD控制的表、视图、同义词上的select语句将根据where子句返回行的子集,该子句由通过应用程序上下文生效的安全策略函数自动生成。VPD的主要组成部分是行级别的安全性(RLS),也称为"细粒度的访问控制"(FGAC)。


因为VPD在语句解析期间透明地生成谓词,因此无论用户是否正在运行特别的查询、检索应用程序中的数据或者查看Oracle Forms中的数据,都可以一致地实施安全策略。因为Oracle Server在解析时将谓词应用于语句,所以应用程序不需要使用特殊的表、视图等来实现该策略。因此,Oracle可以使用索引、物化视图和并行操作来优化查询,而以其他的方式则不能够进行优化。因此,相比于使用应用程序或其他方式过滤结果的查询,使用VPD可能会产生较少的系统开销。


从维护的角度来看,安全策略可以在安全函数中定义,使用角色和权限很难创建这种安全函数。类似地,应用程序服务器提供商(Application Server Provider,ASP)可能只需要建立一个数据库来为相同应用程序的多个客户服务,使用VPD策略来确保一个顾客的雇员只可以查看他们自己的数据。DBA可以使用少量的VPD策略维护一个较大的数据库,而不是针对每个客户都使用一个单独的数据库。


Oracle 10g中的新增内容是列级别的VPD操作。使用列级别的VPD,DBA可以约束对表中特定列的访问。查询返回相同数量的行,但如果用户的上下文不允许访问列,则在约束的列中返回NULL值。



虚拟专用数据库如何工作
将一个或多个安全策略与表或视图关联后,就可以实现虚拟专用数据库。对带安全策略的表进行直接或间接访问时,数据库将调用一个实施该策略的函数。策略函数返回一个访问条件(WHERE 子句),即谓词。应用程序将它附加到用户的 SQL 语句,从而动态修改用户的数据访问权限。

你可以通过编写一个存储过程将 SQL 谓词附加到每个 SQL 语句(用于控制该语句的行级别访问权限)来实施 VPD。例如,如果 John Doe(他属于 Department 10)输入 SELECT * FROM emp 语句,则可以使用 VPD 添加 WHERE DEPT = 10 子句。这样,您便可以通过对查询进行修改来限制访问某些行的数据。

虚拟专用数据库确保无论用户以何种方式访问数据(通过应用程序、报表编写工具或 SQL*Plus),都将强制实施同一强大的访问权限控制策略。这样,使用 VPD ,银行便可以确保客户只看到他们自己的帐户,电信公司可以安全地隔离客户记录,人力资源应用程序可以支持复杂的员工记录数据访问原则。

其实总结起来一句话,我们可以设置完毕之后,查询或者编辑过程中自动添加一个WHERE条件。


实验数据:

用户:SDE,我在SDE用户创建一个要素类test123,里面有一个X字段(整型)

SQL> desc sde.test123
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 OBJECTID                                  NOT NULL NUMBER(38)
 QUXIAN                                             NVARCHAR2(50)
 SHAPE                                              ST_GEOMETRY
 X                                                  NUMBER(5)

用户:DDD,普通用户

-- Create the user 
create user DDD
  identified by ""
  default tablespace SDE
  temporary tablespace TEMP
  profile DEFAULT
  password expire;
-- Grant/Revoke object privileges 
grant select, insert, update, delete on A69 to DDD;
grant select, insert, update, delete on D69 to DDD;
grant select, insert, update, delete on TEST123 to DDD;
grant select, insert, update, delete on TEST123_VW to DDD;
-- Grant/Revoke role privileges 
grant connect to DDD;
grant resource to DDD;
-- Grant/Revoke system privileges 
grant unlimited tablespace to DDD;
我使用ArcGIS的权限功能,将SDE用户的test123要素类给DDD赋予SELECT、INSERT、UPDATE、DELETE权限。

那么我使用DDD用户就可以看到sde用户下的test123的所有数据。

那么我的需求就是,我只想让DDD用户看到test123要素类中X=2的要素。


VPD包含两个要素:策略(policy),策略函数(policy Function)

编写策略函数(fn_reg)

CREATE OR REPLACE  FUNCTION fn_reg (p_owner in varchar2, p_object in varchar2) return varchar2 IS
v_region varchar2(20);
begin
v_region := sys_context('USERENV','SESSION_USER');--获得登录用户
if v_region = 'DDD' then ---如果登录用户是DDD
return  'X=2';   ---相关WHERE条件就是X=2
else
return null;
end if;
end fn_reg;

如果用户比较多,可以将这个用户放在一个表中,或者参考上面的链接,好像编写策略函数不支持else if

一般情况下通过完善策略函数来对用户的业务进行定义



策略(policy)用户管理(添加、删除、修改)对那些对象(表或视图)执行RLS(行级安全)控制。

添加策略

begin
dbms_rls.add_policy(object_schema => 'sde',object_name => 'test123',policy_name => 'pol',function_schema => 'sde',policy_function => 'fn_reg',Statement_Types =>'Select,Insert,Update,Delete,Index',Enable =>True);
end;
/


begin
dbms_rls.add_policy(object_schema => 'sde',object_name => 'a69',policy_name => 'pol_a',function_schema => 'sde',policy_function => 'fn_reg',Statement_Types =>'Select,Insert,Update,Delete,Index',Enable =>True);
end;
/

dbms_rls.add_policy(
	object_schema => 'sde', ――用户
	object_name => 'test123',――对test123要素类
	policy_name => 'pol',――策略名称
	function_schema => 'sde',――策略函数所属用户
	policy_function => 'fn_reg',――上面编写的策略函数
	Statement_Types =>'Select,Insert,Update,Delete,Index',――相关权限
	Enable =>True); ――是否启动策略

添加策略的相关属性


参    数

说    明

object_schema

包含由策略保护的表、视图或同义词的模式。如果该值是NULL,则使用调用过程的用户的模式

object_name

由策略保护的表、视图或同义词的名称

policy_name

添加到该对象的策略的名称。对于受保护的每个对象,该策略名必须唯一

function_schema

拥有策略函数的模式;如果该值为NULL,则使用调用过程的用户的模式

policy_function

函数名称,该函数为针对object_name的策略生成谓词。如果函数是程序包的一部分,则在此处必须也指定程序包名,用于限定策略函数名

statement_types

应用策略的语句类型。允许的值(以逗号分隔)可以是SELECT、INSERT、UPDATE、DELETE和INDEX的任意组合。默认情况下,除了INDEX之外的所有类型都适用

update_check

对于INSERT或UPDATE类型,该参数是可选项,它默认为FALSE。如果该参数为TRUE,则在检查SELECT或DELETE操作时,则对INSERT或UPDATE语句也要检查该策略

enable

该参数默认为TRUE,表明添加该策略时是否启用它

Static_policy

如果该参数为TRUE,该策略为任何访问该对象的人产生相同的谓词字符串,除了SYS用户或具有EXEMPT ACCESS POLICY权限的任何用户。该参数的默认值为FALSE

policy_type

如果该值不是NULL,则覆盖static_policy。可允许的值是STATIC、SHARED_STATIC、CONTEXT_SENSITIVE、SHARED_CONTEXT_SENSITIVE和DYNAMIC

Long_predicate

该参数默认为FALSE。如果它为TRUE,谓词字符串最多可为32K字节长。否则,限制为4000字节

sec_relevant_cols

实施列级别的VPD,这是Oracle 10g的新增内容。只应用于表和视图。在列表中指定受保护的列,使用逗号或空格作为分隔符。该策略只应用于指定的敏感列位于查询或DML语句中时。默认情况下,所有的列都是受保护的

sec_relevant_cols_opt

允许在列级别VPD过滤查询中的行仍然出现在结果集中,敏感列返回NULL值。该参数的默认值为NULL;如果不是默认值,则必须指定DBMS_RLS.ALL_ROWS,用于显示敏感列为NULL的所有列


注意:上面为什么还有对a69表进行添加策略,如果用户将test123注册版本了,那么会产生相关的A表。

删除策略
BEGIN
   DBMS_RLS.drop_policy (object_schema   => 'SDE',
                         object_name     => 'test123',
                         policy_name     => 'POL');
END;
/

添加之后,我们需要查看一下是否有效
1:可以使用PL/SQL进入sde用户下查看Function的fn_reg是否编译正确
2:查看V$VPD_POLICY特别注意PREDICATE是有相关的条件信息比如X=2
SQL> select object_owner,object_name,policy,predicate from V$VPD_POLICY;

OBJECT_OWNER                   OBJECT_NAME                    POLICY                         PREDICATE
------------------------------ ------------------------------ ------------------------------ -------------------------
SDE                            TEST123                        POL                            
SDE                            TEST123                        POL                            X=2
SDE                            TEST123                        POL                            X=2
SDE                            T                              POLICY_LIMITED_QUERY_T         X <= 10000
SDE                            TEST123                        POL                            
SDE                            A69                            POL_A                          X=2
SDE                            A69                            POL_A                          X=2

那么进行测试,我使用sde用户登录之后

那么我使用ddd用户登录之后

我们可以使用ddd用户只过滤x=2的要素。
那么我们在ArcMap上连接ddd用户对test123进行编辑,一开始老报ORA-28115: 策略违反检验选项。
倒腾半天,忽然开窍,我设置的策略是过滤X=2,那么我新建要素并没有设置X=2,所以报ora-28115错误。
刚好,我可以使用ddd用户连接,设置一个编辑模板,这个编辑模板设置x=2即可。


通过上面的测试,我们就可以模拟,在同一个要素类对不同的要素进行权限的设置,而且可以进行相关的读和写的操作。

也就是可以实现:
一个要素类包含北京市的所有数据,那么海淀区用户只能看到而且只能编辑海淀区的数据,朝阳区用户只能看到而且只能编辑朝阳区的数据,北京市局的用户可以查看和编辑所有区的数据。

而且即便是用户通过SQLPLUS的方法查看表也是只能查看自己区域的数据,安全性也得到了保证。

由于上面使用的都是纯Oracle知识,还不确定是否在应用在ArcSDE里面有没有相关的Bug或者问题,这个有待大家一块交流和分享。

 -------------------------------------------------------------------
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
-------------------------------------------------------------------

  相关解决方案