Oracle R12 MOAC入门探索

更新时间:2023-10-05 19:15:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

EBS R12 MOAC原理探索

Author: Creation Date: Last Updated: Document Ref: Version:

Approvals:

王浩鑫(hansen.wang) November 21, 2008 November 29, 2008

DRAFT 1A

Copy Number _____

Document Control

Change Record

Reviewers

Distribution

3

Date Author Version Change Reference 21-May-08 Draft 1a No Previous Document

Name Position

Copy No. Name Location 1 Library Master Project Library 2 Project Manager 3 4

Note To Holders:

If you receive an electronic copy of this document and print it out, please write your name on the equivalent of the cover page, for document control purposes. If you receive a hard copy of this document, please write your name on the front cover, for document control purposes.

Company Confidential - For internal use only Document Control ii

Contents

Document Control .................................................................................................................. ii 1.

1.1.

1.2. 2.

2.1. 2.2. 2.3. 2.4. 3.

3.1. 3.2. 3.3. 4.

4.1. 4.2. 5.

MOAC介绍和配置 .................................................................................................... 2

MOAC背景 ......................................................................................................... 2 多OU使用配置 .................................................................................................... 5 MOAC内部实现 ...................................................................................................... 10

过程概述 ............................................................................................................ 10 po_glob_org_access_tmp表的分析 ................................................................ 11 MO_GLOBAL包的分析 .......................................................................................... 16 VPD介绍和使用实例 ........................................................................................ 21 技术实施要点 ........................................................................................................... 29

环境初始化 ........................................................................................................ 29 并发请求 ............................................................................................................ 31 Form开发 .......................................................................................................... 31 附录 ........................................................................................................................... 32

VPD实例源码 .................................................................................................... 32 参考文档 ............................................................................................................ 35 WhOpen and Closed Issues for this Deliverable ................................................ 36 Open Issues ..................................................................................................................... 36 Closed Issues .................................................................................................................. 36

Company Confidential - For internal use only Document Control iii

1. MOAC介绍和配置

1.1. MOAC背景

1.1.1.

概述

MOAC(Multi-Org Access Control)中文简称为多组织访问控制,是ebs R12的重要新功能,其目标是:使用安全性控制文件实现在一个职责类对多个OU进行操作。这句概括可能有些模糊,但一开始说多了会更模糊,本文的重点在于整理MOAC的内部流程和实现过程。 1.1.2.

业务需求

一个老外的Blog例子,个人觉得蛮不错 Business Reason for this change

-----------------------------------------

Four years ago, I was tasked to design a Payables Invoice scanning process that had

following requirements:

1. My client had 100s of legal entities and organization units.

2. They wanted to receive all paper payables invoices at a central location

n.Effectively, they would have a single Address where invoices for all the Legal entities /Operating Units were received. 3. All the invoices would be scanned at that central location.

4. The scanned images were then placed in a queue that were then

keyed(typed) into the system by Bangalore Team(their shared servicecentre) Here lies the issue:-

Scanned Invoices had ?o be first sorted per operating unit. Why? Because, there was different \The poor clerk had to switch responsibility depending upon which operating unit the invoice was being entered against. Also it will never be possible to force all your suppliers to post their invoices to XML Gateway. Hence clerk had to ensure that each paper invoice is coded/entered into the right organization/operating unit. 1.1.3.

r12解决方案

同样来自另一个老外的Blog例子,其中涉及到了MOAC和Multi-Org preferences You have around 20 OU’s divided into three major Region (North America, Europe and APAC). Lets say within APAC region you are responsible for all 7 OU’s within Region. In this situation, a system administrator may create a security profile that has 7 operating units assigned to it and assign it to your responsibility. But, you may only deal with five of the operating units on a daily basis and do not want work space cluttered with extraneous operating units. You could set up Multi-Org

preferences to restrict the list of operating units; you have complete control over this and can change it at anytime. In addition, you can specify a default operating unit.

Company Confidential - For internal use only MOAC介绍和配置 2 of 38

1.1.4. 一些小悬念 1、 订单不见了

在上面的例子中可得出,PO_HEADERS和PO_HEADERS_ALL都是建立的PO.PO_HEADERS_ALL上的同义词(不再是视图),但是:

有一条记录,而

没有记录,基于同样基表的同义词,为什么? 2、 一次查询怎么能将两个OU的发票查询出来了

Company Confidential - For internal use only MOAC介绍和配置 3 of 38

而同样的条件,下面的结果为什么又只有一个呢?

3、 并发请求参数,两个相同的请求,为什么值集一个没有值呢

而另一个值集又有值呢?

Company Confidential - For internal use only MOAC介绍和配置 4 of 38

1.2. 多OU使用配置

这些都是MOAC的魔力,不过没有关系,下面的讨论可能会揭开其中的奥秘。

1.2.1.

概述

在MOAC中使用的是安全性配置文件来实现对OU访问的控制的,我们首先定义好安全性配置文件,然后将该文件使用预制文件的形式定义在职责或者用户上,让这个用户可以访问该安全性配置文件所分配的安全OU,但由于业务上的需要,不是所有拥有该安全性配置文件的用户都想访问该安全性配置文件分配的全部OU,在R12中用户可以在职责中使用“用户首选项”来设置自己的操作OU,本节实现MOAC的设置。 1.2.2.

安全性控制文件介绍

在这里引用一段实施文档对安全性配置文件的介绍:

