为 OTN 撰稿
为 Oracle 技术网撰写技术文章,获得报酬的同时可提升技术技能。
更多信息
密切关注
OTN 架构师社区
OTN ArchBeat 博客 Facebook Twitter YouTube 随身播图标

Oracle Identity Manager UI 定制

作者:Gaurav Singh

定制 Oracle Identity Manager 用户界面的提示、技巧和技术洞察

2014 年 2 月

下载
download-icon13-1Oracle Identity Manager

简介

定制 Oracle Identity Manager (OIM) 自助控制台(“ID Console”)满足了一些业务需求,包括:

  • 向各种屏幕添加定制身份属性
  • 创建/管理 UI 表单,供用户请求访问企业资源时填写数据
  • 在某些屏幕上显示定制消息/横幅广告
  • 对一组特定用户隐藏某些 UI 控件
  • 提交表单数据或域值更改时触发定制验证

在本文中,我们将了解有关 OIM(协同一些其他组件)如何在 UI 上实现这种灵活性的一些幕后细节。本文假设读者熟悉 OIM 的基本功能,了解各种应用开发框架构件,如 EO.xml、VO.xml、pageDef.xml、tf.xml、.jsff 文件和托管 bean (mBean)。本文适用于 OIM 11gR2 及更高版本。

基于 MDS 的定制

Oracle Metadata Services (MDS) 通过 XML 文件提供可安全升级的定制框架。我们来看看以下示例,了解其含义:

示例:

假设一个应用提供以下 OOTB XML 文档,其路径 /metadata/sample-app-metadata.xml 由 MDS 管理。

<BaseDocument id="base">
     <TagA id="tagA" name="Sample Tag A" prop="30" />
     <TagB id="tagB" name="Sample Tag B" prop="25" />
<TagC id="tagC" name="Sample Tag C" prop="10" />
</BaseDocument>

现在,如果该应用保证此 XML 可在运行时定制,它将为此提供两个字符串。定制层名称(对于 OIM 为“site”)和层值(同样对于 OIM 为“site”)。使用这种办法,可在目录 /metadata/mdssys/cust/<layer-name>/<layer-value>/sample-app-metadata.xml.xml(注意扩展名“.xml.xml”)中创建一个定制 XML 文件,如下所示:

<mds:customization version="11.1.1.61.15" xmlns:mds="http://xmlns.oracle.com/mds">
  <mds:modify element="tagB">
     <!-MODIFYING PROP OF TAG-B TO 15 -->
              <mds:attribute name="prop" value="15"/>
  </mds:modify>
  <mds:insert parent="base" position="first">
     <!-INSERTING A CUSTOM ELEMENT AT THE BEGINNING OF ROOT TAG -->
     <Tag0 id="tag0" name="Custom Tag 0" prop="35" />
  </mds:insert>
</mds:customization>

在运行时,如果应用现在请求 sample-app-metadata.xml,以下 XML 将生效(定制更改以粗体显示):

<BaseDocument id="base?>
  <Tag0 id="tag0" name="Custom Tag 0" prop="35" />
  <TagA id="tagA" name="Sample Tag A" prop="30" />
  <TagB id="tagB" name="Sample Tag B" prop="15" />
  <TagC id="tagC" name="Sample Tag C" prop="10" />
</BaseDocument>

现在,由于定制 XML 独立存在,升级到下一版本时替换基础文档不会影响定制。它是可以安全升级的。

OIM 使用此概念以及 MDS 中的沙箱进行 UI 定制。我们来看一个典型用例:为用户实体添加了一个定制属性,并将其拖放到创建和查看用户页面上。我们将同时看到生成的构件及其含义。

  1. 图 1 显示激活沙箱后添加到用户实体的新属性:
singh-oim-ui-fig01
图 1:添加新属性
  1. 我们来导出沙箱,看看沙箱的内容(图 2)。
