ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Identity Manager開発者ガイド
11g リリース1(11.1.1)
B66705-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

8 ユーザー管理操作の拡張のためのイベント・ハンドラの開発

この章では、ユーザー管理操作に関する後処理機能の非同期実装について説明します。内容は次のとおりです。

8.1 ユーザー管理操作の概要

Identity Managementシステムでは、ユーザーまたはシステムによって実行されるアクションは、操作と呼ばれます。操作の例として、ユーザーの作成、ユーザーの更新、パスワード・ポリシーの作成などがあります。各操作には、前処理ステージおよび後処理ステージがあります。

各ステージにおける処理は、そのステージに配置されているブランチおよびイベント・ハンドラ(存在する場合)によって決定されます。ステージにブランチがある場合は、イベント・ハンドラからのレスポンスによって、使用するブランチが決まります。ステージにイベント・ハンドラがない場合、またはイベント・ハンドラからのレスポンスに推奨パスがない場合は、操作はデフォルトのパスに従って次のステージに移ります。

アイデンティティ管理環境で実行される各操作が、ユーザーまたは他のエンティティに影響を及ぼす場合があります。たとえば、ユーザーを作成するとそのユーザーに対するリソースのプロビジョニングが発生し、履歴を更新するとレポート表が変更され、新規パスワード・ポリシーを作成すると特定のユーザー・パスワードが無効になって次のログイン時に変更を要求される場合があります。

ユーザーに固有の操作(作成、変更、削除、有効化、無効化など)は、ユーザー管理操作と呼ばれます。操作のライフサイクルは、次のステージで構成されます。

ユーザー管理操作(作成、更新、削除、有効化、無効化、ロック、ロック解除、パスワード変更など)の影響(ユーザー管理操作の後処理機能とも呼ばれます)は、イベント・ハンドラを作成することによってカスタマイズできます。


ヒント:

イベント・ハンドラを作成する方法の詳細は、「カスタム・イベント・ハンドラの作成」を参照してください。


Oracle Identity Manager 11gリリース1(11.1.1)では、ユーザー管理操作に関連付けられた後処理機能の非同期実行がサポートされています。これにより、ユーザー管理操作の体感パフォーマンスは大幅に向上しています。

ユーザー管理操作に関連付けられた後処理機能は、特定の一連のユーザーに対してプログラムでトリガーできます。この機能は、ユーザーがデータ・ストアで直接管理される状況(特に、リコンシリエーションまたはバルク・ロード・シナリオ)で役立ちます。

8.2 イベント・ハンドラによるユーザー管理操作の拡張

11gリリース1(11.1.1)のカーネルでは、ユーザー管理操作の機能をカスタマイズするために実装されているサービス・プロバイダ・インタフェース(SPI)を公開しています。現在は、エンティティの操作の前処理、後処理および検証ステージのみをカスタマイズできます。


注意:

前処理および検証機能のカスタマイズは、操作と同期しています。ただし、後処理機能のカスタマイズは非同期です。


この項では、イベント・ハンドラによるユーザー管理操作の拡張について、次のトピックで説明します。

8.2.1 イベント・ハンドラXMLファイルの要素の理解

イベント・ハンドラXMLファイルは、要素および要素の属性で構成されます。この項では、イベント・ハンドラXMLファイル内の、一部の要素および要素の属性について説明します。また、イベント・ハンドラXML定義の必須の名前空間についても説明します。

要素

イベント・ハンドラXMLファイルのトップレベル(親)要素は、eventhandlersです。表8-1に、eventhandlers親要素内に一般的に定義されるサブ要素を示します。

表8-1 eventhandlers要素内の一般的なサブ要素

サブ要素 説明

validation-handler

編成に対して実行される検証を識別します。

action-handler

前処理、後処理およびアクション・ステージで実行される操作を識別します。

failed-handler

イベント・ハンドラが失敗した場合に実行されるイベント・ハンドラを識別します。

finalization-handler

編成の最後に実行されるイベント・ハンドラを識別します。終了処理は、編成の最後のステージです。

change-failed

影響の編成が失敗した場合に実行されるイベント・ハンドラを識別します。

out-of-band-handler

拒否や取消しなどの帯域外編成フローのイベント・ハンドラを定義します。

compensate-handler

編成の補正フローで実行されるイベント・ハンドラを識別します。


要素の属性

イベント・ハンドラXMLファイル内の要素には、属性が含まれています。表8-2に、要素内に一般的に定義される属性を示します。

表8-2 eventhandlers要素内のサブ要素の一般的な属性

要素の属性 説明

名前

イベント・ハンドラの名前。

class