安全性配置文件控制对业务组中的组织、职位、员工和申请人记录的访问,系统管理员可以使用安全性配置文件来限制用户的责任。具体限制内容如下: ?

按人员类型应用限制;(您可以选择将您设置的安全性限制应用于员工、申请人、联系人或者他们的任何组合。) ?

按组织限制访问;(您可以查看所有组织(无安全性);按组织层次结构和(或)组织列表保护组织;按单个业务实体保护组织;按业务实体和库存组织的组合保护组织。) ?

按职位限制访问;(您可以在“职位安全性”标签区域中,查看所有职位(无安全性);或者撤消选定“查看所有职位”复选框,然后选择职位层次结构和顶层职位。如果您要允许访问该职位,请选定“包括顶层职位”复选框。)

Company Confidential - For internal use only MOAC介绍和配置 5 of 38

? 按工资单限制访问;(您可以选定“查看所有工资单”复选框,允许访问所有工资单;或者通过撤消选定“查看所有工资单”复选框,然后撤消选定“包括”复选框,排除不可访问工资单,这样可以允许访问许多工资单;您可以通过撤消选定“查看所有工资单”复选框,然后选定“包括”复选框,选择要包括的工资单,这样可以允许访问少量工资单。)

? 按主管限制访问;(您可以在“基于用户的安全性”标签区域中,选定“按主管限制”复选框,然后在“最大结构层”框中输入您要允许主管查看的访问层数,或者将此字段留空,以便允许访问所有层。)

? 允许访问授权用户记录(仅限于 SSHR);您可以选定“允许授权用户”复选框,可以在其他用户使用自助应用产品授权自助用户进行访问的情形下,允许使用该配置文件的自助用户访问其他自助用户的记录。

1.2.3. 设置安全性控制文件

路径:HRMS->安全性->配置文件

在MOAC中主要是使用按组织限制访问,在按组织访问设置的过程中该处定义的OU既是多OU的根本。在一些职责下还有组织访问控制,这两者的关系不在本文的理解范围内。

在该文档中使用的安全性控制文件如下:

名称 Hansen 安全性文件 Company Confidential - For internal use only MOAC介绍和配置 6 of 38

按当前性类型 按组织层次结构和(或) 组织列表列出的安全组织 包括四个OU OU_上海大道,OU_苏州大道,OU_Kiddy公司,OU_HAND 图中红色字体是整个MOAC中OU来源的核心,它体现在mo_global. populate_orgs 中,在后面的章节将会详细理解其含义。 1.2.4.

运行请求

路径:HRMS->[查看]-[请求](Alt+V+R)

在定义好安全性控制文件后需要在HRMS职责下运行请求“维护安全性清单请求”,否则在打开业务实体首选项页面时会出现如下错误:APP-FND-02901: 您没有访问任何业务实体的权限。请检查您的配置文件选项“MO:安全性配置文件”是否包括任何业务实体,或是否设置了配置文件选项“MO:业务实体”。 1.2.5.

设置预制文件

路径:系统管理员->profile->系统

其中“MO:业务实体”和“MO:安全性配置文件”两者的设置和关系在 mo_global. set_org_access的注释中有体现:

If the application being initialized can handle more than one Operating Unit, access will be allowed for the Operating Units encompassed by the security profile (if specified) and the value of the Operating Unit parameter will be ignored,

provided access is enabled for the application calling this api. If no security profile is specified, access will be initialized for the Operating Unit only. If both are unspecified an exception will be raised.

因此两者的关系可以概括为:当没有设置“MO:安全性配置文件”的值时,必须设置“MO:业务实体”的值,设置了“MO:安全性配置文件”值后自动覆盖

“MO:业务实体”的值,并且此时的“MO:默认业务实体”的值即为用户或职责的默认OU,并且一般是将安全性控制文件挂在用户和职责层。

Company Confidential - For internal use only MOAC介绍和配置 7 of 38

1.2.6. 添加功能

在当前职责检查是否包含功能“用户首选项” (FNDMOPREFS),如果没有包含,则在相应的菜单中添加该功能,但该功能仅在支持多MOAC的应用下使用,查看哪些应用支持该职责可使语句

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

路径:系统管理员->应用->菜单

查找出需要添加该功能的菜单,将该功能添加到相应模块即可。 1.2.7.

定制多OU

当我们设置了多OU预制文件后,默认情况下我们可以操做该列表的所有OU数据,但很多情况下我们只是需要操作该列表下的部门OU数据,在该情况下我们可以使用“用户首选项”功能来实现。

路径:%应付%->设置->选项->用户业务实体首选项

如果需要设置多OU,只须选中相应的复选框,然后点击设置为首选即可。 在未设置安全性配置文件前的界面如下:

Company Confidential - For internal use only MOAC介绍和配置 8 of 38

1.2.8.

总结

在该节中主要介绍了MOAC的设置,但作为技术人员,了解设置远远是不够的,下一章就MOAC的内部实现展开讨论,这也是该文档讨论的重点。

Company Confidential - For internal use only MOAC介绍和配置 9 of 38

2. MOAC内部实现

2.1. 过程概述

2.1.1.

MOAC总体流程概述

在r12中使用安全性控制文件实现在一个职责类对多个职责进行操作,11i中基于各个模块基表的多OU视图已经被apps下这些模块基表的同义词取代,也即是在R12中PO_Headers_all不再是定义在PO.PO_HEADERS_ALL上的视图,而是其同义词。但同样是基于PO.PO_HEADERS_ALL上的同义词,为什么apps下PO_HEADERS_ALL能查询出值,而PO_HEADERS却不能查询出值呢?这里就涉及到oracle数据库的一个重要概念virtual private database (VPD),正是因为 PO_HEADERS使用了VPD所以我们在没有初始化的情况下不能获取结果,多OU的技术正是使用了VPD才使得我们在操作数据的时候没有任何障碍并且安全。