singh-oim-ui-fig02
图 2:沙箱内部
  • /mdsys/sandbox/active_mdsSandboxMetadata.xml:该文件标识一个沙箱 zip。它包含沙箱名称、创建者、上次修改者及各自的时间戳。如果您要用某个其他名称导入同一沙箱,更改 zip 文件名称也无济于事。应在此文件中更改名称。OIM 创建的沙箱名称前缀为“IdM”,更改名称时不得删除。
  • oracle/iam/ui/common/model/user/entity[或 view]/mdssys/cust/site/site/userEO[或 VO].xml.xml:有两个基于 userEO/VO.xml 的定制 XML 文件。它们包含新添加属性的定义。稍后再介绍它们。

    注意:如果您为 Role 或 Organization 添加属性,将在类似路径下看到类似文件。
  • oracle/iam/ui/runtime/form/model/user/entity[或 view]/mdssys/cust/site/site/userEO[或 VO].xml.xml:这些基于 userEO/VO.xml 的定制 XML 文件只存在于用户创建和用户修改流程中。由于用户创建/修改根据当前用户授权采取直接或审批路线,这两个流程在后台与透明处理此问题的目录集成。

    注:创建 Role 或 Organization 属性时不会看不到类似路径的文件;创建应用实例表单时在类似路径下将有 EO/VO.xml 文件,因为它们也与目录集成(虽然不是以透明方式)。
  • xliffBundles/oracle/iam/ui/runtime/BizEditorBundle_en_US.xlf:这是个资源包文件,其中保存属性的显示标签供本地化使用。默认情况下,生成该文件时使用在其下创建属性的浏览器区域设置的区域设置后缀。因此,例如在创建属性时,如果标签为法语,但浏览器区域设置为英语,则该标签将用于区域设置为英语的浏览器。
  1. 在 ADF 业务组件 (BC) 层,OIM 在指定的 EO.xml 和 VO.xml 文件中维护各种实体的属性。必须用新属性更新这些文件。但不会修改实际的 XML;而是在此基础上创建一个定制 XML,执行 <mds:insert> 操作,运行时在恰当的位置插入属性定义。沙箱实际上是这些 XML 文件的一个压缩集合。以下是一个 userEO.xml.xml 文件的示例。
<?xml version='1.0' encoding='UTF-8'?>
<mds:customization version="11.1.1.64.93" xmlns:mds="http://xmlns.oracle.com/mds"
motype_local_name="PDefEntityObject" motype_nsuri="http://xmlns.oracle.com/bc4j">
   
<!-- INSERT STATEMENT TO BE EXECUTED OVER OOTB USEREO.XML FILE-->
  <mds:insert parent="UserEO" position="last">  
  
  <!-- EO.XML ENTRY FOR ATTRIBUTE. NOTE THAT NAME IS ppNumber__c. -->
  <Attribute Name="ppNumber__c" IsPersistent="false" Precision="60" Scale="0"
    ColumnName="PPNUMBER__C" Type="java.lang.String" ColumnType="VARCHAR2(255)"
    SQLType="VARCHAR" xmlns="http://xmlns.oracle.com/bc4j">
    <Properties>
    <!-- CERTAIN PROPERTIES OF ATTRIBUTE -->
      <Property Name="AttributeType" Value="Text"/>
      <Property Name="DISPLAYWIDTH" Value="60"/>
      <Property Name="ExtnCustom" Value="Y"/>
  
  <!-- REFERENCE TO BizEditorBundle.xlf FOR DISPLAY LABEL (CONTAINED IN THE SAME SANDBOX) -->
      <Property Name="LABEL_ResId" 
      Value="${adfBundle['oracle.adf.businesseditor.model.util.BaseRuntimeResourceBundle']
      ['oracle.iam.ui.common.model.user.entity.UserEO.ppNumber__c_LABEL']}"/>
  
  <!-- NAME OF ATTRIBUTE AS KNOWN BY OIM BACKEND -->
    <Property Name="oimRefAttrName" Value="ppNumber"/>
  </Properties>
    <CompOper Name="=" ToDo="2" Oper="=" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="STARTSWITH" ToDo="2" Oper="STARTSWITH" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="ENDSWITH" ToDo="2" Oper="ENDSWITH" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="<>" ToDo="2" Oper="<>" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="CONTAINS" ToDo="2" Oper="CONTAINS" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="DOESNOTCONTAIN" ToDo="2" Oper="DOESNOTCONTAIN" MinCardinality="1"
      MaxCardinality="1"/>
    <CompOper Name="Dummy" ToDo="-2" Oper="Dummy" MinCardinality="1" MaxCardinality="1"/>
  </Attribute>
  </mds:insert>
   <mds:modify element="UserEO">
      <mds:attribute name="StaticDef" value="oracle.iam.ui.common.model.user.entity.UserEO"/>
   </mds:modify>
