この章では、編成に関する概念と、Oracle Identity Managerの機能を拡張するためのカスタム・イベント・ハンドラの作成方法について説明します。内容は次のとおりです。
Identity Managementシステムでは、ユーザーまたはシステムによって実行されるアクションは、操作と呼ばれます。操作には、ユーザーの作成、ロールの変更、パスワード・ポリシーの作成などがあります。事前に定義された一連のステージを進み、各ステージでなんらかのビジネス・ロジックを実行するOracle Identity Manager操作を編成と呼びます。編成によって変更されるオブジェクトのタイプを編成ターゲットと呼びます。編成操作の実行に必要なデータを編成パラメータと呼びます。
バルク編成は、複数のエンティティで同じ操作を編成するプロセスです。たとえば、複数ユーザーの組織を更新する場合にバルク編成を送信できます。その結果、すべてのエンティティに対する操作が1回のコールで実行されます。
編成は、ステージと呼ばれる事前に定義されたステップに分割されます。すべての操作は、終了処理に到達するまで、これらのステージを移動します。編成には次のステージがあります。
検証: 編成パラメータの整合性など、編成に対する検証を実行するステージ。編成パラメータは、編成操作を実行するために必要なデータです。
前処理: 編成パラメータ操作の実行、承認の取得または職務の分離チェックを実行するステージ。
アクション: アクションを実行するステージ。
監視: 操作の監視が実行されるステージ。
後処理: 現行の操作に関連する結果としての操作が実行されるステージ。結果としての操作には、自動ロール・メンバーシップや、ユーザー作成に対するポリシー評価があります。
終了処理: クリーン・アップを実行する、プロセスの最後のステージ。
実行される各操作には、ユーザーやその他のエンティティに影響を及ぼすものもあります。たとえば、ユーザーを作成するとそのユーザーに対するリソースのプロビジョニングが発生し、新規パスワード・ポリシーを作成すると特定のユーザー・パスワードが無効になって次のログイン時に変更を要求される場合があります。結果としての各操作は編成として表されます。遅延された結果としての処理は、現行の編成の終了処理の前に実行されます。即時結果は、現行のイベント・ハンドラが戻された直後、現行の編成の次のイベント・ハンドラに進む前に実行されます。ユーザーの作成、変更、削除、有効化、無効化、ロック、ロック解除などのいくつかの操作の結果は、後続の項に示すとおり、イベント・ハンドラを作成することによってカスタマイズできます。
後処理ステージが開始点となる編成もあります。信頼できるソースからユーザーを調整する場合や、ユーザーをバルク・ロードしてこのデータをそのままOracle Identity Managerに追加する場合です。データがOracle Identity Managerにある場合は、ユーザーに対する後処理操作を実行し、自動グループ・メンバーシップの計算やポリシーの評価ができます。その結果、リコンシリエーション・エンジンやバルク・ロード・ユーティリティによって後処理専用の編成が送信されます。
イベント・ハンドラ は、様々なステージで編成に登録されるコードです。これらのイベント・ハンドラは、関連する編成ステージが実行されたときに起動されます。イベント・ハンドラは、同期がとられる場合と非同期の場合があります。同期イベント・ハンドラはすぐにレスポンスを返しますが、非同期イベント・ハンドラは後のステージで完了します。イベント・ハンドラは条件付きにすることができ、これは、特定の条件が満たされた場合に実行されることを意味します。
編成の各ステージにおける処理は、そのステージに配置されているブランチおよびイベント・ハンドラ(存在する場合)によって決定されます。ステージにブランチがある場合は、イベント・ハンドラからのレスポンスによって、使用するブランチが決まります。ステージにイベント・ハンドラがない場合、またはイベント・ハンドラからのレスポンスに推奨パスがない場合、操作はデフォルトのパスに従って次のステージに移ります。ただし、イベント・ハンドラが無効な場合や取り消された場合、プロセスは帯域外ステージに移ることができます。次のステージがあります。
無効: 編成の検証に失敗した場合、プロセスはこのステージに移ります。
拒否: 前処理イベント・ハンドラが拒否された場合、プロセスはこのステージに移ります。たとえば、承認者によって承認が却下された場合、編成は拒否されます。
取消し: 取消しメソッドをコールすることによって操作が停止された場合、プロセスはこのステージに移ります。
補正: 補正メソッドをコールすることによって操作がロールバックされた場合、プロセスはこのステージに移ります。
図28-1に、様々な編成ステージを示します。
Oracle Identity Managerを使用すると、編成操作の起動のカスタマイズするためにService Provider Interfaces (SPI)を実装できます。エンティティ編成の操作でサポートされるのは、前処理、後処理、検証および終了処理ステージのカスタマイズのみです。
イベント・ハンドラの実装の例を次に示します。
ユーザーの作成時、アカウントのステータス(有効または無効)が同じルールに基づいて設定されます。これを実行するために前処理イベント・ハンドラを実装できます。
契約者というタイプのユーザーを作成するときは、このユーザーに電子メール・アドレスが必要です。その他のユーザーは、電子メール・アドレスがなくても作成できます。ユーザーが契約者かどうかを検証する場合に検証イベント・ハンドラを使用でき、検証結果に基づいてユーザー作成を許可または禁止します。
エージェントというタイプのユーザーを作成した後に、このユーザーの代替電子メール・アドレスで通知を受け取るようにします。これは、後処理イベント・ハンドラを実装することによって実行できます。
後処理イベント・ハンドラは、ビジネス要件を満たすために最も一般的に実装されます。後処理イベント・ハンドラの実装によって特定の要件を満たすことができる例を次に示します。
要件
エンタープライズ・ユーザーが契約者の場合、Oracle Identity Managerでユーザーを作成した後、ユーザーは、外部アプリケーションである契約者登録システムに登録される必要があります。これはデータベース・アプリケーションです。データベースには、ユーザーのユーザーID、契約者ID、名、姓の各属性を格納する構造があります。正常に登録された後は、Oracle Identity Managerのユーザー・プロファイルでユーザーの契約者IDが取得され、更新される必要があります。
解決策
このユースケースはプラグインとして開発でき、Oracle Identity Managerにデプロイできます。プラグインは、契約者IDや指定したデータベース表からの構成済の列名の取得、およびOracle Identity Managerでのユーザー・プロファイルの更新に使用できます。後処理イベント・ハンドラは、ユーザー・エンティティの作成操作用に実装および登録できます。これは、条件付きのイベント・ハンドラで、タイプが契約者であるユーザーに対してのみ実行されます。ユーザー・タイプが契約者の場合、イベント・ハンドラは外部アプリケーションに接続し、Oracle Identity ManagerのユーザーIDに基づいて契約者IDを取得し、契約者IDを使用してOracle Identity Managerでユーザー・プロファイルを更新します。
次に、イベント・ハンドラの後処理実装の例をもう1つ示します。
Oracle Identity Managerでリコンサイルされるデータが、すべてのユースケースを実装するには不十分で、リコンサイルしたデータに基づいて追加の属性を生成する必要がある場合のカスタム属性の生成です。これは、特にカスタム属性がロール・メンバーシップ・ルールまたはアクセス・ポリシーで使用される場合に一般的なユースケースです。
イベント・ハンドラは、次のもので構成されます。
Javaコード: 操作の実装
XML定義: 適切なステージでの関連する編成との関連付け
プラグイン定義: Oracle Identity Managerプラグイン・フレームワークへのイベント・ハンドラおよび拡張コードの登録
カスタム・イベント・ハンドラの開発では、Javaコードを使用した操作の実装、XML定義の記述、プラグインの作成と登録が行われます。これについて次の項で説明します。
この項では、SPIの実装によるJavaコードの作成と、JARファイルの作成方法について説明します。
カスタム・イベント・ハンドラを作成する際、次の事項を考慮する必要があります。
カスタム・イベント・ハンドラを登録できる編成ステージは、検証、前処理および後処理です。
検証、前処理および後処理イベント・ハンドラは条件付きにできます。これは、特定の条件が満たされた場合にのみイベント・ハンドラが実行されるという意味です。
イベント・ハンドラを条件付きにするには、oracle.iam.platform.kernel.spi.ConditionalEventHandlerインタフェースとそのisApplicableメソッドを実装します。このメソッドでは、コンテキスト・データと編成パラメータが使用可能です。条件付きイベント・ハンドラの場合、操作の開始時にイベント・ハンドラの適用性が計算されます。したがって、編成フローの中でコンテキストまたは編成パラメータが変更されると、実行してはいけないイベント・ハンドラが実行される場合があります。
イベント・ハンドラは、単一のエンティティもバルク・エンティティも処理できます。
イベント・ハンドラは、親ハンドラでの特定の操作をコールバックする、関連付けられた失敗ハンドラを持つことができます。
イベント・ハンドラの再試行がサポートされているため、イベント・ハンドラはリエントラントです。
リコンシリエーションによって後処理編成が送信される場合、バルク編成が送信されます。イベント・ハンドラに対するbulkExecuteメソッドは、これらの編成に対してコールされます。したがって、必ずこのメソッドを実装してください。
カスタム・イベント・ハンドラ間でデータが渡される場合は、イベント間データを使用して渡すことができます。編成に対してgetInterEventData()メソッドをコールすると、ハッシュマップが返されます。このマップでは、カスタムで始まるキーを持つオブジェクトを配置でき、後続のカスタム・ハンドラでこのデータにアクセスできます。同じハッシュマップに含まれる事前定義されたイベント間データは変更または削除しないでください。
書込みまたは削除操作のためにイベント・ハンドラ内部でAPIコールを行うには、Platform.getServiceForEventHandlersメソッドを使用してAPIサービスを取得します。このメソッドを使用して取得したサービスを使用して行われたAPIコールは、後処理を含め、同期をとって実行されます。
検証ハンドラを除くイベント・ハンドラの戻りタイプを次の表に示します。
イベント・ハンドラのタイプ | 成功時 | 失敗時 |
---|---|---|
同期 |
executeメソッドの新規EventResult()と、バルク・バージョンのexecuteメソッドの新規BulkEventResult() |
EventFailedException |
非同期 |
nullを返します |
EventFailedException |
表28-1に、様々な編成ステージで実装できるメソッドを示します。
表28-1 イベント・ハンドラを実装するためのメソッド
メソッド | 適用可能な編成ステージ | 説明 |
---|---|---|
initialize |
前処理、後処理 |
このメソッドは、接続を開き、状態またはリソースをプールするために使用します。 |
execute for single entity |
前処理、後処理 |
このメソッドは、基礎となる操作の入力属性を読み取り、(必要に応じて)別の値に更新する場合に使用します。 |
execute for bulk orchestration |
前処理、後処理 |
このメソッドは、基礎となる複数の操作の入力属性を読み取り、(必要に応じて)別の値に更新する場合に使用します。 |
isApplicable |
条件付き |
このメソッドは、条件付きハンドラで、イベント・ハンドラ実行の前提条件が満たされるかどうかを判別するために使用します。 |
validate |
validation |
このメソッドは、検証ハンドラで入力データを検証する場合に使用します。 |
cancel |
前処理、後処理 |
このメソッドは、編成操作が取り消される場合にコールされます。 |
compensate |
前処理、後処理 |
このメソッドは、編成操作が補正される場合にコールされます。 |
executeなどのメソッドでは、次の引数値が使用可能です。
トラブルシューティングのためにコードに含めることができるID:
プロセスID: 編成インスタンスのID
イベントID: イベント・ハンドラ・インスタンスのID
基礎となるエンティティ・インスタンスの詳細情報で構成される編成オブジェクト。次のもので構成されます。
基礎となるエンティティの入力属性の読取り元となるENTITY_ATTRIBUTE、VALUEを含むマップ(キー値ペア)。
エンティティID: 同じエンティティまたは異なるエンティティの値を元に戻すには、エンティティ・マネージャAPIを使用して、エンティティIDおよびデータを渡します。バルク編成の場合、複数のエンティティIDとマップを取得します。
注意: Platform.getServiceForEventHandlersを使用して、イベント・ハンドラで作成、更新および削除操作をコールするサービスを取得します。 |
この項では、様々な種類のイベント・ハンドラを作成する方法を説明するコード例を示します。
例1: カスタム電子メール検証
例28-1に、ユーザーの電子メールIDにアンパサンド(@)が使用されていることを確認するカスタム検証ハンドラのコード例の一部を示します。
例28-1 カスタム電子メール検証
public void validate(long processId, long eventId, Orchestration orchestration) throws ValidationException, ValidationFailedException { HashMap<String, Serializable> parameters = orchestration.getParameters(); String email = (parameters.get("Email") instanceof ContextAware) ? (String) ((ContextAware) parameters .get("Email")).getObjectValue() : (String) parameters .get("Email"); if (!(email.contains("@"))) { throw new ValidationFailedException("Email doesn't contain @"); } }
例2: ミドル・ネームを設定するカスタム前処理イベント・ハンドラ
例28-2に、ミドル・ネームに値が指定されていない場合に、ミドル・ネームを名の最初の文字に設定するカスタム前処理イベント・ハンドラのコード例の一部を示します。
例28-2 ミドル・ネームを設定するカスタム前処理イベント・ハンドラ
// 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 ((middleName == null) || middleName.equals("")) { 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) { if(parameters.containsKey(key)){ String value = (parameters.get(key) instanceof ContextAware) ? (String) ((ContextAware) parameters .get(key)).getObjectValue() : (String) parameters.get(key); return value; } else{ return null; } }
例3: リソース・オブジェクトをプロビジョニングするカスタム後処理イベント・ハンドラ
例23-3に、ロールがROLE 00.5であるユーザーにリソース・オブジェクトOBJ005をプロビジョニングするカスタム後処理イベント・ハンドラのコード例の一部を示します。
例28-3 カスタム後処理イベント・ハンドラの例
// 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; }
例4: bulkExecuteメソッドを使用するカスタム・ユーザー後処理イベント・ハンドラ
例28-4に、バルク・ユーザー作成編成に含まれるユーザーをループする方法を示します。
例28-4: bulkExecuteメソッドを使用するカスタム・ユーザー後処理イベント・ハンドラ
public BulkEventResult execute(long processId, long eventId, BulkOrchestration orchestration){ HashMap<String, Serializable>[] orchParamArray = orchestration.getBulkParameters(); // Array of user keys String [] entityIds = orchestration.getTarget().getAllEntityId(); for(int i=0; i< entityIds.length; i++){ } }
例5: isApplicableメソッドでのコンテキストの使用
Oracle Identity Managerでの操作は、複数のコンテキストで実行できます。たとえば、ユーザーの作成は、管理者がユーザーをダイレクト操作として作成する場合、管理者がリクエストを送信することによってユーザーを作成する場合、自己登録によってユーザーを作成する場合、および信頼できるソース・リコンシリエーションによってユーザーを作成する場合という4つのコンテキストで発生する可能性があります。これらのすべてのシナリオで、Oracle Identity Managerは、同じデータ型で、同じパラメータ名と値を持つ、同じユーザー作成編成を送信します。
例28-5には、イベント・ハンドラの適応性を示すためにこの操作を実行するコンテキストの検出方法を示します。
例28-5 isApplicableメソッドでのコンテキストの使用
public boolean isApplicable(AbstractGenericOrchestration orchestration) { // Request Context if (ContextManager.getContextType() == ContextTypes.REQUEST) { } // Recon context if (ContextManager.getContextType() == ContextTypes.RECON) { } }
カスタム・イベント・ハンドラ・コードを使用してJARを作成するには:
表28-2に示すSPIのいずれかを実装して、カスタム前処理、後処理または検証ハンドラを作成します。
表28-2 カスタム・イベント・ハンドラを作成するためのSPI
ステージ | 実装するSPI |
---|---|
前処理 |
oracle.iam.platform.kernel.spi.PreProcessHandler |
後処理 |
oracle.iam.platform.kernel.spi.PostProcessHandler |
検証 |
oracle.iam.platform.kernel.spi.ValidationHandler |
終了処理 |
oracle.iam.platform.kernel.spi.FinalizationHandler |
カスタム・クラスをコンパイルするクラス・パスに次のJARファイルを含めます。
OIM_ORACLE_HOME/server/platform/ディレクトリから:
iam-platform-kernel.jar
iam-platform-utils.jar
iam-platform-context.jar
iam-plaftorm-authz-service.jar
OIM_ORACLE_HOME/designconsole/lib/ディレクトリから:
oimclient.jar
xlAPI.jar
コンパイルに他のOracle Identity Manager JARファイルが必要な場合は、この手順に示すディレクトリにあります。
カスタム・クラスのJARファイルを作成します。
イベント・ハンドラの例外処理では、条件付きのJAVA例外処理メソッドを使用する必要があります。失敗時の処理には次のガイドラインを参照してください。
イベント・ハンドラ・コードで、失敗を示す適切な引数を指定してEventFailedExceptionをスローします。
失敗は、失敗ハンドラを登録することによって処理できます。失敗ハンドラの一部として、失敗を修正するために必要なロジックを実装できます。失敗ハンドラは、レスポンスとして次のオプションを持つFailedEventResultを返す必要があります。
CANCEL: 操作を取り消す必要があることを示します。これまでに実行され完了したすべてのイベント・ハンドラに対するCancelメソッドは、カーネルによって実行とは逆の順にコールされます。
COMPENSATE: 操作をロールバックする必要があることを示します。これまでに実行され完了したすべてのイベント・ハンドラに対するCompensateメソッドは、カーネルによって実行とは逆の順にコールされます。
MANUAL_COMPLETE: 失敗したハンドラは手動で完了され、残りのイベント・ハンドラが処理されることを示します。
RETRY: 失敗したイベント・ハンドラを再試行する必要があることをカーネルに示します。
NULL: 失敗したハンドラによるレスポンスや推奨がないことを示します。
この項では、イベント・ハンドラXMLファイル内の、一部の要素および要素の属性について説明します。また、イベント・ハンドラXML定義の必須の名前空間についても説明します。
要素
イベント・ハンドラXMLファイルのトップレベル(親)要素は、eventhandlers
です。表28-3に、eventhandlers
親要素内に一般的に定義されるサブ要素を示します。
表28-3 eventhandlers要素内の一般的なサブ要素
サブ要素 | 説明 |
---|---|
|
編成に対して実行される検証を識別します。 |
|
前処理、後処理およびアクション・ステージで実行される操作を識別します。 |
|
デフォルトのフローでイベント・ハンドラが失敗した場合に実行されるイベント・ハンドラを識別します。 |
|
編成の最後に実行されるイベント・ハンドラを識別します。終了処理は、編成の最後のステージです。 |
|
影響の編成が失敗した場合に親編成で実行されるイベント・ハンドラを識別します。 |
|
拒否や取消しなどの帯域外編成フローのイベント・ハンドラを定義します。 |
|
編成の補正フローで実行されるイベント・ハンドラを識別します。 |
要素の属性
イベント・ハンドラXMLファイル内の要素には、属性が含まれています。表28-4に、要素内に一般的に定義される属性を示します。
表28-4 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属性は、イベント・ハンドラが独自のトランザクションで実行されるかどうかを示します。サポートされている値は、TRUEまたはFALSEです。デフォルト値はFALSEです。 |
<eventhandlers>要素の名前空間要件
すべてのイベント・ハンドラ定義には、次の必須名前空間定義が必要です。
<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">
表28-4に示す、すべてのカスタム・イベントの定義を含むメタデータXMLファイルを作成します。
例28-6 カスタム・イベント定義のサンプル・メタデータXMLファイル
<?xml version='1.0' encoding='utf-8'?> <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"> <!-- Custom preprocess event handlers --> <action-handler class="oracle.oim.extensions.preprocess.SamplePreprocessExtension" entity-type="User" operation="CREATE" name="SetUserMiddleName" 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="CustomResourceProv" stage="postprocess" order="1000" sync="TRUE"/> <!-- Custom validation event handlers --> <validation-handler class="oracle.oim.extensions.validation.SampleValidationExtension" entity-type="User" operation="CREATE" name="ValidateUserEmail" order="1000"/> </eventhandlers>
カスタム・イベント・ハンドラを含むプラグインを作成するには、適切なイベント・ハンドラ・クラスを開発する必要があります。プラグインおよびプラグイン・ポイントの詳細は、「プラグインの開発」を参照してください。
プラグインZIPを作成して登録するには:
イベント・ハンドラ・プラグイン・ポイントを含むプラグインXMLを定義します。
注意: プラグイン定義で使用されるプラグイン・ポイントがoracle.iam.platform.kernel.spi.EventHandlerに設定されていることを確認してください。 |
プラグイン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およびJARファイルをプラグインZIPファイルにパッケージ化します。
「カスタム・イベント定義XMLの定義」に示す情報を使用して定義されたイベント・ハンドラXMLを同じzipのMETA-INFというディレクトリにパッケージ化します。
プラグイン登録ユーティリティを使用してプラグインを登録します。追加情報については、「プラグインの登録」を参照してください。
デプロイおよび登録したカスタム・イベント・ハンドラのリストは、Oracle Enterprise Managerを使用して表示できます。イベント・ハンドラは、起動順に表示されます。このイベント・ハンドラのリストを使用すると、イベント・ハンドラの実行順序を指定できます。
カスタム・イベント・ハンドラの順序を指定するには、既存のイベント・ハンドラのリストと特定の操作におけるその順序を把握している必要があります。そのためには、次の手順を実行して、Enterprise ManagerからMBeanを起動する必要があります。
Enterprise Managerにログインします。
左側にあるナビゲーション・ペインで、「WebLogicドメイン」を展開して「OIM DOMAIN」を選択します。
ドメイン名を右クリックして、「システムMBeanブラウザ」を選択します。
「アプリケーション定義のMBean」でoracle.iamを展開します。
「OIM_SERVER_NAME」、「oim」、「IAMAppDesignMBean」、「ConfigQueryMBeanName」の順にナビゲートします。
「操作」タブをクリックします。
getEventHandlersメソッドをクリックします。
p1パラメータのエンティティ名およびp2パラメータの操作名を指定して、「起動」をクリックします。パラメータ値は大/小文字を区別しません。指定可能なパラメータ値は次のとおりです。
エンティティ名: 値は、User、RoleまたはRoleUserのいずれかです。
操作: 値は、CREATE、MODIFYまたはDELETEのいずれかです。
承認者は、リクエストを承認する前に属性値を更新できます。承認者が入力したデータの清浄化を保証するために、承認者がリクエストを更新したときに、Oracle Identity Managerは再度検証ハンドラを起動します。これは、リクエストが送信され、承認者が承認ワークフローでそのリクエストを変更した場合に、特定のエンティティおよび操作用に構成された検証ハンドラが1つのリクエスト・フローの中で複数回起動されることを意味します。
たとえば、自己登録リクエストが送信されると、USER CREATE用に構成された一連の検証ハンドラが実行されます。次に、承認者が組織またはその他のユーザー属性を移入するようにリクエストを変更すると、これらの検証ハンドラが再実行されます。
したがって、カスタム検証ハンドラは1つのリクエスト・フローで複数回起動されることから、このカスタム検証ハンドラはリエントラントな検証ロジックで開発される必要があります。
次のサンプル・ユースケースについて考えてみます。
部門番号フィールドの値にランダムな番号を付与して、HR Employee Number UDFを生成する必要があります。ユーザー作成リクエストまたは自己登録リクエストが送信されると、カスタム・ロジックに基づいてHR Employee Number UDFが自動的に生成されます。承認者が承認時にリクエストを編集し、部門番号の値を変更すると、部門番号に割り当てられた新しい値を使用して、HR Employee Number UDFが再計算される必要があります。ただし、承認者が部門番号を変更しなかった場合は、リクエストの送信時に生成された以前の値が使用されます。
このため、部門番号とランダムな番号を付与することによってHR Employee Number UDFを生成するための新しい検証ハンドラを開発する必要があります。前処理ハンドラがリクエストのライフサイクルで起動されるのは1回だけであるため、このロジックを前処理ハンドラで作成することはできません。この検証ハンドラのロジックを次に示します。
package custom.handlers; import java.io.Serializable; import java.util.HashMap; import java.util.Random; import oracle.iam.identity.usermgmt.api.UserManagerConstants; import oracle.iam.identity.utils.Utils; import oracle.iam.platform.kernel.ValidationException; import oracle.iam.platform.kernel.ValidationFailedException; import oracle.iam.platform.kernel.spi.ValidationHandler; import oracle.iam.platform.kernel.vo.BulkOrchestration; import oracle.iam.platform.kernel.vo.Orchestration; public class EmployeeNumberGenerationHandler implements ValidationHandler { @Override public void initialize(HashMap<String, String> parameters) { } @Override public void validate(long processId, long eventId, Orchestration orchestration) throws ValidationException, ValidationFailedException { HashMap<String, Serializable> contextParams = orchestration.getParameters(); //1. Generate UDF Employee number during request submission as Department Number and a random number //2. If request is in approval stage, then control has come here since approver has modified the request //2a: Check if approver has modified Department Number. If yes, then re-generate if( !Utils.isRequestInApprovalStage()) //Utility method to find if request is in approval stage or not? If it returns true, it means that approver is attempting to update the request during approval { //Step 1: String dept = contextParams.get(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()).toString(); String en = dept+"_"+random(); contextParams.put("SSN", en); } else { String dept = contextParams.get(UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()).toString(); //compare with department number with which request was submitted, if modified by approver; the regenerate SSN if( Utils.isAttributeModifiedByApprover(orchestration , UserManagerConstants.AttributeName.DEPARTMENT_NUMBER.getId()) ) // //Utility method to find if approver has edited the particular attribute or not , during approval? { String en = dept+"_"+random(); contextParams.put("SSN", en); } } } private String random() { Random random = new Random(); String randomStr = "" + random.nextLong(); randomStr = randomStr.replaceAll("-", ""); return randomStr; } @Override public void validate(long processId, long eventId, BulkOrchestration orchestration) throws ValidationException, ValidationFailedException { } }
イベント・ハンドラを開発して実装する前に、操作を分析することをお薦めします。操作用のプラグインがサポートされている場合は、イベント・ハンドラを開発するのではなく、プラグインを使用してカスタマイズします。たとえば、ユーザー名の生成は、使用可能なプラグインを使用して実装する必要があり、ユーザーの作成編成でイベント・ハンドラとして作成しようとしないでください。
イベント・ハンドラの開発における考慮事項については、「開発に関する考慮事項」を参照してください。
デプロイメント・マネージャでは、Oracle Identity Managerのデプロイメント間でのプラグインおよびプラグインに登録されたイベント・ハンドラの移行をサポートしています。たとえば、イベント・ハンドラをテスト環境で実装した後、デプロイメント・マネージャを使用して本番環境に移行することができます。図28-2に、デプロイメント・マネージャを使用したプラグインのエクスポートを示します。
表28-5に、一般的な問題、および操作の実行時にイベント・ハンドラがトリガーされなかった場合のトラブルシューティングに役立つ原因と解決策を示します。
表28-5 イベント・ハンドラのトラブルシューティング
問題 | 原因/解決策 |
---|---|
リコンシリエーションによってユーザーを作成すると、カスタム前処理イベント・ハンドラはトリガーされません。 |
開始ステージが後処理の場合、リコンシリエーションは後処理のみの編成を送信します。 |
リコンシリエーションによってユーザーを作成すると、カスタム後処理イベント・ハンドラはトリガーされますが、実行メソッドのロジックはトリガーされません。 |
リコンシリエーションはバルク編成を送信します。したがって、必ずbulkExecuteメソッドを実装してください。 |
編成操作の完了に非常に長い時間がかかります。 |
イベント・ハンドラごとにかかる時間を確認します。
|
注意: この項は、Oracle Identity Manager Release 9.xのイベント・ハンドラにのみ該当します。編成に基づくイベント・ハンドラについては、前の項を参照してください。 |
Design Consoleの「開発ツール/ビジネス・ルール定義」フォルダでは、システム管理者および開発者がOracle Identity Managerのイベント・ハンドラおよびデータ・オブジェクトを管理するツールが提供されます。
このフォルダには、次のフォームが含まれます。
イベント・ハンドラ・マネージャ: このフォームでは、Oracle Identity Managerで使用されるイベント・ハンドラを作成および管理できます。詳細は、「「イベント・ハンドラ・マネージャ」フォーム」を参照してください。
データ・オブジェクト・マネージャ: このフォームでは、データ・オブジェクトを定義し、そのオブジェクトにイベント・ハンドラとアダプタを割り当て、関連するアダプタ変数をマップできます。詳細は、「「データ・オブジェクト・マネージャ」フォーム」を参照してください。
このフォームは、「開発ツール/ビジネス・ルール定義」フォルダに表示されます。このフォームを使用して、ユーザー定義またはシステム生成のアクション(またはイベント)を処理するJavaクラスを管理します。これらのクラスはイベント・ハンドラと呼ばれます。新規イベント・ハンドラをOracle Identity Managerに追加する場合は、Oracle Identity Managerで認識されるようにするために、最初にそのイベント・ハンドラをここで登録する必要があります。
イベント・ハンドラには次の2種類があります。
「アダプタ・ファクトリ」フォームを使用して作成されるイベント・ハンドラ。名前の先頭の文字はadp
です。これらはアダプタと呼ばれます。
Oracle Identity Managerで内部的に作成されるイベント・ハンドラ。名前の先頭の文字はtc
です。これらは、システム・イベント・ハンドラと呼ばれます。
「イベント・ハンドラ・マネージャ」フォームを使用して、Oracle Identity Managerによりいつイベント・ハンドラがトリガーされるかを指定できます。イベント・ハンドラの実行は、次のようにスケジュールできます。
挿入前: 情報がデータベースに追加される前
更新前: 情報がデータベース内で更新される前
削除前: 情報がデータベースから削除される前
挿入後: 情報がデータベースに追加された後
更新後: 情報がデータベース内で更新された後
削除後: 情報がデータベースから削除された後
図28-3に、「イベント・ハンドラ・マネージャ」フォームを示します。
表28-6に、「イベント・ハンドラ・マネージャ」フォームのフィールドの説明を示します。
表28-6 「イベント・ハンドラ・マネージャ」フォームのフィールド
フィールド名 | 説明 |
---|---|
イベント・ハンドラ名 |
イベント・ハンドラの名前。 |
パッケージ |
イベント・ハンドラが属するJavaパッケージ。 |
挿入前 |
このチェック・ボックスを選択すると、データベースに情報が追加される前に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
更新前 |
このチェック・ボックスを選択すると、データベースで情報が変更される前に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
削除前 |
このチェック・ボックスを選択すると、データベースから情報が削除される前に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
挿入後 |
このチェック・ボックスを選択すると、データベースに情報が追加された後に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
更新後 |
このチェック・ボックスを選択すると、データベースで情報が変更された後に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
削除後 |
このチェック・ボックスを選択すると、データベースから情報が削除された後に、Oracle Identity Managerによってイベント・ハンドラがトリガーされます。 |
注意 |
イベント・ハンドラに関する追加情報。 |
次の各項では、イベント・ハンドラの作成および変更の方法について説明します。
注意: イベント・ハンドラを使用するには、「データ・オブジェクト・マネージャ」フォームを使用して、イベント・ハンドラをデータ・オブジェクトにアタッチする必要があります。イベント・ハンドラのデータ・オブジェクトへの割当ての詳細は、「「データ・オブジェクト・マネージャ」フォーム」を参照してください。 |
注意: 名前の先頭の文字が |
イベント・ハンドラの追加または変更
イベント・ハンドラを追加または変更するには、次の手順を実行します。
「イベント・ハンドラ・マネージャ」フォームを開きます。
Oracle Identity Managerにイベント・ハンドラを追加するには、「イベント・ハンドラ名」参照フィールドにイベント・ハンドラの名前を入力します。
イベント・ハンドラを変更するには、「イベント・ハンドラ名」参照フィールドをダブルクリックします。
表示される「参照」ダイアログ・ボックスで、編集するイベント・ハンドラを選択します。
パッケージ・フィールドで、イベント・ハンドラがそのメンバーであるJavaパッケージの名前を追加または編集します。
どの時点でOracle Identity Managerによりイベント・ハンドラをトリガーするかに応じて、該当するチェック・ボックスを選択します。
イベント・ハンドラは、挿入前、更新前、削除前、挿入後、更新後および削除後に実行されるようにスケジュールできます。
注意: チェック・ボックスを選択しても、イベント・ハンドラがその時点で(たとえば挿入前に)トリガーされるわけではありません。これは、その時点でのイベント・ハンドラの実行が可能であることを意味しています。 |
「注意」領域で、イベント・ハンドラに関する説明を追加または編集します。
「保存」をクリックします。
イベント・ハンドラが追加または編集されます。
「データ・オブジェクト・マネージャ」フォームは、「開発ツール/ビジネス・ルール定義」フォルダに表示されます。このフォームを使用して、次の操作を実行できます。
データベースのデータを追加、変更または削除できるオブジェクトに、ルール・ジェネレータ・アダプタ、エンティティ・アダプタまたはイベント・ハンドラを割り当てます。このタイプのオブジェクトは、データ・オブジェクトと呼ばれます。
スケジュール(挿入前、更新前、削除前、挿入後、更新後または削除後)に従って実行されるように、アダプタまたはイベント・ハンドラのスケジュールを設定します。
同じ実行スケジュールに属するアダプタまたはイベント・ハンドラが、Oracle Identity Managerによってトリガーされる順序を調整します。
現在のデータ・オブジェクトを追加、変更および削除できるユーザー・グループを表示します。
アダプタ変数を適切なソースの場所およびターゲットの場所にマップします。
図28-4に、「データ・オブジェクト・マネージャ」フォームを示します。
表28-7に、「データ・オブジェクト・マネージャ」フォームのフィールドの説明を示します。
表28-7 「データ・オブジェクト・マネージャ」フォームのフィールド
フィールド | 説明 |
---|---|
フォームの説明 |
データ・オブジェクトに関連付けられているフォームの名前。 |
データ・オブジェクト |
イベント・ハンドラ、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタを割り当てるデータ・オブジェクトの名前。 |
次の項では、ルール・ジェネレータ・アダプタ、エンティティ・アダプタまたはイベント・ハンドラを割り当てるターゲット・データ・オブジェクトの選択方法について説明します。
ターゲット・データ・オブジェクトの選択
ターゲット・データ・オブジェクトを選択するには、次の手順を実行します。
「データ・オブジェクト・マネージャ」フォームを開きます。
フォームの説明フィールドをダブルクリックします。
表示される「参照」ダイアログ・ボックスで、イベント・ハンドラ、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタを割り当てるデータ・オブジェクトに関連付けられているフォームの名前を選択します。
フォームを選択すると、対応するデータ・オブジェクトの名前がデータ・オブジェクト・フィールドに表示されます。
「保存」をクリックします。
ターゲット・データ・オブジェクトが選択されます。これで、ルール・ジェネレータ・アダプタ、エンティティ・アダプタおよびイベント・ハンドラを割り当てられるようになりました。
「データ・オブジェクト・マネージャ」フォームを起動してターゲット・データ・オブジェクトを選択すると、このフォームのタブが使用できるようになります。
「データ・オブジェクト・マネージャ」フォームには、次のタブが含まれます。
ハンドラのアタッチ、アダプタのマップ
それぞれのタブについて、次の各項で説明します。
このタブを使用して、データ・オブジェクトに割り当てるか、データ・オブジェクトから削除するルール・ジェネレータ・アダプタ、エンティティ・アダプタまたはイベント・ハンドラを選択します。次の情報が含まれます。
割り当てられたイベント・ハンドラまたはアダプタが、Oracle Identity Managerによって(挿入前、更新前、削除前、挿入後、更新後または削除後の)いつトリガーされるかを指定します。同じ実行スケジュールに属するアダプタまたはイベント・ハンドラがOracle Identity Managerによってトリガーされる順序を設定します。
イベント・ハンドラ、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタをOracle Identity Managerによってトリガーする必要がなくなった場合は、データ・オブジェクトからそれを削除する必要があります。
たとえば、adpCONVERTTOLOWERCASE
、adpSOLARISHMDSTRINGGEN
、adpSETSOLARISASSET
およびadpSETPASSWORDFROMMAIN
の各アダプタが、挿入前にOracle Identity Managerによってトリガーされるとします。これらのアダプタの順序番号に基づき、Oracle Identity Managerは、まずadpCONVERTTOLOWERCASE
アダプタをトリガーし、それからadpSOLARISHMDSTRINGGEN
、adpSETSOLARISASSET
およびadpSETPASSWORDFROMMAIN
アダプタの順にトリガーします。
注意: 現在のデータ・オブジェクトを追加、変更および削除できるユーザー・グループを表示するには、権限の挿入、「権限の更新」または権限の削除の各タブをそれぞれクリックします。 |
次の各項では、これらの手順について説明します。
データ・オブジェクトへのイベント・ハンドラ、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタの割当て。イベント・ハンドラまたはアダプタの実行スケジュールの構成。データ・オブジェクトからのイベント・ハンドラ、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタの削除。
イベント・ハンドラまたはアダプタを割り当てるには、次の手順を実行します。
アダプタまたはイベント・ハンドラをいつトリガーするかに応じて、該当する「データ・オブジェクト・マネージャ」フォームのタブを選択します。
たとえば、挿入前にOracle Identity Managerでアダプタをアクティブ化する場合は、挿入前タブを選択します。
選択したタブで、「割当て」をクリックします。
「割当て」ダイアログ・ボックスが表示されます。
イベント・ハンドラまたはアダプタを選択し、データ・オブジェクトに割り当てます。
「OK」をクリックします。
イベント・ハンドラまたはアダプタがデータ・オブジェクトに割り当てられます。
実行スケジュールを構成するには、次の手順を実行します。
実行スケジュールを変更するイベント・ハンドラまたはアダプタを選択します。
「割当て」をクリックします。
「割当て」ダイアログ・ボックスが表示されます。
イベント・ハンドラまたはアダプタを選択します。
上をクリックすると、選択したイベント・ハンドラまたはアダプタの位置と順序番号が、その前のイベント・ハンドラまたはアダプタと入れ替わります。
下をクリックすると、選択したイベント・ハンドラまたはアダプタの位置と順序番号が、その次のイベント・ハンドラまたはアダプタと入れ替わります。
すべてのイベント・ハンドラとアダプタの順序番号が適切に設定されるまで、手順3と4を繰り返します。
「OK」をクリックします。
イベント・ハンドラおよびアダプタは、実行スケジュールまたは独自に構成したスケジュールで正しい順序でトリガーされます。
アダプタのマップ・タブは、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタをデータ・オブジェクトに割り当てた後でのみ使用できます。
このタブを使用して、ルール・ジェネレータ・アダプタまたはエンティティ・アダプタの変数を、それぞれに適したソースの場所およびターゲットの場所にマップします。たとえば、adpSOLARISUSERIDGENERATOR
アダプタにfirstname、Adapter return valueおよびlastnameの3つの変数があるとします。各アダプタ変数のマップ済列にY
が表示されている場合は、3つの変数がすべて正しい場所にマップされており、アダプタのステータスが「準備完了」に変わります。
注意: アダプタのステータスは、次の3つのいずれかになります。
|
アダプタのコンパイルおよびアダプタ変数のマッピングの詳細は、第8章「アダプタ・ファクトリの使用」を参照してください。
注意: データ・オブジェクトにアダプタが割り当てられていない場合は、アダプタのマップ・タブは無効になります。 |