我们可以通过查询获取PO_HEADERS的建立是添加了MO_GLOBAL. ORG_SECURITY安全性检测方法,

该方法正是对OU安全性控制的方法,在该方法对多OU情况下org_id判断的过程中,查询了一张非常重要的表po_glob_org_access_tmp,而对单OU访问模式下是判断当前org_id和context的org_id是否相同。po_glob_org_access_tmp表是一张session临时表,它存放着当前的用户访问中有权限访问的所有OU信息。在多OU条件下对

PO_HEADERS的查询或其他DML,系统会自动添加MO_GLOBAL. ORG_SECURITY的验证,真正的查询结果是我们所写的SQL语句和该验证的共同结果,这样就实现了一个职责多OU下对应的所有数据。

通过上面的概述,我们可以提取出四个关键词VPD,ORG_SECURITY,

MO_GLOBAL ,CONTEXT,PO_GLOB_ORG_ACCESS_TMP,整个MOAC的实现过程呢可以看作是对这几个关键词的串联理解,首先是向PO_GLOB_ORG_ACCESS_TMP插入当前能操作的ORG_ID,然后是通过MO_GLOBAL的一系列方法设置CONTEXT的值(包括访问模式和当前org_id),最后是使用VPD向相对应的同义词上添加ORG_SECURITY验证,当访问模式为Single-org时,对当前的org_id使用CONTEXT值进行验证,当访问模式为Mutil-org,对当前的org_id使用表 po_glob_org_access_tmp验证,通过验证的数据即为安全操作数据。重点会涉及到VPD的实现,以及对po_glob_org_access_tmp表的分析和对MO_GLOBAL分析理解。

Company Confidential - For internal use only MOAC内部实现 10 of 38

2.2. po_glob_org_access_tmp表的分析

2.2.1.

po_glob_org_access_tmp介绍:

在多OU的实现中,VPD都是通过判断基表的org_id是否在po_glob_org_access_tmp表中存在,如果存在则为安全数据。该表是一张session临时表,其中的值只能通过使用mo_globlal和mo_utils包的方法进行操作。该表中的值是在

mo_global.populate_orgs中进行插值,mo_global.delete_orgs进行删除操作的,在populate_orgs过程中,有这样一条bug修改记录:

Bug fix 4511279:Need to populate temp table even when access mode is \该注释表明,该表不仅在多OU模式下需要插值,并且在单OU模式下也需要进行插值操作,当然单OU下该表有且仅有一条记录。

mo_global.populate_orgs方法包含四个参数:

PROCEDURE populate_orgs (

p_org_id_char VARCHAR2, p_sp_id_char VARCHAR2,

p_current_org_id OUT NOCOPY VARCHAR2, p_view_all_org OUT NOCOPY VARCHAR2); p_org_id_char 当前的OU “MO: Operating Unit” p_sp_id_char 当前的安全性配置文件“MO: Security Profile” p_current_org_id 当前的org_id p_view_all_org 是否查看所有的OU标示 p_org_id_char和p_sp_id_char 的值分别对应“MO: Operating Unit”和“MO: Security Profile”预制文件的值,在调用populate_orgs过程前,有一个逻辑判断

IF l_security_profile_id IS NOT NULL THEN l_org_id := null; END IF; 该逻辑的含义即为,如果设置了“MO: Security Profile”预制文件,那么“MO:

Operating Unit”的值会自动被覆盖,也即是参数p_org_id_char和p_sp_id_char中一定是有一个为空的。当p_org_id_char不为空时,肯定是单OU模式。 2.2.2.

table记录的生成逻辑:

在多OU的设置开始我们会定义一个安全性配置文件和设置当前的安全性配置文件,该配置文件中定义了一系列组织访问的权限控制,我们可以使用下面语句查询出当前使用的安全性控制文件

SELECT security_profile_name

, business_group_id

,view_all_organizations_flag FROM per_security_profiles WHERE security_profile_id =

to_number(fnd_profile.VALUE('XLA_MO_SECURITY_PROFILE_LEVEL'));

可以通过以下语句获取当前安全性配置文件和当前用户在当前职责下可访问的OU SELECT per.organization_id organization_id

, hr.NAME name FROM per_organization_list per

, hr_operating_units hr

Company Confidential - For internal use only MOAC内部实现 11 of 38

WHERE per.security_profile_id =

to_number(fnd_profile.VALUE('XLA_MO_SECURITY_PROFILE_LEVEL'))

AND hr.organization_id = per.organization_id AND hr.usable_flag is null;

当一切条件设置完成后,下面进入mo_global.populate_orgs进行插值操作,伪代码如下:

1 IF 安全性配置文件预制文件不为空 THEN

获取安全性预制文件的信息,文件名,业务组,查看所有标示 SELECT security_profile_name

, business_group_id,

view_all_organizations_flag

INTO l_sp_name

,l_bg_id

,p_view_all_org

FROM per_security_profiles

WHERE security_profile_id = to_number(p_sp_id_char);

1.1 IF 安全性配置文件没有设置组织控制 THEN

1.1.1 IF 安全性预制文件指定了业务组 THEN

获取该业务组下对应的所有org_id

SELECT hr.organization_id organization_id