</mds:customization>
  1. 我们现在可以发布此沙箱,并重新登录 ID 控制台。
  2. 我们将这个新域显示在 user create 和 user details 页面上。图 3 和图 4 演示了这一过程。现在我们得到另外一个活动的沙箱。
singh-oim-ui-fig03
图 3:User Create 屏幕(Data Component Catalog — userVO)
singh-oim-ui-fig04
图 4:User Details 屏幕(Data Component Manage Users — UserVO1)
  1. 从技术上讲,我们需要在 .jsff 文件中添加一个 <af:inputText> 组件,并将其绑定到 ADF BC 层中的特定属性。此绑定应通过 pageDef.xml<attribute> 绑定完成。我们来导出沙箱并验证其实际内容如下所示。
singh-oim-ui-fig05
图 5:userCreateForm.jsff.xml
singh-oim-ui-fig06
图 6:userCreateFormPageDef.xml.xml
  1. 现在可以测试更改,完成后即可发布沙箱。

我们来看看 OIM 通过 MDS 定制 UI 时使用的一些组件。

  • 沙箱:允许在运行时测试一组元数据或定制构件,不会影响其他用户的会话。沙箱内的任何元数据文件(或定制 XML 文件)仅适用于沙箱处于活动状态的用户会话。大致来说,OIM 中的沙箱遵循以下生命周期:
    singh-oim-ui-fig07
    图 7:OIM 沙箱生命周期
    • 已创建/导入:沙箱在 MDS_SANDBOXES 表中有一个条目,其中可能包含也可能不包含与其关联的元数据文件。即使它有元数据,这些元数据在运行时也不起作用。
    • 已激活:沙箱内所含元数据文件在运行时只对激活它的用户会话生效。如果用户注销或会话过期,该元数据将再次变得无效。
    • 已发布:沙箱生命周期的最终状态之一。元数据文件一旦发布,将永久保存在 MDS 中其各自路径下,因此将在运行时对所有后续用户会话可用。
    • 已删除:沙箱生命周期的最终状态之一。一旦处于此状态,沙箱就变得不可恢复,其中所有元数据文件都将丢失。
  • WebCenter Composer:Oracle 的一个单独产品,它提供在运行时编辑 ADF 页面的 UI。上面的用例演示项目编号 5 显示了该界面的屏幕快照。实际上,它基于被编辑页面生成定制 XML 文件,这些 XML 文件包含在页面上添加/修改/删除的其他组件。然后,这些文件被推送到当前 ADF 上下文的 MDS 会话,由 MDS 管理。(MDS 会话可通过 ADFContext.getCurrent.getMDSSessionAsObject() 方法获取。)
  • ADF Business Editor:Business Editor (BE) 是一个 ADF 组件,可以在运行时创建或编辑 ADF BC 构件(EO.xmlVO.xmlAM.xml)。为用户/角色/组织创建定制属性时,BE 负责基于包含新属性的对应 EO/VO 生成定制 XML 文件。同样,这些文件被推送到当前 ADF 上下文的 MDS 会话,由 MDS 的管理。BE 也在创建应用实例表单时发挥作用。在本例中,在运行时创建一个新的 EO.xmlVO.xml,并编辑 OOTB CatalogAM.xml 以包含新的 VO。