イベント・ハンドラを実装するJavaクラスのフル・パッケージ名。

entity-type

イベント・ハンドラの実行対象のエンティティのタイプを識別します。値ANYを設定すると、イベント・ハンドラはすべてのエンティティに対して実行されます。

operation

イベント・ハンドラの実行対象の操作のタイプを識別します。値ANYを設定すると、イベント・ハンドラはすべての操作に対して実行されます。

order

イベント・ハンドラが実行される順序を識別します。サポートされている値は、FIRSTLASTまたは数字です。

orch-target

編成のタイプ(エンティティ編成、Toplink編成など)を識別します。次の値がサポートされています。

  • oracle.iam.platform.kernel.vo.EntityOrchestration

  • oracle.iam.platform.kernel.vo.MDSOrchestration

  • oracle.iam.platform.kernel.vo.RelationOrchestration

  • oracle.iam.platform.kernel.vo.ToplinkOrchestration

デフォルト値はoracle.iam.platform.kernel.vo.EntityOrchestrationです。

sync

この属性は、action-handlerおよびchange-failed要素のみで機能します。sync属性は、イベント・ハンドラが同期か非同期かを示します。サポートされている値は、TRUEまたはFALSEです。TRUE(同期)に設定した場合、カーネルではイベント・ハンドラによってEventResultが返されることを予期します。FALSE(非同期)に設定した場合、イベント結果としてNULLを返し、イベント結果について後でカーネルに通知する必要があります。

注意: validation-handler要素の場合、sync属性はTRUEに設定する必要があります。

stage

この属性は、out-of-band-handler、action-handlerおよびfailed-handler要素のみで機能します。stage属性は、イベント・ハンドラが実行されるステージを示します。次の値がサポートされています。

  • preprocess

  • アクション

  • 監査

  • postprocess

  • veto

  • cancelled

tx

この属性は、out-of-band-handler、action-handler、compensate-handlerおよびfinalization-handler要素のみで機能します。tx属性は、イベント・ハンドラが独自のトランザクションで実行されるかどうかを示します。サポートされている値は、TRUEまたはFALSEです。


<eventhandlers>要素の名前空間要件

例8-1は、すべてのカスタム・イベント・ハンドラXML定義の<eventhandlers>ルート要素で定義する必要がある名前空間です。

例8-1 カスタム・イベント・ハンドラの必須の名前空間定義

<eventhandlers xmlns="http://www.oracle.com/schema/oim/platform/kernel"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.oracle.com/schema/oim/platform/kernel
  orchestration-handlers.xsd">

8.2.2 カスタム・イベント・ハンドラの作成

ユーザー管理操作に対するすべてのカスタマイズは、イベント・ハンドラとして実装する必要があります。

カスタム・イベント・ハンドラを作成するには、次の手順を実行します。

  1. カスタム・イベント・ハンドラを実装します。

    第8.2.2.1項「カスタム・イベント・ハンドラの実装」を参照してください。

  2. カスタム・イベント・ハンドラを含むプラグインを作成します。

    第8.2.2.2項「カスタム・イベント・ハンドラのプラグインの作成」を参照してください。

  3. カスタム・イベントを定義します。

    第8.2.2.3項「カスタム・イベントの定義」を参照してください。

8.2.2.1 カスタム・イベント・ハンドラの実装

カスタム・イベント・ハンドラを実装するには、次の手順を実行します。

  1. 表8-3に示すSPIのいずれかを実装して、カスタム前処理、後処理または検証ハンドラを作成します。

    表8-3 カスタム・イベント・ハンドラを作成するためのSPI

    ステージ 実装するSPI

    前処理

    oracle.iam.platform.kernel.spi.PreProcessHandler

    後処理

    oracle.iam.platform.kernel.spi.PostProcessHandler

    検証

    oracle.iam.platform.kernel.spi.ValidationHandler


  2. カスタム・クラスをコンパイルするクラス・パスに次のJARファイルを含めます。

    OIM_INSTALL_HOME/server/platformから

    • iam-platform-kernel.jar

    • iam-platform-utils.jar

    • iam-platform-context.jar

    • iam-plaftorm-authz-service.jar

    OIM_INSTALL_HOME/designconsole/libから

    • oimclient.jar

    • xlAPI.jar

    OIM_INSTALL_HOME/designconsole/libおよびOIM_INSTALL_HOME/serverから

    その他のすべてのJARファイル

  3. カスタム・クラスを含むJARファイルのライブラリを作成します。

次のコード・サンプルは、Oracle Identity Manager 9.1.x APIおよび11g APIを起動して、ユーザー管理操作をカスタマイズする方法を示しています。詳細は、SPIのJavadocを参照してください。