,hr.name NAME

INTO t_org_id

,t_ou_name;

FROM hr_operating_units hr

WHERE hr.business_group_id = l_bg_id AND hr.usable_flag is null;

1.1.2 ELSE 安全性预制文件没有定业务组 THEN

获取系统所有的org_id

SELECT hr.organization_id organization_id

,hr.NAME NAME

INTO t_org_id

,t_ou_name;

FROM hr_operating_units hr

WHERE hr.usable_flag IS NULL; END IF;

1.2 ELSE 安全性设置文件中指定了OU范围 THEN

获取安全性配置文件对应的所有Org_id

SELECT per.organization_id organization_id

,hr.NAME NAME

INTO t_org_id

,t_ou_name;

FROM per_organization_list per, hr_operating_units hr WHERE per.security_profile_id = to_number(p_sp_id_char) AND hr.organization_id = per.organization_id AND hr.usable_flag IS NULL; END IF;

Company Confidential - For internal use only

MOAC内部实现 12 of 38

2 ELSE 没有设置安全性配置文件 THEN

2.1 IF 当前OU配置文件有值 THEN

获取当前的org_id

SELECT hr.organization_id organization_id

, hr.name NAME

INTO t_org_id

,t_ou_name;

FROM hr_operating_units hr

WHERE hr.organization_id = to_number(p_org_id_char) AND hr.usable_flag is null; END IF; END IF;

3 IF 如果t_org_id的长度大于1,即为当前用户有多OU访问权限 THEN 获取用户首选项的org_id的值

SELECT organization_id

FROM fnd_mo_sp_preferences INTO t_pref_org_id

WHERE user_id = fnd_global.user_id AND resp_id = fnd_global.resp_id;

3.1 IF 用户首选项的t_pref_org_id表长度不为空 then

3.1.1 IF (g_sync <> 'N') THEN sync_ind := 'Y'; END IF;

判断用户首选项的值和当前所有的OU值是否相同,如果相同 则将值放入放入t_common_org信息表中;

将fnd_mo_sp_preferences用户首选项表中没有访问权限的OU信息删除 END IF;

3.2 IF 要求同步 (sync_ind = 'Y') AND 首选项中有值 THEN

FOR i IN t_common_org_id.FIRST .. t_common_org_id.LAST LOOP INSERT

INTO mo_glob_org_access_tmp (organization_id

, organization_name)

VALUES (t_common_org_id(i) , t_common_ou_name(i)); END LOOP;

3.3 ELSIF 如果没有要求同步,则mo_glob_org_access_tmp表中

的值为当前能选择的所有值 then

FOR i IN t_org_id.FIRST .. t_org_id.LAST LOOP INSERT

INTO mo_glob_org_access_tmp (organization_id

, organization_name) VALUES (t_org_id(i) , t_ou_name(i)); END LOOP; END IF;

g_ou_count := t_org_id.COUNT;

END IF;

Company Confidential - For internal use only MOAC内部实现 13 of 38

4 IF p_sp_id_char IS NOT NULL AND l_bg_id IS NOT NULL AND 访问所有OU

标示 = 'Y' THEN

设置访问所有OU的标志 访问所有OU标示 := 'N'; END IF;

设置全局访问模式

5 IF 访问所有OU标示 = 'Y' THEN

访问模式:='A'; --ALL

6 ELSIF g_ou_count = 1 THEN

访问模式:='S'; --Single

7 ELSIF g_ou_count > 1 THEN

访问模式:='M'; --Mutil END IF;

8 IF ou表的长度=1 THEN

设置默认org_id为当前唯一的org_id

END IF; 2.2.3.

view_all_organizations_flag字段

在上段的分析过程中,有一个概念是 访问所有OU标示(p_view_all_org)它是对应的安全性配置文件表的view_all_organizations_flag字段,当界面上的安全性类型为查看所有组织(无安全性)时,此值对应的结果为“Y”,否则为“N”。

2.2.4.

fnd_mo_sp_preferences值逻辑

在上面的分析过程中涉及到一个fnd_mo_sp_preferences表,在多OU操作的情况下,向po_glob_org_access_tmp表插值时需要检查设置fnd_mo_sp_preferences的值,只有是该表和查询出的结果值都满足才插入到po_glob_org_access_tmp,他的设置是在1.2.6中介绍的。

Company Confidential - For internal use only MOAC内部实现 14 of 38

按照1.2.6的界面查询值是只有一个默认值的结果的,但当我们将四个组织都设置为首选时如图

该查询才会有值

SELECT msp.user_id ,msp.resp_id

,msp.security_profile_id ,msp.organization_id

FROM fnd_mo_sp_preferences msp; 结果如下:

但security_profile_id=0的记录是怎么产生的呢? 通过查询

SELECT security_profile_name ,business_group_id ,view_all_organizations_flag FROM per_security_profiles WHERE security_profile_id = 0

可以得知该值时安全性配置文件Setup Business Group产生的,该文件时系统默认的安全性配置文件。其内部机制有待研究……

2.2.5. 总结

在该节中对po_glob_org_access_tmp的值生成分析是对应的多OU模式下的验证值,但在进行验证的过程中有段代码是:

EXISTS (SELECT 1

FROM mo_glob_org_access_tmp oa

Company Confidential - For internal use only MOAC内部实现 15 of 38

WHERE oa.organization_id = org_id)

但对应单OU模式下的验证语句

