ORACLE R12 MOAC

  1. MOAC简介

         MOAC(Multi-Org Access Control)为多组织访问控制,是Oracle EBS R12的重要新功能。它可以实现在一个Responsibility下对多个OU(Operation Unit)进行操作,允许用户在不切换Responsibility的情况下,处理多个OU组织的事物。

UseràResponsibilityàSingle Operation Mode/Multiple Operation Unit Mode

 

     2.    MOAC

         2.1、相关配置文件

            1) MO:Security Profile(MO:安全性配置文件)

             定义业务组

            

             提交安全性请求

            

 

            2) MO:Default Operation Unit(MO:默认业务实体)

            3) MO:Operation Unit(MO:业务实体)

             

           

 

 

 

    2.2、逻辑控制 

        

 

         1) 如果MO:Security Profile没有设置,MO:Operation Unit的优先级大于MO:Default Operation Unit,将默认MO:Operation Unit设置的OU

         2)如果设置了MO:Security Profile,且当前Responsibility仅能访问单个OU,将直接默认该OU,忽略MO:Default Operation Unit

         3)如果设置了MO:Security Profile,且当前Responsibility可访问多个OU,首先将校验MO:Default Operation Unit设置的值是否在MO:Security Profile中,若存在,则默认MO:Default Operation Unit的值,否则为空。

         4) 一个配置文件又分地点、应用产品、责任、用户层,默认级别为:用户>责任>应用>地点。

 

      

     2.3、查看可用MOAC模块

           MOAC需要应用程序做支持才能启用,所以在启用MOAC之前,需要清楚哪些应 用程序支持MOAC特性。

           SELECT fmp.application_short_name FROM fnd_mo_product_init fmp WHERE fmp.status='Y' ; 

           也可对应用改程序注册 MOAC 支持,或取消 MOAC 支持

            注册:fnd_mo_product_init_pkg.register_application

            取消:fnd_mo_product_init_pkg.remove_application

 

   3.    VPD

     MOAC是通过Oracle数据库的VPD(Virtual Private Database)技术来实现的,VPD技术提供了数据库对象(表、同义词、视图)

      行级别访问的控制,使用VPD技术可以有效的限制用户获取数据的范围。

        

         3.1 VPD工作方法

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

           例如:实现需求只允许某个用户查询管理员工表的数据,则VPD自动会将查询语句SELECT * FROM fnd_user添加查询条件

         SELECT * FROM fnd_user where user_name = ‘HAND_CW’,其中‘where user_name=’HAND_CW’为VPD安全性策略函数返回的字符串。

 

 

       3.2 VPD内容

            1) policy_function

                策略函数是作用在对象(表、视图、同义词)上,根据应用程序上下文返回一个特定的谓词,即自动在查询表、视图时,加上返回的where条件。可使用dbms_rls.add_policy将对象与策略函数绑定。

                查看R12 MOAC使用的策略函数

                 SELECT DISTINCT  dp.policy_name,

                                 dp.package || '.' || dp.function,

                                 dp.policy_type

  FROM dba_policies dp

 WHERE dp.policy_name = 'ORG_SEC';

 

            2)policy_type

               策略函数创建并返回的字符串具有很强的动态性,为了保证结果,提高性能,R12有一下几种策略类型:

                context_sensitive,shared_context_sensitive,shared_static、static

               设置策略函数的策略类型:

                Dbms_rls.add_policy(policy_type => dbms_fls.shared_context_sensitive);

 

     3.3 创建客户化表的VPD屏蔽

           表:CUX_FREIGHT_INFO_HEADERS_ALL,同义词:CUX_FREIGHT_INFO_HEADERS

           为同义词CUX_FREIGHT_INFO_HEADERS添加VPD屏蔽

           BEGIN

                    dbms_rls.add_policy(object_schema   => 'CUX', --数据表(或视图)所在的Schema名称

                                                   object_name     => 'CUX_FREIGHT_INFO_HEADERS ', --数据表(或视图)的名称

                                                   policy_name     => 'ORG_SEC ', --POLICY的名称,主要用于将来对Policy的管理

                                                   function_schema => 'CUX', --返回Where子句的函数所在Schema名称

                                                   policy_function => 'MO_GLOBAL.ORG_SECURITY', --返回Where子句的函数名称

                                                   policy_type     => dbms_rls.shared_context_sensitive);

           END;

            创建该VPD屏蔽后,select * from CUX_FREIGHT_INFO_HEADERS没有返回结果集,

            select * from CUX_FREIGHT_INFO_HEADERS_ALL可返回表的所有结果集

 

       3.4 删除VPD

          BEGIN

                dbms_rls.drop_policy(object_name => 'CUX_FREIGHT_INFO_HEADERS',

                                                 policy_name => 'ORG_SEC');

           END;

 

 

        3.5 查看VPD

                SELECT *

                 FROM user_policies t

                  WHERE 1 = 1

                 AND t.object_name = 'CUX_FREIGHT_INFO_HEADERS';

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    4.    支持MOACFORM开发

              在R12版本中,OU的控制采购了MOAC的方式,是用户的操作得到了改善,如果客户化的form能够支持MOAC的功能,需要在界面上提供当前用户可选择的OU字段供用户选择。

         4.1 定义FORM参数

               mo_default_org_id、mo_default_ou_name、mo_ou_count

 

         4.2 PRE_FORM

               mo_global.init('CUX'); --根据应用去设置form为单OU或者多OU模式

                mo_utils.get_default_ou(l_default_org_id, l_default_ou_name, l_ou_count);  --得到默认的OU

              

               copy(l_default_org_id,'PARAMETER.mo_default_org_id'); 

                copy(l_default_ou_name,'PARAMETER.mo_default_ou_name');

                copy(l_ou_count,'PARAMETER.mo_ou_count');

               IF nvl(l_ou_count, 0) <= 0 THEN--判断是否找到了OU,如果没有找到,则报错

                    fnd_message.debug('错误001:没有找到相应的OU,请联系系统管理员或开发人员!');

                    RAISE form_trigger_failure;

               END IF;

               IF l_default_org_id IS NOT NULL THEN

                   mo_global.set_policy_context('S', l_default_org_id);

           END IF;

 

      4.3 WHEN_CREATE_RECORD

          在带有OU的BLOCK的when-create_record中添加如下代码:

          l_org_id_name     := name_in('System.Trigger_Block') || '.ORG_ID';

          l_block_item_name := name_in('System.Trigger_Block') || '.OU_NAME';

          IF :parameter.mo_default_org_id IS NOT NULL

              AND name_in(l_org_id_name) IS NULL THEN

                   copy(:parameter.mo_default_org_id,

                   name_in('System.Trigger_Block') || '.ORG_ID');

                  copy(:parameter.mo_default_ou_name,

                  name_in('System.Trigger_Block') || '.OU_NAME');

 

                 set_item_property(l_block_item_name,

                                            item_is_valid,

                                               property_true);

              END IF;

           

     

 

 

 

 

 

       

