この章では、ユーザー管理操作に関する後処理機能の非同期実装について説明します。内容は次のとおりです。
Identity Managementシステムでは、ユーザーまたはシステムによって実行されるアクションは、操作と呼ばれます。操作の例として、ユーザーの作成、ユーザーの更新、パスワード・ポリシーの作成などがあります。各操作には、前処理ステージおよび後処理ステージがあります。
各ステージにおける処理は、そのステージに配置されているブランチおよびイベント・ハンドラ(存在する場合)によって決定されます。ステージにブランチがある場合は、イベント・ハンドラからのレスポンスによって、使用するブランチが決まります。ステージにイベント・ハンドラがない場合、またはイベント・ハンドラからのレスポンスに推奨パスがない場合は、操作はデフォルトのパスに従って次のステージに移ります。
アイデンティティ管理環境で実行される各操作が、ユーザーまたは他のエンティティに影響を及ぼす場合があります。たとえば、ユーザーを作成するとそのユーザーに対するリソースのプロビジョニングが発生し、履歴を更新するとレポート表が変更され、新規パスワード・ポリシーを作成すると特定のユーザー・パスワードが無効になって次のログイン時に変更を要求される場合があります。
ユーザーに固有の操作(作成、変更、削除、有効化、無効化など)は、ユーザー管理操作と呼ばれます。操作のライフサイクルは、次のステージで構成されます。
validation
前処理
監査
アクション
後処理
補正
終了処理
ユーザー管理操作(作成、更新、削除、有効化、無効化、ロック、ロック解除、パスワード変更など)の影響(ユーザー管理操作の後処理機能とも呼ばれます)は、イベント・ハンドラを作成することによってカスタマイズできます。
Oracle Identity Manager 11gリリース1(11.1.1)では、ユーザー管理操作に関連付けられた後処理機能の非同期実行がサポートされています。これにより、ユーザー管理操作の体感パフォーマンスは大幅に向上しています。
ユーザー管理操作に関連付けられた後処理機能は、特定の一連のユーザーに対してプログラムでトリガーできます。この機能は、ユーザーがデータ・ストアで直接管理される状況(特に、リコンシリエーションまたはバルク・ロード・シナリオ)で役立ちます。
11gリリース1(11.1.1)のカーネルでは、ユーザー管理操作の機能をカスタマイズするために実装されているサービス・プロバイダ・インタフェース(SPI)を公開しています。現在は、エンティティの操作の前処理、後処理および検証ステージのみをカスタマイズできます。
|
注意: 前処理および検証機能のカスタマイズは、操作と同期しています。ただし、後処理機能のカスタマイズは非同期です。 |
この項では、イベント・ハンドラによるユーザー管理操作の拡張について、次のトピックで説明します。
イベント・ハンドラXMLファイルは、要素および要素の属性で構成されます。この項では、イベント・ハンドラXMLファイル内の、一部の要素および要素の属性について説明します。また、イベント・ハンドラXML定義の必須の名前空間についても説明します。
要素
イベント・ハンドラXMLファイルのトップレベル(親)要素は、eventhandlersです。表8-1に、eventhandlers親要素内に一般的に定義されるサブ要素を示します。
表8-1 eventhandlers要素内の一般的なサブ要素
| サブ要素 | 説明 |
|---|---|
|
|
編成に対して実行される検証を識別します。 |
|
|
前処理、後処理およびアクション・ステージで実行される操作を識別します。 |
|
|
イベント・ハンドラが失敗した場合に実行されるイベント・ハンドラを識別します。 |
|
|
編成の最後に実行されるイベント・ハンドラを識別します。終了処理は、編成の最後のステージです。 |
|
|
影響の編成が失敗した場合に実行されるイベント・ハンドラを識別します。 |
|
|
拒否や取消しなどの帯域外編成フローのイベント・ハンドラを定義します。 |
|
|
編成の補正フローで実行されるイベント・ハンドラを識別します。 |
要素の属性
イベント・ハンドラXMLファイル内の要素には、属性が含まれています。表8-2に、要素内に一般的に定義される属性を示します。
表8-2 eventhandlers要素内のサブ要素の一般的な属性
| 要素の属性 | 説明 |
|---|---|
|
名前 |
イベント・ハンドラの名前。 |
|
class |
イベント・ハンドラを実装するJavaクラスのフル・パッケージ名。 |
|
entity-type |
イベント・ハンドラの実行対象のエンティティのタイプを識別します。値 |
|
operation |
イベント・ハンドラの実行対象の操作のタイプを識別します。値 |
|
order |
イベント・ハンドラが実行される順序を識別します。サポートされている値は、 |
|
orch-target |
編成のタイプ(エンティティ編成、Toplink編成など)を識別します。次の値がサポートされています。
デフォルト値は |
|
sync |
この属性は、action-handlerおよびchange-failed要素のみで機能します。sync属性は、イベント・ハンドラが同期か非同期かを示します。サポートされている値は、 注意: validation-handler要素の場合、sync属性は |
|
stage |
この属性は、out-of-band-handler、action-handlerおよびfailed-handler要素のみで機能します。stage属性は、イベント・ハンドラが実行されるステージを示します。次の値がサポートされています。
|
|
tx |
この属性は、out-of-band-handler、action-handler、compensate-handlerおよびfinalization-handler要素のみで機能します。tx属性は、イベント・ハンドラが独自のトランザクションで実行されるかどうかを示します。サポートされている値は、 |
<eventhandlers>要素の名前空間要件
例8-1は、すべてのカスタム・イベント・ハンドラXML定義の<eventhandlers>ルート要素で定義する必要がある名前空間です。
ユーザー管理操作に対するすべてのカスタマイズは、イベント・ハンドラとして実装する必要があります。
カスタム・イベント・ハンドラを作成するには、次の手順を実行します。
カスタム・イベント・ハンドラを実装します。
第8.2.2.1項「カスタム・イベント・ハンドラの実装」を参照してください。
カスタム・イベント・ハンドラを含むプラグインを作成します。
第8.2.2.2項「カスタム・イベント・ハンドラのプラグインの作成」を参照してください。
カスタム・イベントを定義します。
第8.2.2.3項「カスタム・イベントの定義」を参照してください。
カスタム・イベント・ハンドラを実装するには、次の手順を実行します。
表8-3に示すSPIのいずれかを実装して、カスタム前処理、後処理または検証ハンドラを作成します。
カスタム・クラスをコンパイルするクラス・パスに次の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ファイル
カスタム・クラスを含む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;
}
カスタム・イベント・ハンドラを含むプラグインを作成するには、適切なイベント・ハンドラ・クラスを開発する必要があります。詳細は、第7章「プラグインの開発」を参照してください。
|
注意: プラグイン定義で使用されるプラグイン・ポイントが |
|
注意: プラグインは、パッケージ化のガイドラインに準拠しているかぎり、必要に応じて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>
カスタム・イベントを定義するには、次の手順を実行します。
すべてのカスタム・イベントの定義を含むメタデータ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>
これらのイベント定義をMDSにインポートします。詳細は、第33章「MDSユーティリティとユーザーが修正可能なメタデータ・ファイル」を参照してください。shiphomeベースのインストールの場合、イベント定義のインポートに必要なスクリプトが次のディレクトリにあります。
OIM_HOME/common/wlst
|
注意: すべてのカスタム・イベント定義を同じファイルで定義する必要はありません。複数の新しいイベント定義ファイルに分割するか、既存のイベント定義ファイルに追加できます。目的のイベント定義ファイルのエクスポート、変更および再インポートでは、後者が実装されています。イベント定義ファイルのエクスポートおよびインポートの詳細は、第33章「MDSユーティリティとユーザーが修正可能なメタデータ・ファイル」を参照してください。 |
次のリストに、イベント・ハンドラが起動しない場合のトラブルシューティングに役立つ情報を示します。一般的な原因は次のとおりです。
EventHandlers.xmlに構文エラーがあります。
EventHandlers.xmlがMDS内の間違った場所にインポートされました。Oracle Identity Managerによって認識されるトップレベル・ディレクトリ(/db/、/file/、/custom/など)内である必要があります。/mystuff/(例)およびルート・ディレクトリ(/)は認識されません。
前処理イベント・ハンドラがリコンシリエーションを使用して実装されています。前処理イベント・ハンドラはリコンシリエーションでは起動されません。
前処理イベント・ハンドラがリコンシリエーションを使用して実装されていますが、バルク編成実行が実装されていません。リコンシリエーションを使用するには、バルクと非バルクの両方の方式が実装されている必要があります。