org_id = sys_context(''multi_org2'',''current_org_id'') sys_context(''multi_org2'',''current_org_id'')的值是怎么获取的呢?在下面的2.3节将会对其进行讨论,同时我们经常所说的访问模式是指什么,它的生成逻辑和控制方式又是怎样的呢?这也将会在2.3节进行讨论。

2.3. MO_GLOBAL包的分析

2.3.1.

概述

在2.1的过程概述中提到的流程概述中,整个流程的核心都是在MO_GLOBAL中完成的,包括对po_glob_org_access_tmp记录的插入,访问模式的设置,默认OU的获取,对VPD的支持(提供ORG_SECURITY验证方法),在该节将会对这些概念进行理解,在此基础上对MO_global pakage进行分析。 2.3.2.

访问模式(Access Mode)

在MOAC的实现中,采用Access Mode来控制当前是Mutil org还是Single org。常见的有三种模式:

S M A X Single Mutil All 单OU模式 多OU模式 预留将来使用 阻止从同义词返回任何数据 值的产生逻辑:

访问模式值生成逻辑是在mo_global.set_org_access中实现的,它有三个参数 p_org_id_char The operating unit ID for the current session p_sp_id_char The security profile id for the current session p_appl_short_name Application owner for the current module or session PROCEDURE set_org_access(p_org_id_char VARCHAR2, p_sp_id_char VARCHAR2, p_appl_short_name VARCHAR2); 该方法中调用了populate_orgs和set_org_context方法,其中populate_orgs的作用和逻辑在2.2中已经阐述,但该方法中需要使用到populate_orgs中设置的一些全局变量和一些返回值。set_org_context方法主要是对Access Mode进行付值。

该方法的伪代码:

1 IF 当前的数据库实例不是multi-org数据库实例 THEN

RETURN; END IF;

2 IF \预制文件和\预制文件都没有设置 THEN

抛出异常

3 ELSIF 应用简称为空 THEN

抛出异常 END IF;

4 获取当前应用是否支持Mutil-org的标示

Company Confidential - For internal use only MOAC内部实现 16 of 38

SELECT nvl(mpi.status, 'N') INTO l_access_ctrl_enabled

FROM fnd_mo_product_init mpi

WHERE mpi.application_short_name = p_appl_short_name; 5 删除表po_glob_org_access_tmp中的数据 delete_orgs;

6 IF 支持Mutil-org THEN

6.1 IF 当前环境设置了安全性配置文件 THEN

\值被覆盖; END IF;

6.2 populate_orgs(l_org_id,

l_security_profile_id, l_current_org_id, l_view_all_orgs);

判断当前是否有多个OU 6.3 IF OU个数为0 THEN

RAISE NO_ORG_ACCESS_FOUND;

6.4 ELSIF OU个数为1 THEN

设置Access MODE为'S',且org_id为当前唯一的org_id set_policy_context('S', l_current_org_id); 6.5 ELSE OU个数>1 THEN

6.5.1 IF 访问所有OU标示= 'Y' THEN

设置Access MODE为'A' set_policy_context('A',''); 6.5.2 ELSE

设置Access MODE为'M' set_policy_context('M',''); END IF;

END IF;

7 ELSE 当前应用不支持多OU

7.1 IF 已经设置了\预制文件 THEN

7.1.1 populate_orgs(l_org_id,

null, l_current_org_id, l_view_all_orgs);

7.2 设置Access MODE为'S',且org_id为预制文件的Org_id

set_policy_context('S',l_org_id);

END IF; END IF; 8 commit;

在该方法中共产生了三种访问模式,但这些访问模式是怎样付值和被VPD所使用的呢?这就需要另一个知识点 Application context…… 2.3.3.

应用程序上下文(Application context)的理解

介绍:应用程序上下文,其实就是个环境变量,在SESSION的生命周期内有效。oracle官方的资料如下:

Application context can be useful for the following purposes:

1.Enforcing fine-grained access control

2.Preserving user identity across multitier environments

3.Serving as a secure data cache for attributes needed by an application for fine-grained auditing or for use in PL/SQL conditional statements or loops This cache saves the repeated overhead of querying the database each time such attributes are needed.

Company Confidential - For internal use only

MOAC内部实现 17 of 38

4.Serving as a holding area for attribute-value pairs that an application can define, modify, and access

Three types of application context are defined, differentiated by where the context data is stored and by how updates can be done:

1.Secure session-based application contexts, for which data is stored in the database user session (UGA) in a namespace specified by an SQL command (CREATE CONTEXT).

2.The client session-based application context, using only the

CLIENTCONTEXT namespace, updatable by any OCI client or by the existing DBMS_SESSION API for application context. No privilege or package security check is done.

3.Nonsession-based (global) application contexts, for which data is stored in the shared area (SGA).

创建语法:

CREATE CONTEXT cux_context_name USING apps.cux_vpd_global cux_context_name 是应用程序上下文的名称(namespace)

apps.cux_vpd_global是可以对这个namespace进行变量的创建和删除的package

相关DB对象:

dba_context,sys.context$ c, sys.obj$

在MOAC中的使用:

在MOAC中我们是用的是第二种类型的client session-based应用上下文 付值:使用DBMS_SESSION. set_context方法操作

procedure set_context(namespace varchar2,

attribute varchar2, value varchar2, username varchar2 default null, client_id varchar2 default null); namespace Name of the namespace to use for the application context attribute Name of the attribute to be set value Value to be set Eg:dbms_session.set_context('multi_org', 'access_mode', p_access_mode);

取值:使用sys_context(namespace, attribute)