例1: カスタム・パスワード検証

例8-2は、カスタム検証ハンドラのコードの一部分のサンプルを示しており、ここでは、パスワードに$が使用されていないことを確認しています。

例8-2 カスタム検証ハンドラのサンプル

 throws ValidationException, ValidationFailedException {
    HashMap<String, Serializable> parameters = orchestration.getParameters();
    String password = (parameters.get("usr_password") instanceof ContextAware)
      ? (String) ((ContextAware) parameters.get("usr_password")).getObjectValue()
      : (String) parameters.get("usr_password");
    if (password.contains("$")) {
      throw new ValidationFailedException();
    }
}

例2: ミドル・ネームのイニシャルを設定するカスタム前処理イベント・ハンドラ

例8-3は、カスタム前処理イベント・ハンドラのコードの一部分のサンプルを示しており、ここでは、ユーザーにミドル・ネームがない場合に、ミドル・ネームのイニシャルを名の最初の文字に設定しています。


注意:

バルク・リコンシリエーションでは前処理イベント・ハンドラは実行されません。


例8-3 カスタム前処理イベント・ハンドラのサンプル

// This custom preprocess event handler sets the first letter of the first name as
// the middle initial when the user doesn't have a middle name
public EventResult execute
   (long processId, long eventId, Orchestration orchestration) {
   HashMap<String, Serializable> parameters = orchestration.getParameters();
// If the middle name is empty set the first letter of the first name 
// as the middle initial
String middleName = getParamaterValue(parameters, "Middle Name");
  if (isNullOrEmpty(middleName)) {
     String firstName = getParamaterValue(parameters, "First Name");
     middleName = firstName.substring(0,1);
     orchestration.addParameter("Middle Name", middleName);
  }
  return new EventResult();
}
private String getParamaterValue(HashMap<String, Serializable> parameters, 
  String key) {
  String value = (parameters.get(key) instanceof ContextAware)
  ? (String) ((ContextAware) parameters.get(key)).getObjectValue()
  : (String) parameters.get(key);
  return value;
}

例3: リソース・オブジェクトをプロビジョニングするカスタム後処理イベント・ハンドラ

例8-4は、カスタム後処理イベント・ハンドラのコードの一部分のサンプルを示しており、ここでは、ロールがROLE 00.5であるユーザーにリソース・オブジェクトOBJ005をプロビジョニングしています。

例8-4 カスタム後処理イベント・ハンドラのサンプル

// This custom post process event handler provisions resource object 'OBJ005' 
// to a user who has role 'ROLE 005'
public EventResult execute(long processId, long eventId, 
  Orchestration orchestration) {
    tcUserOperationsIntf userOperationsService =   
    Platform.getService(tcUserOperationsIntf.class);
try {
  String userKey = getUserKey(processId, orchestration);
  if (hasRole(userKey, "ROLE 005")) {
     long objKey = findObject("OBJ001");
userOperationsService.provisionResource(Long.getLong(userKey), objKey);
}
} catch (Exception e) {
throw new EventFailedException("Error occurred ", e);
}
 
return new EventResult();
}
 
// This method retrieves the key of the user entity on which an operation 
// is performed
// This method shows how to retrieve the operation being performed, entity type
// and the associated value objects 
private String getUserKey (long processID, Orchestration orchestration) {
  String userKey;
  String entityType = orchestration.getTarget().getType();
  EventResult result = new EventResult();
 
if (!orchestration.getOperation().equals("CREATE")) {
userKey = orchestration.getTarget().getEntityId();
} else {
OrchestrationEngine orchEngine = Platform.getService(OrchestrationEngine.class);
userKey = (String) orchEngine.getActionResult(processID);
}
return userKey;
}
 
// This method checks if a given user has a given role. 
// It demonstrates how to invoke a OIM 11g API from a custom event handler
private boolean hasRole(String userKey, String roleName) 
  throws Exception {
  RoleManager roleManager = Platform.getService(RoleManager.class);
  List<Identity> roles = roleManager.getUserMemberships(userKey);
 
  for (Iterator iterator = roles.iterator(); iterator.hasNext();) {
Role role = (Role) iterator.next();
if (roleName.equals((String)role.getAttribute("Role Name"))) {
return true;
}
 
}
return false;
}
 