备注:mo_utils.get_default_ou(l_default_org_id, l_default_ou_name, l_ou_count);

函数代码如下:

      PROCEDURE get_default_ou(p_default_org_id  OUT NOCOPY NUMBER,

                         p_default_ou_name OUT NOCOPY VARCHAR2,

                         p_ou_count        OUT NOCOPY NUMBER) IS

  l_prof_org_id     hr_operating_units.organization_id%TYPE;

  l_default_org_id  hr_operating_units.organization_id%TYPE;

  l_default_ou_name hr_operating_units.name%TYPE;

BEGIN

  p_ou_count := mo_global.get_ou_count;

  IF (get_multi_org_flag <> 'Y' OR p_ou_count = 0) THEN

    RETURN;

  END IF;

  IF (p_ou_count = 1) THEN

    BEGIN

      SELECT mg.organization_id,

             mg.organization_name

        INTO l_default_org_id,

             l_default_ou_name

        FROM mo_glob_org_access_tmp mg;

    EXCEPTION

      WHEN OTHERS THEN

        l_default_org_id  := NULL;

        l_default_ou_name := NULL;

    END;

  ELSE

    l_prof_org_id := fnd_profile.value('DEFAULT_ORG_ID');

    IF (mo_global.check_access(l_prof_org_id) = 'Y') THEN

      l_default_org_id  := l_prof_org_id;

      l_default_ou_name := mo_global.get_ou_name(l_default_org_id);

    ELSE

      l_default_org_id  := NULL;

      l_default_ou_name := NULL;

    END IF;

  END IF;

  p_default_org_id  := l_default_org_id;

  p_default_ou_name := l_default_ou_name;

EXCEPTION

  WHEN OTHERS THEN

    generic_error('MO_UTILS.Get_Default_OU',

                  SQLCODE,

                  SQLERRM);

END get_default_ou;

 

 

 

posted @ 2016-08-10 13:37  旺仔丶小馒头  阅读(1057)  评论(0编辑  收藏  举报