Eg:sys_context('multi_org2','current_org_id')

为了获取在MO_GLOBAL中使用的context,可以根据定义使用语句:

SELECT *

FROM dba_context dc

WHERE package = 'MO_GLOBAL'

在MO_GLOBAL中对这两个值的使用在mo_global.set_policy_context方法中 multi_org的access_mode属性存放的是当前的访问模式. multi_org2的current_org_id属性存放的是当前的org_id. 两参数的信息: multi_org access_mode multi_org2 current_org_id S=Single, M=Multiple, A=All, X=None

Operating unit org id, only applicable if access mode is Single Company Confidential - For internal use only MOAC内部实现 18 of 38

其中access_mode和current_org_id的值在mo_global.set_org_access方法中已经获取到了,但access_mode=’A’或’M’时current_org_id为空,否则current_org_id值为当前的唯一Org_id;经过上面一系列的讨论,可以得到mo_global.set_policy_context的付值是多OU产生阶段的最后一个步骤,接下来我们解析一下这个逻辑,

mo_global.set_policy_context伪代码:

1 IF 当前的access_mode和org_id未发生改变 THEN

返回(状态没有变,不需要设置);

2 ELSIF 参数access_mode='S' THEN

2.1 IF 当前的access_mode为空 or 当前的access_mode<>'S' THEN

-设置access_mode Context的值

dbms_session.set_context('multi_org', 'access_mode', p_access_mode); g_access_mode := p_access_mode; END IF;

2.2 IF (当前的org_id为空 or 当前的org_id<>参数org_id or

上下文中的org_id <> 参数org_id -- Bug4916086 OR 上下文中的org_id为空) THEN 设置current_org_id context的值

dbms_session.set_context('multi_org2', 'current_org_id', p_org_id); g_current_org_id := p_org_id; END IF;

3 ELSIF (参数access_mode = 'M') THEN

3.1 IF 当前的access_mode为空 or 当前的access_mode<>'M' THEN

--设置access_mode Context的值

dbms_session.set_context('multi_org', 'access_mode', p_access_mode); g_access_mode := p_access_mode; END IF;

3.2 IF (当前的org_id不为空 ) THEN

将current_org_id Context的值清空

dbms_session.set_context('multi_org2', 'current_org_id', ''); g_current_org_id := NULL; END IF;

4 ELSIF (参数access_mode = 'A') and g_init_access_mode = 'A' THEN 4.1 IF 当前的access_mode为空 or 当前的access_mode<>'A' THEN

-设置access_mode Context的值

dbms_session.set_context('multi_org', 'access_mode', p_access_mode); g_access_mode := p_access_mode; END IF;

4.2 IF (当前的org_id不为空 ) THEN

将current_org_id Context的值清空

dbms_session.set_context('multi_org2', 'current_org_id', ''); g_current_org_id := NULL; END IF;

5 ELSIF (参数access_mode in ('X','B')) THEN 5.2 IF 上下文中的org_id is not null then

将current_org_id Context的值清空

dbms_session.set_context('multi_org2', 'current_org_id', ''); end if;

设置access_mode CONTEXT的值

dbms_session.set_context('multi_org', 'access_mode', p_access_mode); g_current_org_id := NULL;

g_access_mode := p_access_mode;

Company Confidential - For internal use only MOAC内部实现 19 of 38

6 ELSIF (参数access_mode为空) THEN

6.1 IF (g_access_mode IS NOT NULL) THEN

设置access_mode CONTEXT的值

dbms_session.set_context('multi_org', 'access_mode', p_access_mode); g_access_mode := p_access_mode; END IF;

6.2 IF (当前org_id不为空) THEN

将current_org_id Context的值清空

dbms_session.set_context('multi_org2', 'current_org_id', ''); g_current_org_id := NULL; END IF;

END IF;

7 获取当前用户和职责的信息,用以验证MO设置是否完成 g_old_user_id:=sys_context('FND','USER_ID'); g_old_resp_id:=sys_context('FND','RESP_ID'); 2.3.4.

mo_global 流程理解

到了这一步,我们已经分别将值放到了po_glob_org_access_tmp和context中,但是系统是怎么实现这个功能的呢?它的出发点在什么地方呢,在oracle ETRM上查询引用在这个包的数据库对象,有706个,真正使用mo_global.unit的入口包是哪个,我不能确定,但我们只要理解它从mo_global.unit这个口进入后的流程也就能理解了MOAC的Org_id安全机制了。 mo_global主要流程图

该流程图展示了系统设置Organization Security Policy的整个流程,通过该流程,系统将MO的Org_id放入session 临时表po_glob_org_access_tmp表中,将Access mode值存储到Application context multi_org的access_mode attribute中,将当前默认的org_id存入到Application context multi_org2的current_org_idattribute中,我们可以在程序中使用

Company Confidential - For internal use only MOAC内部实现 20 of 38

sys_context('multi_org2','current_org_id') 获取当前的org_id,使用sys_context('multi_org', 'access_mode')获取当前的访问模式。

这两个值是我们多OU访问判断的关键,在2.4中会阐述怎么使用这两个值进行多OU的安全性策略控制。

2.3.5. 总结

在这一节中讨论到MO_GLOBAL包在生成MO的OU信息,同时理解了Access mode 和application context这两个概念,但我们只是涉及到了对MO的设置,并没有解决1.1.3中的同义词没有值的问题,我们也知道了需要使用我们设置的Access mode 和application context,但系统到底是怎使用的呢?在使用这两个值的过程中需要引入新的概念VPD……