沙箱优秀实践
  • 使用相同的名称重新导入沙箱将替换现有沙箱。在执行任何手动 XML 编辑之前,请备份所有沙箱。
  • 一个页面应始终在一个沙箱中编辑,以免将来出现冲突(和混淆)。
  • 对于任何 OOTB 构件(jsff 页面或 EO 或 VO),有且仅有一个包含客户的站点定制的定制文件。对同一构件的所有连续定制将导致编辑同一文件。因此,必须避免出现并行执行定制的会话。一个会话发布的更改会覆盖另一个会话发布的任何更改。
  • 例如,因为 userEO 只有一个定制文件,添加用户属性的沙箱也可能包含任何先前发布的用户属性。

将定制 ADF 构件注入 OIM

除了基于 MDS 的定制框架,OIM 还提供了一种构建定制 ADF 任务流和托管 bean 的方法。这些通常用于定制验证、处理定制链接和按钮操作,甚至构建全新的屏幕和通过某些链接启动它们。下面是此类更改的部署过程:

  • 在 jdev 中创建 ADF Model 和 ADF View Controller 项目,其中包含您的构件。定制项目中必须包含 OIM Client、OIM Model 和 OIM View Controller 共享库。这些库可在 IDM_HOME/server/jdev.lib 目录中找到。
  • 从 jdev 项目准备 ADF 库 JAR 文件。为了准备这些 jar,需要在 jdev 中创建 ADF 库 JAR 部署配置文件。
  • 将 ADF 库 JAR 文件打包到 WEB-INF/lib 文件夹中的 oracle.iam.ui.custom-dev-starter-pack.war(文件位于 IDM_HOME/server/apps 中)。如果 WEB-INF 中没有 OOTB,则创建一个 lib 文件夹。
  • 在 WebLogic 控制台找到 oracle.iam.ui.custom 库,查看部署路径(可能不是从 IDM_HOME/server/apps 部署的)。
  • singh-oim-ui-fig08
    图 8:WebLogic 控制台中的 oracle.iam.ui.custom
  • 用刚刚重新打包的存档替换文件系统中的 Web 存档 (war)。
  • 停止图 8 所示的两个活动应用。它们分别是 ID 控制台和系统管理员控制台应用,都依赖定制库。
  • 更新 oracle.iam.ui.custom 库部署。一旦更新完成,就启动先前停止的两个应用。

开发定制 mBean 时必须牢记几点:

  • adfc-config.xml 中直接注册 bean 时,不要使用 pageFlowScopebackingBeanScope。而是使用会话和请求作用域。如果您构建了自己的任务流,那么可以在此使用任何所需作用域注册 bean。
  • 在 bean 代码内部,可通过 EL 上下文 API 使用表达式语言 (EL) 表达式计算获取 OOTB bean 的句柄。可以看到,所用 bean 作用域和名称附加到 web center composer UI 中的一些域/组件(通过在 ID 控制台上单击“Customize”显示)。
  • 不过,获取 OOTB bean 句柄可能有些危险,因为定制 bean 不能确定 OOTB bean 何时初始化,这可能导致定制代码中出现空指针异常。
  • MDS 定制几乎总是伴随着执行定制代码注入。只要开发定制 bean 或任务流,就必须通过 web center composer 执行某些更改,以调用您的 bean 代码或任务流。

总结

本文对通过 OIM UI 可能实现的定制进行了技术分析,演示了最常见的用例 — 为创建和查看详细信息页面添加新用户属性 — 并介绍了后台发生的一些事情。本文还介绍了注入在运行时可用的 OIM UI 定制 ADF 代码的所须执行的基本步骤。

关于作者

Gaurav Singh 是 Oracle Identity Manager 开发小组成员。自其职业生涯伊始,他就一直关注 UI 技术,研究了 Oracle ADF、Oracle Metadata Services、Oracle Composer 及类似工具,以提供下一代用户界面。
LinkedIn