// This method finds details about a resource object with the given name. 
// It demonstrates how to invoke a 9.1.x API from a custom event handler
private long findObject(String objName) throws Exception {
  long objKey = 0;
  tcObjectOperationsIntf objectOperationsService =  
  Platform.getService(tcObjectOperationsIntf.class);
HashMap params = new HashMap();
params.put("Objects.Name", objName);
tcResultSet objects = objectOperationsService.findObjects(params);
for (int i = 0; i < objects.getRowCount(); i++) {
  objects.goToRow(i);
  if (objects.getStringValue("Objects.Name").equals(objName)) {
  objKey = objects.getLongValue("Objects.Key");
}
}
 return objKey;
}

8.2.2.2 カスタム・イベント・ハンドラのプラグインの作成

カスタム・イベント・ハンドラを含むプラグインを作成するには、適切なイベント・ハンドラ・クラスを開発する必要があります。詳細は、第7章「プラグインの開発」を参照してください。


注意:

プラグイン定義で使用されるプラグイン・ポイントがoracle.iam.platform.kernel.spi.EventHandlerに設定されていることを確認してください。



注意:

プラグインは、パッケージ化のガイドラインに準拠しているかぎり、必要に応じてJARファイルと同様にパッケージ化できます。


次に、プラグインXMLファイルの例を示します。

<?xml version="1.0" encoding="UTF-8"?>
<oimplugins>
  <plugins pluginpoint="oracle.iam.platform.kernel.spi.EventHandler">
    <plugin pluginclass=  
       "oracle.oim.extensions.preprocess.SamplePreprocessExtension" 
        version="1.0" 
        name="SamplePreprocessExtension">
    </plugin>
    <plugin pluginclass= 
        "oracle.oim.extensions.postprocess.SamplePostprocessExtension"
         version="1.0" 
         name="SamplePostprocessExtension">
    </plugin>
    <plugin pluginclass= 
       "oracle.oim.extensions.validation.SampleValidationExtension"
        version="1.0" 
        name="SampleValidationExtension">
    </plugin>
  </plugins>
</oimplugins>

8.2.2.3 カスタム・イベントの定義

カスタム・イベントを定義するには、次の手順を実行します。

  1. すべてのカスタム・イベントの定義を含むメタデータXMLファイルを作成します。

    例8-5は、メタデータ・ファイルとはどのようなものかを示しています。

    例8-5 カスタム・イベント定義のサンプル・メタデータXMLファイル

    <?xml version='1.0' encoding='utf-8'?>
    <eventhandlers>
      <!-- Custom preprocess event handlers -->
      <action-handler
        class="oracle.oim.extensions.preprocess.SamplePreprocessExtension"
        entity-type="User" 
        operation="CREATE" 
        name="SamplePreprocessExtension"
        stage="preprocess"
        order="1000" 
        sync="TRUE"/>
     
      <!-- Custom postprocess event handlers -->
      <action-handler
        class="oracle.oim.extensions.postprocess.SamplePostprocessExtension"
        entity-type="User" 
        operation="CREATE" 
        name="SamplePostprocessExtension"
        stage="postprocess"
        order="1000" 
        sync="TRUE"/>
     
      <action-handler
        class="oracle.oim.extensions.postprocess.SamplePostprocessExtension"
        entity-type="User" 
        operation="MODIFY" 
        name="SamplePostprocessExtension"
        stage="postprocess"
        order="1000" 
        sync="TRUE"/>
     
      <!-- Custom validation event handlers -->
       <validation-handler
        class="oracle.oim.extensions.validation.SampleValidationExtension"
        entity-type="User" 
        operation="CREATE" 
        name="SampleValidationExtension"
        order="1000"/>       
     
       <validation-handler
        class="oracle.oim.extensions.validation.SampleValidationExtension"
        entity-type="User" 
        operation="MODIFY" 
        name="SampleValidationExtension"
        order="1000"/>       
    </eventhandlers>
    
  2. これらのイベント定義をMDSにインポートします。詳細は、第33章「MDSユーティリティとユーザーが修正可能なメタデータ・ファイル」を参照してください。shiphomeベースのインストールの場合、イベント定義のインポートに必要なスクリプトが次のディレクトリにあります。

    OIM_HOME/common/wlst


    注意:

    すべてのカスタム・イベント定義を同じファイルで定義する必要はありません。複数の新しいイベント定義ファイルに分割するか、既存のイベント定義ファイルに追加できます。目的のイベント定義ファイルのエクスポート、変更および再インポートでは、後者が実装されています。イベント定義ファイルのエクスポートおよびインポートの詳細は、第33章「MDSユーティリティとユーザーが修正可能なメタデータ・ファイル」を参照してください。


8.3 イベント・ハンドラのトラブルシューティング

次のリストに、イベント・ハンドラが起動しない場合のトラブルシューティングに役立つ情報を示します。一般的な原因は次のとおりです。