2.4. VPD介绍和使用实例

2.4.1.

VPD介绍

什么是VPD(虚拟专用数据库):

VPD is one feature that allows development community to enforce security by attaching a security policy to database objects such as tables, views and synonyms.

简单的说,VPD就是向特定的数据库对象附加一个安全策略,在对这个对象操作的过程在中,会自动的使用这个安全策略进行验证,同时满足自定义条件和安全策略的操作才会获得预期的结果。下面以一个故事来介绍VPD

在一个交友网站上,有一张表ALL_PERSON_INFO存放该网站所有帅哥靓女的信息,该表有一个字段gender来存放该记录的性别。当一个用户登录该网站时,系统会有一个session值记录当前用户的性别。同时为了防止该网站背上同性恋之家的黑名,于是站长就来了一条严重的限制,该网站的用户只能查看到异性的信息。当一位名叫Tea的帅哥登录到这个网站,需要查找名字中带有coffee的女性时,常有的查询语句是:

Select * from

ALL_PERSON_INFO api

where api. Gender <>session( ‘gender’) and api.name like = ‘%coffee%’

很好,该语句查到的永远都是用户的异性信息。

但一个电脑牛人gay却想去看该系统的帅哥信息,他获取到这条查询语句后,使用SQL注入的技术(或其他技术)在该SQL查询上添加了另外一个条件,然后变成如下语句:

Select * from

ALL_PERSON_INFO api

where api. Gender <>session( ‘gender’) and api.name like = ‘%coffee%’ or api. Gender = session( ‘gender’)

这样造成的结果就是该网站所有的帅哥信息,赤裸裸地被这个gay拿去和他的同类们分享。

于是该网站的站长就气愤地找他们的DBA,说他没有把数据保护好,这下可苦了这个DBA,但却是也不是他的错啊,话虽如此,但系统优化还是得继续。这个DBA开始了他的优化系统之路,通过多方查找,他将视线定位在了VPD上,使用该技术,他成功根除了这个安全隐患。他的基本步骤概括如下:

首先将session( ‘gender’)放到一个APPLICATION CONTEXT中,然后为该表建立了一个同义词GENDER_PERSON_INFO,然后在该同义词上设置了一项安全策略,该策略具有一个相关函数,称为policy function,它返回一个用作谓词的字符串api.

Company Confidential - For internal use only MOAC内部实现 21 of 38

Gender <>sys_context(‘friend’,’gender’),通过使用该策略,凡是含有api. Gender =

session( ‘gender’)的查询将不会返回任何结果。

接下来来一个VPD使用的实例……

2.4.2. VPD使用实例

a. 建立对象和数据

CREATE TABLE hss.vpd_test( ID NUMBER,

NAME VARCHAR2(100), gender CHAR(1) );

INSERT INTO hss.vpd_test VALUES(1,'hansen','M'); INSERT INTO hss.vpd_test VALUES(2,'tea','M'); INSERT INTO hss.vpd_test VALUES(3,'tiger','F'); INSERT INTO hss.vpd_test VALUES(4,'coffee','F'); COMMIT; 查询数据如下:

b. 在APPS下建立同义词

CREATE SYNONYM HX_VPD_TEST For hss.vpd_test; 查询结果如下

c. 建立应用程序上下文

CREATE CONTEXT HX_VPD USING apps.XXHX_VPD_PKG; 查询结果如下

Company Confidential - For internal use only

MOAC内部实现 22 of 38

d. 建立策略函数包和应用设置函数包,包头定义如下,包体见附录 CREATE OR REPLACE PACKAGE XXHX_VPD_PKG IS

/*================================================== Program Name:

XXHX_VPD_PKG Description:

该pakcage的功能是建立策略函数gender_valid, 设置应用程序上下文值

History:

1.00 2008-11-28 hansen Creation

==================================================*/

/*================================================== Function Name : gender_valid Description:

安全策略函数必须带2个参数:第1个参数是方案名 (或用户名)、第2个参数是方案对象名(或表名、 视图名)。该函数返回附加到SQL语句的where子句 后面的字符串.即使在安全策略函数中不使用也要带 上所述2个参数,否则在执行时会出现“ORA-28112: 无法执行策略函数”的错误提示。 Argument:

obj_schame 方案名 obj_name 方案对象名 Return

安全策略字符串 History:

1.00 2008-11-28 hansen Creation

==================================================*/ FUNCTION gender_valid(obj_schame VARCHAR2,

obj_name VARCHAR2) RETURN VARCHAR2;

/*================================================== Function Name : set_context Description:

该方法用于设置应用程序上下文的值 Argument:

p_user_gender 性别 History:

1.00 2008-11-28 hansen Creation

==================================================*/ PROCEDURE set_context(p_user_gender VARCHAR2); END xxhx_vpd_pkg; e. 注册为对象注册策略 BEGIN

DBMS_Rls.Add_Policy( object_schema =>'APPS', object_name =>'HX_VPD_TEST',

policy_name =>'HX_VPD_GENDER', function_schema => 'APPS',

policy_function =>'XXHX_VPD_PKG.GENDER_VALID',

policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE);

END;

Company Confidential - For internal use only MOAC内部实现 23 of 38

4. 技术实施要点

4.1. 环境初始化

4.1.1.

环境初始化

a.进入一个新窗口执行发票查询(类似于PO,AP 模块也是多OU),

b.查看我们的首选项表:

c. 查看我们在多OU成功时能访问的表

d. 单OU模式下的Org_id BEGIN

fnd_global.apps_initialize(user_id => 1230, resp_id => 50541, resp_appl_id => 200); mo_global.set_policy_context('S', '81');

Company Confidential - For internal use only 技术实施要点 29 of 38

END;

这里插一点,fnd_global.apps_initialize的作用是环境初始化,初始化该环境后,我们可以使用fnd_global.user_id这类的变量,但多OU的初始化仅这样是明显不够的。

e. 多OU模式下使用mo_global.set_policy_context('M', ')方法进行访问,但结果却是失败的(在新的session下测试) BEGIN

fnd_global.apps_initialize(user_id => 1230, resp_id => 50541, resp_appl_id => 200); mo_global.set_policy_context('M', ''); END;

f. 根据前面的分析,是因为我们没有向po_glob_org_access_tmp表中插值,使用mo_global.init('SQLAP'),一切OK!! BEGIN

fnd_global.apps_initialize(user_id => 1230, resp_id => 50541, resp_appl_id => 200); mo_global.init('SQLAP'); END; /

Company Confidential - For internal use only

技术实施要点 30 of 38

4.2. 并发请求

4.3. Form开发

4.2.1. 并发请求

在R12中提交请求需要设置并发程序的OU模式,

路径:系统管理->并发->程序选出自己的程序,更新,在请求页面选择业务实体模式,设置好该处后如果没有设置预制文件“MO:默认业务实体”在请求提交的过程中会弹出下拉列表让用户选择相应的业务实体。

原理如下:

New column MULTI_ORG_CATEGORY in FND_CONCURRENT_PROGRAMS ? Values

– ‘S’ = Single Org – ‘M’ = Multi Org

? In upgrade, for programs where definition has been customized, value is null and concurrent program will NOT run. ? Script to set value

UPDATE fnd_concurrent_programs SET multi_org_category = { 'S‘ or ‘M’}

WHERE CONCURRENT_PROGRAM_NAME = '{Program Name}'

4.3.1. Form开发

现在还没有涉及到form开发,如果有机会再补上,提供一个讲解的文档, metlink no: 420787.1 White Paper

Oracle Applications Multiple Organizations Access Control for Custom Code

Company Confidential - For internal use only 技术实施要点 31 of 38

5. 附录

5.1. VPD实例源码

5.1.1. sql

--建立测试表

CREATE TABLE hss.vpd_test( ID NUMBER,

NAME VARCHAR2(100), gender CHAR(1) );

--插入测试值

INSERT INTO hss.vpd_test VALUES(1,'hansen','M'); INSERT INTO hss.vpd_test VALUES(2,'tea','M'); INSERT INTO hss.vpd_test VALUES(3,'tiger','F'); INSERT INTO hss.vpd_test VALUES(4,'coffee','F'); COMMIT;

SELECT * FROM hss.vpd_test ;

--建立同义词

CREATE SYNONYM HX_VPD_TEST For hss.vpd_test; SELECT * FROM hx_vpd_test;

--建立应用上下文

CREATE CONTEXT HX_VPD USING apps.XXHX_VPD_PKG;

SELECT *

FROM dba_context

WHERE PACKAGE = 'XXHX_VPD_PKG';

--注册策略 BEGIN

DBMS_Rls.Add_Policy( object_schema =>'APPS', object_name =>'HX_VPD_TEST', policy_name =>'HX_VPD_GENDER', function_schema => 'APPS',

policy_function =>'XXHX_VPD_PKG.GENDER_VALID',

policy_type => DBMS_RLS.SHARED_CONTEXT_SENSITIVE); END; /

--查看返回结果

SELECT xxhx_vpd_pkg.gender_valid('APPS', 'HX_VPD_TEST') FROM dual;

--设置应用初始值 BEGIN

xxhx_vpd_pkg.set_context('');

dbms_output.put_line(sys_context('HX_VPD','GENDER'));

Company Confidential - For internal use only 附录 32 of 38

END; /

SELECT * FROM HX_VPD_TEST;

--查看设置文件信息 SELECT *

FROM dba_policies dba

WHERE dba.object_name = 'HX_VPD_TEST';

5.1.2. pkg

CREATE OR REPLACE PACKAGE XXHX_VPD_PKG IS

/*================================================== author:

Hansen.wang Program Name: XXHX_VPD_PKG Description:

该pakcage的功能是建立策略函数gender_valid, 设置应用程序上下文值

History:

1.00 2008-11-28 hansen Creation

==================================================*/

/*================================================== Function Name : gender_valid Description:

安全策略函数必须带2个参数:第1个参数是方案名 (或用户名)、第2个参数是方案对象名(或表名、 视图名)。该函数返回附加到SQL语句的where子句 后面的字符串.即使在安全策略函数中不使用也要带 上所述2个参数,否则在执行时会出现“ORA-28112: 无法执行策略函数”的错误提示。 Argument:

obj_schame 方案名 obj_name 方案对象名 Return

安全策略字符串 History:

1.00 2008-11-28 hansen Creation

==================================================*/ FUNCTION gender_valid(obj_schame VARCHAR2,

obj_name VARCHAR2) RETURN VARCHAR2;

/*================================================== Function Name : set_context Description:

该方法用于设置应用程序上下文的值 Argument:

p_user_gender 性别 History:

1.00 2008-11-28 hansen Creation

==================================================*/

Company Confidential - For internal use only 附录 33 of 38

本文来源:https://www.bwwdw.com/article/tlpd.html

Top