Oracle® Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発 11g リリース1(10.3.4) B61623-02 |
|
前 |
次 |
ロール・マッピングとは、実行時にプリンシパル(ユーザーまたはグループ)をセキュリティ・ロールに動的に割り当てるプロセスのことです。WebLogic Serverでは、ロール・マッピング・プロバイダは、WebLogicリソースを操作しようとしているサブジェクト内のプリンシパルに適用されるセキュリティ・ロールを調べます。通常、この操作ではWebLogicリソースへのアクセスを取得する必要があるので、ロール・マッピング・プロバイダは認可プロバイダと共に使用するのが一般的です。
以下の節では、ロール・マッピング・プロバイダの概念と機能、およびカスタム・ロール・マッピング・プロバイダの開発手順について説明します。
ロール・マッピング・プロバイダを開発する前に、以下の概念を理解しておく必要があります。
セキュリティ・ロールは、WebLogicリソースへの同じアクセス・パーミッションを持つユーザーまたはグループの集合です。グループと同様、セキュリティ・ロールを使用すると、複数のユーザーによるWebLogicリソースへのアクセスを一度に制御できます。ただし、セキュリティ・ロールはWebLogic Serverドメインの特定のリソースを対象としており(WebLogic Serverドメイン全体を対象とするグループとは異なります)、動的に定義することが可能です。「動的セキュリティ・ロール計算」を参照してください。
注意: セキュリティ・ロールの詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。WebLogicリソースの詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のセキュリティ・プロバイダとWebLogicリソースに関する項およびポリシーで保護できるリソースのタイプに関する項を参照してください。 |
weblogic.security.service
パッケージのSecurityRole
インタフェースは、セキュリティ・ロールの抽象的な記法を表すために用いられます(詳細については、WebLogic Server APIリファレンスJavadocのSecurityRoleインタフェースを参照してくさい。)
プリンシパルをセキュリティ・ロールにマップすると、そのプリンシパルがそのセキュリティ・ロールに割り当てられているかぎり、そのプリンシパルには定義されたアクセス許可が付与されます。たとえば、アプリケーションでAppAdmin
というセキュリティ・ロールを定義し、これによってそのアプリケーションのリソースのごく一部に対する書込みアクセスが提供されるものとします。この場合、AppAdmin
セキュリティ・ロールに割り当てられたプリンシパルはすべて、それらのリソースに対して書込みアクセス権を持つことになります。詳細は、「動的セキュリティ・ロール計算」と『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。
なお、多数のプリンシパルを単一のセキュリティ・ロールにマップすることができます。プリンシパルの詳細は、「ユーザー/グループ、プリンシパル、サブジェクト」を参照してください。
セキュリティ・ロールの指定は、Java EEデプロイメント記述子ファイルかWebLogic Server管理コンソール、あるいはその両方で行われます。詳細については、「ロール・マッピング・プロバイダとデプロイメント記述子の管理」を参照してください。
セキュリティ・ロールは、宣言的なもの(すなわち、Java Enterprise Editionにおけるロール)とすることも、リクエストのコンテキストに基づいて動的に計算することもできます。
動的セキュリティ・ロール計算とは、このようにプリンシパル(ユーザーまたはグループ)を実行時にセキュリティ・ロールにレイト・バインドすることを意味する用語です。こうしたレイト・バインディングは、プリンシパル対セキュリティ・ロールの関連付けが静的に定義されるか動的に計算されるかによらず、保護対象WebLogicリソースについての認可判定の直前に行われます。バインディングが呼出しシーケンス内で行われるため、あらゆるプリンシパル対セキュリティ・ロール計算の結果は、リクエストに対して下される認可判定の一環として、認証用ID情報として解釈することができます。
こうしたセキュリティ・ロールの動的計算には非常に重要な利点があります。つまり、ビジネス・ルールに基づいてユーザーまたはグループをセキュリティ・ロールに関連付けることができるのです。たとえば、本来の管理者が長期の出張で不在の間のみ、ユーザーにManager
セキュリティ・ロールを割り当てることができます。このセキュリティ・ロールを動的に計算することで、そうした一時的な措置のためにアプリケーションを変更したり再デプロイしたりする必要はなくなります。さらに、本来の管理者が戻ってきたときに、その特別に付与した特権を忘れずに取り消す必要もありません。なお、ユーザーを一時的にManagers
グループに追加した場合には、その必要があるでしょう。
注意: 通常はWebLogic Server管理コンソールで利用できるロール条件を使用して、ユーザーまたはグループにセキュリティ・ロールを付与します。(このリリースのWebLogic Serverでは、カスタム・ロール条件は記述できません。)詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。 |
計算で得られたセキュリティ・ロールは、対象(利用可能であれば)のID情報やリクエストのパラメータ値など、リクエストのコンテキストを構成する様々な情報にアクセスすることができます。こうしたコンテキスト情報は通常、WebLogic Securityフレームワークで評価される式に含まれるパラメータの値として使用されます。この機能は、デプロイメント記述子またはWebLogic Server管理コンソールを通じて静的に定義されたセキュリティ・ロールの計算も担当します。
注意: 認証済みユーザーに対するセキュリティ・ロールの計算は、Java EE仕様で定義されているロール・ベース・アクセス制御(RBAC)によるセキュリティ機能を拡張したものです。動的なセキュリティ・ロール計算を作成するには、WebLogic Server管理コンソールでロール文を定義します。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。 |
WebLogic Securityフレームワークは、認可判定の一環として、セキュリティ・レルム用に構成されている各ロール・マッピング・プロバイダを呼び出します。関連情報については、「認可プロセス」を参照してください。
ロール・マッピング・プロバイダによる動的セキュリティ・ロール関連計算の結果、一連のセキュリティ・ロールが一度にサブジェクト内のプリンシパルに割り当てられます。その後、これらのセキュリティ・ロールを用いて、保護対象WebLogicリソース、リソース・コンテナ、およびアプリケーション・コードについての認可判定が行われます。たとえば、Enterprise JavaBeans (EJB)であれば、アクセスを許可するかどうかを決めるビジネス・ポリシーを知らなくても、Java EEのisCallerInRole()
メソッドを用いてデータベース内のレコードからフィールドを取得することができます。
動的セキュリティ・ロール計算を作成する場合のロール・マッピング・プロバイダとWebLogic Securityフレームワークとの対話を図9-1に示し、続いてそれについて説明します。
一般に、ロール・マッピングは以下のように実行されます。
ユーザーまたはシステム・プロセスがWebLogicリソースをリクエストし、特定の操作を実行しようとします。
リクエストされたWebLogicリソースのタイプを処理するリソース・コンテナがリクエストを受け取ります。たとえばEJBコンテナはEJBリソースに対するリクエストを受け取ります。
リソース・コンテナは、リクエストのコンテキストに関連付けられている情報を取得するためにロール・マッピング・プロバイダで使用する場合のあるContextHandler
オブジェクトを作成します。
リソース・コンテナは、サブジェクト(ユーザーおよびグループ・プリンシパルを含む)、WebLogicリソースの識別子、そして場合によっては追加入力を提供するContextHandler
オブジェクトを渡してWebLogic Securityフレームワークを呼び出します。
WebLogic Securityフレームワークは、適用するセキュリティ・ロールのリストを取得するために、構成済みの各ロール・マッピング・プロバイダを呼び出します。この仕組みは次のとおりです。
ロール・マッピング・プロバイダはContextHandler
を用いて、リクエストに関する様々な情報をリクエストします。また、ロール・マッピング・プロバイダは、リクエストする情報のタイプを表す一連のCallback
オブジェクトを作成します。そのCallback
オブジェクト群は、handle
メソッドを通じて、配列としてContextHandler
に渡されます。
ロール・マッピング・プロバイダは、必要なコンテキスト情報を取得するのに、ContextHandler
を複数回呼び出す場合があります。ロール・マッピング・プロバイダでContextHandler
が呼び出される回数はその実装によって異なります。
コンテキスト情報と、セキュリティ・ポリシー、サブジェクト、およびWebLogicリソースを格納する関連セキュリティ・プロバイダ・データベースを使用することで、ロール・マッピング・プロバイダは、サブジェクト内のユーザー・プリンシパルとグループ・プリンシパルで表されるリクエスト側に特定のセキュリティ・ロールの資格があるかどうかを決定します。
セキュリティ・ポリシーは、指定されたセキュリティ・ロールを付与すべきかどうかを判定する際に評価される一連の式すなわちルールとして表されます。これらのルールを使用する際に、ロール・マッピング・プロバイダは、取得したコンテキスト情報の値を式のパラメータに代入しなければならない場合があります。さらに、ユーザー・プリンシパルまたはグループ・プリンシパルのID情報が、式のパラメータ値として必要になることもあります。
注意: セキュリティ・ポリシーのルールは、WebLogic Server管理コンソールとJava EEデプロイメント記述子で設定します。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のセキュリティ・ポリシーに関する項を参照してください。 |
リクエスト側に特定のセキュリティ・ロールの資格があるとセキュリティ・ポリシーに指定されている場合には、そのセキュリティ・ロールがサブジェクトに適用されるセキュリティ・ロールのリストに追加されます。
このプロセスは、WebLogicリソースまたはリソース・コンテナに適用されるセキュリティ・ポリシーがすべて評価されるまで続行されます。
セキュリティ・ロールのリストはWebLogic Securityフレームワークに返され、アクセス決定などの操作の一環として使用できるようになります。
最高のパフォーマンスを実現するため、デフォルトでは、アプリケーションおよびモジュールのデプロイメント中にセキュリティ・ポリシーおよびロールに対して並列変更を実行できます。この理由から、セキュリティ・レルムに構成されているデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている必要があります。WebLogicのデプロイ可能なXACML認可プロバイダおよびロール・マッピング・プロバイダは、この要件を満たしています。
ただし、カスタムのデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている場合とサポートされていない場合があります。カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダで並列呼出しがサポートされていない場合は、セキュリティ・ポリシーとロールの並列変更を無効にして、かわりに同期化メカニズムを強制的に使用する必要があります。この場合、各アプリケーションとモジュールはキューに入り、順番にデプロイされます。
注意: 同期化メカニズムを有効にした場合、定義済のWebLogic Serverプロバイダも含めて、レルム内に構成されているすべてのデプロイ可能なプロバイダが影響を受けます。同期化メカニズムを有効にすると、これらのプロバイダのパフォーマンスに悪影響を与える可能性があります。 |
この同期化強制メカニズムを有効にする方法については、『Oracle WebLogic Serverの保護』を参照してください。
WebLogic Serverのデフォルト(つまりアクティブな)セキュリティ・レルムにはWebLogicロール・マッピング・プロバイダが含まれています。WebLogicロール・マッピング・プロバイダは、デフォルト・ユーザーとWebLogicリソースのそれぞれについて、保護されている特定のリソースに関する特定のユーザー(サブジェクト)の動的セキュリティ・ロールを計算します。また、WebLogicロール・マッピング・プロバイダは、システム内のセキュリティ・ロールのデプロイメントとアンデプロイメントをサポートしています。WebLogicロール・マッピング・プロバイダは、WebLogic認可プロバイダと同じセキュリティ・ポリシー・エンジンを使用します。自社の既存のロール・マッピング・メカニズムを使用する場合は、カスタム・ロール・マッピング・プロバイダを作成してそれを既存のメカニズムに結合できます。
セキュリティ・レルムのすべての認可プロバイダ、ロール・マッピング・プロバイダ、および資格証明マッピング・プロバイダは、アプリケーションのデプロイにバージョンを使用するために、アプリケーションのバージョン管理をサポートする必要があります。認可、ロール・マッピング、または資格証明マッピング用にカスタム・セキュリティ・プロバイダを開発する際に、バージョン管理されたアプリケーションをサポートする必要がある場合は、「バージョン管理可能なアプリケーションのプロバイダ」の説明に従って、バージョン管理可能なアプリケーションのSSPIを実装する必要があります。
WebLogicロール・マッピング・プロバイダが開発者のニーズを満たさない場合、次の手順でカスタム・ロール・マッピング・プロバイダを開発することができます。
適切なSSPIを使用して実行時クラスの作成または必要に応じてバルク認可プロバイダを実装
必要に応じてロール・コンシューマSSPIを実装
実行時クラスを作成する前に、以下の作業が必要です。
この情報を理解し、設計に関する判断を下したら、次の手順でカスタム・ロール・マッピング・プロバイダの実行時クラスを作成します。
注意: セキュリティ・レルムでは、少なくとも1つのロール・マッピング・プロバイダがDeployableRoleProviderV2 SSPIを実装する必要があり、実装していない場合、WebアプリケーションやEJBをデプロイできなくなります。 |
カスタム・ロール・マッピング・プロバイダの実行時クラスの作成例については、「例:サンプル・ロール・マッピング・プロバイダの実行時クラスの作成」を参照してください。
RoleProvider
SSPIを実装するには、「Provider」SSPIの目的についてで説明されているメソッドと以下のメソッドの実装を提供する必要があります。
getRoleMapper
public RoleMapper getRoleMapper()
getRoleMapper
メソッドは、RoleMapper
SSPIの実装を取得します。MyRoleProviderImpl
.java
という1つの実行時クラスの場合、getRoleMapper
メソッドの実装は次のようになります。
return this;
実行時クラスが2つの場合、getRoleMapper
メソッドの実装は次のようになります。
return new MyRoleMapperImpl;
これは、RoleProvider
SSPIを実装する実行時クラスが、RoleMapper
SSPIを実装するクラスを取得する場合のファクトリとして使用されるためです。
RoleProvider
SSPIとgetRoleMapper
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
注意: DeployableRoleProvider SSPIは、このリリースのWebLogic Serverでは非推奨になっています。DeployableRoleProviderV2 SSPIをかわりに使用してください。 |
DeployableRoleProviderV2
SSPIを実装するには、「Provider」SSPIの目的についておよび RoleProvider SSPIの実装で説明されているメソッドと以下のメソッドの実装を提供する必要があります。
deleteApplicationRoles
void deleteApplicationRoles(ApplicationInfo application)
アプリケーションのすべてのロールを削除し、アプリケーションが削除された時点でWebLogic Serverドメイン内の管理サーバーでのみ呼び出されます。
deployRole
void deployRole(DeployRoleHandle handle, Resource resource, String roleName, String[] userAndGroupNames)
デプロイされたWebアプリケーションまたはEJBにかわってロールを作成します。ロールがすでに存在する場合は削除され、このロールによって置き換えられます。
endDeployRoles
void endDeployRoles(DeployRoleHandle handle)
アプリケーションのロール・デプロイメントの終了をマークします。
startDeployRoles
DeployRoleHandle startDeployRoles(ApplicationInfo application)
アプリケーションのロール・デプロイメントの開始をマークし、アプリケーションがターゲット指定されているWebLogic Serverドメイン内のすべてのサーバーで呼び出されます。
undeployAllRoles
void undeployAllRoles(DeployRoleHandle handle)
デプロイされていないWebアプリケーションまたはEJBにかわって、ロールのセットを削除します。
DeployableRoleProvider
SSPI、deployRole
メソッド、undeployRole
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
ApplicationInfoインタフェースは、アプリケーションのデプロイメントに関するデータをセキュリティ・プロバイダに渡します。このデータを使用すると、アプリケーションをユニークに識別できます。
WebLogic Securityフレームワークは、ユーザーの利便を図るためにApplicationInfoインタフェースを実装します。このインタフェースのメソッドを実装する必要はありません。
DeployableAuthorizationProviderV2
インタフェースとDeployableRoleProviderV2
インタフェースはApplicationInfo
を使用します。たとえば、DeployableRoleProviderV2
のメソッドの実装を例にあげます。Securityフレームワークは、DeployableRoleProviderV2
のstartDeployRoles
メソッドを呼び出し、このアプリケーションのApplicationInfoインタフェースを渡します。ApplicationInfoデータは、アプリケーションのデプロイ時に管理コンソールで提供される情報を基に決められます。
startDeployRoles
メソッドは、DeployableRoleProviderV2
の他のメソッドでこの後使用できるDeployRoleHandle
を戻します。
ApplicationInfoインタフェースを使用すると、このアプリケーションのアプリケーション識別子、コンポーネント名、およびコンポーネントの種類を取得できます。コンポーネントの種類は、ApplicationInfo.ComponentType
クラスの定義に従って、APPLICATION
、CONTROL_RESOURCE
、EJB
、またはWEBAPP
のいずれかです。
次のコードは、このタスクを実行する方法の一例です。
public DeployRoleHandle startDeployRoles(ApplicationInfo appInfo) throws DeployHandleCreationException : // Obtain the application information... String appId = appInfo.getApplicationIdentifier(); ComponentType compType = appInfo.getComponentType(); String compName = appInfo.getComponentName();
Securityフレームワークは、DeployableRoleProviderV2
のdeleteApplicationRoles
メソッドを呼び出し、このアプリケーションのApplicationInfoインタフェースを渡します。deleteApplicationRoles
メソッドは、アプリケーションのすべてのロールを削除し、アプリケーションが削除された時点でWebLogic Serverドメイン内の管理サーバーでのみ呼び出されます。
RoleMapper
SSPIを実装するには、以下のメソッドの実装を提供する必要があります。
getRoles
public Map getRoles(Subject subject, Resource resource, ContextHandler handler)
getRoles
メソッドは、場合によりContextHandler
に指定された任意情報を使用して、特定のWebLogicリソースに関して特定のサブジェクトに関連付けられているセキュリティ・ロールを返します。ContextHandlerの詳細は、「ContextHandlerとWebLogicリソース」を参照してください。
RoleMapper
SSPIとgetRoles
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
認証プロバイダは、サブジェクト内へのユーザーおよびグループの格納を担当するセキュリティ・プロバイダです。ユーザーおよびグループはその後、ロール・マッピング・プロバイダなど、他のタイプのセキュリティ・プロバイダによって、サブジェクトから抽出されます。セキュリティ・レルム内で構成された認証プロバイダがレルム・アダプタ認証プロバイダである場合、ユーザーおよびグループの情報は、他の認証プロバイダとは少し異なる形でサブジェクト内に格納されます。したがって、このユーザーおよびグループの情報もまた、少し異なる方法で抽出する必要があります。
例9-1では、サブジェクトへの格納にレルム・アダプタ認証プロバイダが使用された場合に、サブジェクトがユーザー名またはグループ名に一致するかどうかをチェックするため、カスタム資格マッピング・プロバイダで使用できるコードを示します。このコードは、getRoles
メソッドに属しています。
例9-1 サンプル・コード:サブジェクトがユーザー名またはグループ名に一致するかどうかのチェック
/** * Determines if the Subject matches a user/group name. * * @param principalWant A String containing the name of a principal in this role * (that is, the role definition). * * @param subject A Subject that contains the Principals that identify the user * who is trying to access the resource as well as the user's groups. * * @return A boolean. true if the current subject matches the name of the * principal in the role, false otherwise. */ private boolean subjectMatches(String principalWant, Subject subject) { // first, see if it's a group name match if (SubjectUtils.isUserInGroup(subject, principalWant)) { return true; } // second, see if it's a user name match if (principalWant.equals(SubjectUtils.getUsername(subject))) { return true; } // didn't match return false; }
SecurityRole
インタフェースのメソッドを使用して、セキュリティ・ロールに関する基本的な情報を取得したり、取得した情報を別のセキュリティ・ロールと比較したりできます。これらのメソッドは、セキュリティ・プロバイダの利便性のために設計されています。
SecurityRole
インタフェースを実装するには、以下のメソッドの実装を提供する必要があります。
equals
public boolean equals(Object another)
equals
メソッドは、渡されたセキュリティ・ロールが、このインタフェースの実装によって表されるセキュリティ・ロールに一致する場合にTRUE
を返し、それ以外の場合はFALSE
を返します。
toString
public String toString()
toString
メソッドは、このセキュリティ・ロールをStringとして返します。
hashCode
public int hashCode()
hashCode
メソッドは、このセキュリティ・ロールのハッシュ・コードを整数で返します。
getName
public String getName()
getName
メソッドは、このセキュリティ・ロールの名前をStringとして返します。
getDescription
public String getDescription()
getDescription
メソッドは、このセキュリティ・ロールの説明をStringとして返します。説明は、このセキュリティ・ロールの目的を記述したものです。
例9-2は、サンプル・ロール・マッピング・プロバイダの実行時クラスであるSimpleSampleRoleMapperProviderImpl.java
クラスを示しています。実行時クラスには以下の実装が含まれています。
initialize
、getDescription
、およびshutdown
というSecurityProvider
インタフェースから継承した3つのメソッド(「「Provider」SSPIの目的について」を参照)。
getRoleMapper
というRoleProvider
SSPIから継承したメソッド(「RoleProvider SSPIの実装」を参照)。
deleteApplicationRoles、deployRole
、endDeployRoles、startDeployRoles、およびundeployAllRoles
というDeployableRoleProviderV2
SSPIの5つのメソッド(「DeployableRoleProviderV2 SSPIの実装」を参照)。
getRoles
というRoleMapper
SSPIのメソッド(「RoleProvider SSPIの実装」を参照)。
例9-2 SimpleSampleRoleMapperProviderImpl.java
package examples.security.providers.roles.simple; import java.security.Principal; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.security.auth.Subject; import weblogic.management.security.ProviderMBean; import weblogic.security.SubjectUtils; import weblogic.security.WLSPrincipals; import weblogic.security.service.ContextHandler; import weblogic.security.spi.ApplicationInfo; import weblogic.security.spi.ApplicationInfo.ComponentType; import weblogic.security.spi.DeployableRoleProviderV2; import weblogic.security.spi.DeployRoleHandle; import weblogic.security.spi.Resource; import weblogic.security.spi.RoleMapper; import weblogic.security.spi.SecurityServices; import weblogic.security.spi.VersionableApplicationProvider; public final class SimpleSampleRoleMapperProviderImpl implements DeployableRoleProviderV2, RoleMapper, VersionableApplicationProvider { private String description; // a description of this provider private SimpleSampleRoleMapperDatabase database; // manages the role definitions for this provider private static final Map NO_ROLES = Collections.unmodifiableMap(new HashMap(1)); // used when no roles are found public void initialize(ProviderMBean mbean, SecurityServices services) { System.out.println("SimpleSampleRoleMapperProviderImpl.initialize"); // Cast the mbean from a generic ProviderMBean to a SimpleSampleRoleMapperMBean. SimpleSampleRoleMapperMBean myMBean = (SimpleSampleRoleMapperMBean)mbean; // Set the description to the simple sample role mapper's mbean's description and version description = myMBean.getDescription() + "\n" + myMBean.getVersion(); // Instantiate the helper that manages this provider's role definitions database = new SimpleSampleRoleMapperDatabase(myMBean); } public String getDescription() { return description; } public void shutdown() { System.out.println("SimpleSampleRoleMapperProviderImpl.shutdown"); } public RoleMapper getRoleMapper() { // Since this class implements both the DeployableRoleProvider // and RoleMapper interfaces, this object is the // role mapper object so just return "this". return this; } public Map getRoles(Subject subject, Resource resource, ContextHandler handler) { System.out.println("SimpleSampleRoleMapperProviderImpl.getRoles"); System.out.println("\tsubject\t= " + subject); System.out.println("\tresource\t= " + resource); // Make a list for the roles Map roles = new HashMap(); // Make a list for the roles that have already been found and evaluated Set rolesEvaluated = new HashSet(); // since resources scope roles, and resources are hierarchical, // loop over the resource and all its parents, adding in any roles // that match the current subject. for (Resource res = resource; res != null; res = res.getParentResource()) { getRoles(res, subject, roles, rolesEvaluated); } // try global resources too getRoles(null, subject, roles, rolesEvaluated); // special handling for no matching roles if (roles.isEmpty()) { return NO_ROLES; } // return the roles we found. System.out.println("\troles\t= " + roles); return roles; } public DeployRoleHandle startDeployRoles(ApplicationInfo application) { String appId = application.getApplicationIdentifier(); String compName = application.getComponentName(); ComponentType compType = application.getComponentType(); DeployRoleHandle handle = new SampleDeployRoleHandle(appId,compName,compType); // ensure that previous roles have been removed so that // the most up to date deployment roles are in effect database.removeRolesForComponent(appId, compName, compType); // A null handle may be returned if needed return handle; } public void deployRole(DeployRoleHandle handle, Resource resource, String roleName, String[] principalNames) { System.out.println("SimpleSampleRoleMapperProviderImpl.deployRole"); System.out.println("\thandle\t\t= " + ((SampleDeployRoleHandle)handle).toString()); System.out.println("\tresource\t\t= " + resource); System.out.println("\troleName\t\t= " + roleName); for (int i = 0; principalNames != null && i < principalNames.length; i++) { System.out.println("\tprincipalNames[" + i + "]\t= " + principalNames[i]); } database.setRole(resource, roleName, principalNames); } public void endDeployRoles(DeployRoleHandle handle) { database.saveRoles(); } public void undeployAllRoles(DeployRoleHandle handle) { System.out.println("SimpleSampleRoleMapperProviderImpl.undeployAllRoles"); SampleDeployRoleHandle myHandle = (SampleDeployRoleHandle)handle; System.out.println("\thandle\t= " + myHandle.toString()); // remove roles database.removeRolesForComponent(myHandle.getApplication(), myHandle.getComponent(), myHandle.getComponentType()); } public void deleteApplicationRoles(ApplicationInfo application) { System.out.println("SimpleSampleRoleMapperProviderImpl.deleteApplicationRoles"); String appId = application.getApplicationIdentifier(); System.out.println("\tapplication identifier\t= " + appId); // clear out roles for the application database.removeRolesForApplication(appId); } private void getRoles(Resource resource, Subject subject, Map roles, Set rolesEvaluated) { // loop over all the roles in our "database" for this resource for (Enumeration e = database.getRoles(resource); e.hasMoreElements();) { String role = (String)e.nextElement(); // Only check for roles not already evaluated if (rolesEvaluated.contains(role)) { continue; } // Add the role to the evaluated list rolesEvaluated.add(role); // If any of the principals is on that role, add the role to the list. if (roleMatches(resource, role, subject)) { // Add a simple sample role mapper role instance to the list of roles. roles.put(role, new SimpleSampleSecurityRoleImpl(role)); } } } private boolean roleMatches(Resource resource, String role, Subject subject) { // loop over the the principals that are in this role. for (Enumeration e = database.getPrincipalsForRole(resource, role); e.hasMoreElements();) { // get the next principal in this role String principalWant = (String)e.nextElement(); // see if any of the current principals match this principal if (subjectMatches(principalWant, subject)) { return true; } } return false; } private boolean subjectMatches(String principalWant, Subject subject) { // first, see if it's a group name match if (SubjectUtils.isUserInGroup(subject, principalWant)) { return true; } // second, see if it's a user name match if (principalWant.equals(SubjectUtils.getUsername(subject))) { return true; } // didn't match return false; } public void createApplicationVersion(String appId, String sourceAppId) { System.out.println("SimpleSampleRoleMapperProviderImpl.createApplicationVersion"); System.out.println("\tapplication identifier\t= " + appId); System.out.println("\tsource app identifier\t= " + ((sourceAppId != null) ? sourceAppId : "None")); // create new roles when existing application is specified if (sourceAppId != null) { database.cloneRolesForApplication(sourceAppId,appId); } } public void deleteApplicationVersion(String appId) { System.out.println("SimpleSampleRoleMapperProviderImpl.deleteApplicationVersion"); System.out.println("\tapplication identifier\t= " + appId); // clear out roles for the application database.removeRolesForApplication(appId); } public void deleteApplication(String appName) { System.out.println("SimpleSampleRoleMapperProviderImpl.deleteApplication"); System.out.println("\tapplication name\t= " + appName); // clear out roles for the application database.removeRolesForApplication(appName); } class SampleDeployRoleHandle implements DeployRoleHandle { Date date; String application; String component; ComponentType componentType; SampleDeployRoleHandle(String app, String comp, ComponentType type) { this.application = app; this.component = comp; this.componentType = type; this.date = new Date(); } public String getApplication() { return application; } public String getComponent() { return component; } public ComponentType getComponentType() { return componentType; } public String toString() { String name = component; if (componentType == ComponentType.APPLICATION) name = application; return componentType +" "+ name +" ["+ date.toString() +"]"; } } }
例9-3は、SimpleSampleRoleMapperProviderImpl.java
実行時クラスとともに使用するSecurityRole
の実装例を示しています。
例9-3 SimpleSampleSecurityRoleImpl.java
package examples.security.providers.roles.simple; import weblogic.security.service.SecurityRole; /*package*/ class SimpleSampleSecurityRoleImpl implements SecurityRole { private String roleName; // the role's name private int hashCode; // the role's hash code /*package*/ SimpleSampleSecurityRoleImpl(String roleName) { this.roleName = roleName; this.hashCode = roleName.hashCode() + 17; } public boolean equals(Object genericRole) { // if the other role is null, we're not the same if (genericRole == null) { return false; } // if we're the same java object, we're the same if (this == genericRole) { return true; } // if the other role is not a simple sample role mapper role, // we're not the same if (!(genericRole instanceof SimpleSampleSecurityRoleImpl)) { return false; } // Cast the other role to a simple sample role mapper role. SimpleSampleSecurityRoleImpl sampleRole = (SimpleSampleSecurityRoleImpl)genericRole; // if our names don't match, we're not the same if (!roleName.equals(sampleRole.getName())) { return false; } // we're the same return true; } public String toString() { return roleName; } public int hashCode() { return hashCode; } public String getName() { return roleName; } public String getDescription() { return ""; } }
WebLogic ServerにはWebServiceアノテーション用のロール・コンシューマが実装されています。このリリースのWebLogic Serverには、ロール・マッピング・プロバイダがロール・コレクションを取得するために使用できるSSPIがあります。
RoleConsumer
SSPIは省略可能です。ロール・コレクションを消費するためには、このSSPIを実装するロール・マッピング・プロバイダのみが呼び出されます。
このSSPIでは、初期状態のロール・コレクションの配信と、更新後のロール・コレクションの配信の両方がサポートされます。
ロール・コレクションの消費においては、RoleConsumer
SSPIをサポートするすべてのロール・マッピング・プロバイダが呼び出されます。各ロール・マッピング・プロバイダは、特定のロール・セットのロール・コレクションを取得するかしないかを選択できます。プロバイダでロールが永続化される場合、ロールを取得する必要があるのは一度だけです。一方、プロバイダでロールがメモリーに保持される場合、ロール・コレクションを再び取得することも可能です。
用意されているWebLogic Serverロール・マッピング・プロバイダでは、ロールはLDAP内に永続化されます。
ロール・マッピング・プロバイダをカスタマイズしてロール・コレクションの配信をサポートするには、以下の3つのインタフェースを実装する必要があります。
weblogic.security.spi.RoleConsumerFactory
weblogic.security.spi.RoleConsumer
weblogic.security.spi.RoleCollectionHandler
これらのインタフェースについては、これ以降の節で説明します。
ロール・マッピング・プロバイダには、RoleConsumer
のインスタンスをWebLogic Securityフレームワークで使用できるように、RoleConsumerFactory
インタフェースが実装されています。WebLogic SecurityフレームワークではRoleConsumerFactory
の実装を呼び出して、プロバイダのロール・コンシューマの実装を取得します。
RoleConsumerFactory
SSPIにはメソッドが1つあり、このメソッドはRoleConsumer
SSPIインタフェースの実装を返します。
public interface RoleConsumerFactory { /** * Obtain the implementation of the RoleConsumer * security service provider interface (SSPI).<P> * * @return a RoleConsumer SSPI implementation.<P> */ public RoleConsumer getRoleConsumer(); }
RoleConsumer
SSPIは、ロール・コレクションを消費するためのロール・コレクション・ハンドラを返します。これにはgetRoleCollectionHandler()
というメソッドが1つあり、このメソッドは引数にRoleCollectionInfo
の実装を取って、RoleCollectionHandler
インタフェースの実装を返します。
public interface RoleConsumer { /** * Obtain a role handler for consumption of a role collection. * * @param info the RoleCollectionInfo for the role collection. * * @return a RoleCollectionHandler or NULL which indicates * that the role collection is not needed. * * @exception ConsumptionException if an error occurs * obtaining the handler and the role collection cannot be consumed. */ public RoleCollectionHandler getRoleCollectionHandler( RoleCollectionInfo info) throws ConsumptionException; }
WebLogic SecurityフレームワークではgetRoleCollectionHandler()
メソッドを呼び出して、ロール・コレクションに関するデータをRoleCollectionInfo
インタフェースの実装としてセキュリティ・プロバイダに渡します(このインタフェースはあらかじめ実装されているので、ユーザーが実装する必要はありません)。
RoleCollectionInfo
のgetName()
、getVersion()
、getTimestamp()
、およびgetResourceTypes()
メソッドを使用して、このロール・コレクションに関する情報を検索します。検索後にはRoleCollectionHandler
を返すか、ロール・コレクションが不要であることを示すNULLを返します。
public interface RoleCollectionInfo { /** * Get the name of the collection. */ public String getName(); /** * Get the runtime version of the role. */ public String getVersion(); /** * Get the timestamp of the role. */ public String getTimestamp(); /** * Get the resource types used in the role collection. */ public Resource[] getResouceTypes(); }
RoleConsumer.getRoleCollectionHandler()
メソッドはRoleCollectionHandler
インタフェースの実装を返します。RoleCollectionHandler
にはsetRole()
とdone()
という2つのメソッドがあります。setRole()
メソッドは、リソース、ロール名、およびその特定のリソース用のロールに割り当てる一連のユーザー名とグループ名の配列を取ります。
done()
メソッドはロール・コレクションの完了を示します。
public interface RoleCollectionHandler { /** * Set a role for the specified resource. */ public void setRole(Resource resource, String roleName, String[] userAndGroupNames) throws ConsumptionException; /** * Signals the completion of the role collection. */ public void done() throws ConsumptionException; }
更新後のロール・コレクションの配信をサポートするには、RoleConsumer
SSPIをサポートするすべてのロール・マッピング・プロバイダで、RoleConsumer.getRoleCollectionHandler()
メソッドに渡されたRoleCollectionInfo
の内容を調べて、ロール・コレクションが変更されているかどうかを判断する必要があります。各プロバイダでは、初期状態のロール・コレクションとSSPIの外部から受け取ったカスタマイズ後のロールとの衝突を解決する方法を(できれば構成によって)決定しておくことが必要です。
WebLogic Serverで提供されているロール・マッピング・プロバイダでは、カスタマイズ後のロールが更新後のロール・コレクションで置き換えられません。初期状態のロール・コレクションのロールはすべて削除され、カスタマイズ後のロールと更新後のロール・コレクションのみが有効になります。ロール・コレクションの情報に異なるタイムスタンプやバージョンがある場合、更新後のロール・コレクションとして扱われます。コレクションの名前は永続キーとして使用されます。
このリリースのWebLogic Serverでは、weblogic.management.security.authorization.PolicyStoreMBean
という新しいMBeanがサポートされています。このMBeanは、管理者が生成したXACMLポリシーおよびポリシー・セットの標準的な管理操作(追加、削除、取得、リスト表示、変更、読込み)に使用できます。認可プロバイダMBeanやロール・マッピング・プロバイダMBeanには、必要に応じてこのMBeanインタフェースを実装できます。
セキュリティ管理者は、PolicyStoreMBeanのメソッドを使用して、サーバー内のポリシーをXACMLドキュメントとして管理できます。たとえば、デフォルトのXACMLプロバイダを使用するドメインを作成および管理したり、作成済みのXACMLドキュメントを管理したりできます。これらのXACMLポリシーは、WebLogic ServerではWLSTを使用して管理できます。
WebLogic ServerにはこのMBeanの実装が含まれており、付属のXACMLプロバイダで使用できます。また、このMBeanの独自の実装を記述して、カスタムの認可プロバイダやロール・マッピング・プロバイダで使用することも可能です。WebLogic Serverに用意されているXACMLプロバイダでは、XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)に記載されているXACMLの必須機能がサポートされています。Oracle固有の使用方法については、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』を参照してください。
ポリシーはXACML 2.0のポリシーまたはPolicySetドキュメントで表現されます。カスタム認可プロバイダでは、XACML 2.0のコア仕様に記載されている標準のPolicyまたはPolicySetドキュメントを想定する必要があります。カスタム・ロール・マッピング・プロバイダでは、Core and hierarchical role based access control (RBAC) profile of XACML v2.0 (http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-rbac-profile1-spec-os.pdf
)に記載されているロール割当てポリシーと整合性があるPolicyまたはPolicySetドキュメントを想定する必要があります。
具体的には、Targetに以下を含める必要があります。
ActionAttributeDesignator
(anyURI-equal
で一致する、urn:oasis:names:tc:xacml:1.0:action:action-id
というIDと、urn:oasis:names:tc:xacml:2.0:actions:enableRole
という値の指定されているもの)。例:
<Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">urn:oasis:names:tc:xacml:2.0:actions:enableRole </AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="true"/> </ActionMatch> </Action>
ResourceAttributeDesignator
(string-equalで一致する、urn:oasis:names:tc:xacml:2.0:subject:role
というIDと、割り当てられたロールの名前である値の指定されているもの)。例:
<ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-ancestor-or-self" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)および『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』で説明しているOracle拡張が、提供されているXACML認可プロバイダおよびロール・マッピング・プロバイダで使用するXACMLポリシー・ファイルについての最も確実な情報です。
ただしサポートされているXACMLファイルの形式を開発プロセスの一環として確認する場合は、おそらく、管理コンソールを使用して、XACML認可またはロール・マッピング・プロバイダのデータベースからデータをXACMLファイルとしてエクスポートする方法が最も便利です。エクスポートしたXACMLファイルをコピーして別の名前で保存し、任意のツールで確認します。
注意: エクスポートしたファイルは読取り専用としてください。変更した場合、そのファイルはWebLogic Serverにインポートし直さないでください。エクスポートしたファイルを編集すると、WebLogic Server構成が使用できなくなる可能性があります。エクスポートしたファイルの編集はサポートされていません。 |
例9-4に、WLSTを使用してXACMLファイルからPolicyStoreMBeanのインスタンスに1つのポリシーを追加する例を示します。
この例ではこのスクリプトで使用するプロパティを、次のant
スクリプトから抜粋した行に似た方法で、あらかじめ別の場所に定義してあるものと想定しています。
<property name="xacml-docs-dir" value="${xacmldir}/xacml-docs"/> <sysproperty key="file" value="${xacml-docs-dir}/policy-getSubject.xacml"/>
例9-4 WLSTを使用してPolicyStoreMBeanにポリシーの追加
: try: protocol = System.getProperty("protocol") host = System.getProperty("host") user = System.getProperty("authuser") passwd = System.getProperty("authpwd") port = System.getProperty("port") dom = System.getProperty("domain") rlm = System.getProperty("realm") fil = System.getProperty("file") prov = System.getProperty("provider") stat = System.getProperty("status") def configure(): try: url = protocol + "://" + host + ":" + port connect(user,passwd, url) path = "/SecurityConfiguration/" + dom + "/Realms/" + rlm + "/" + prov print("cd'ing to " + path) cd(path) print("calling open()") xacmlFile = open(fil,"r") print("calling read()") xacmlDoc = xacmlFile.read() print("calling cmo.addPolicy") if stat == "none": cmo.addPolicy(xacmlDoc) else: cmo.addPolicy(xacmlDoc, stat) print("Add error handling") : :
『Oracle WebLogic Scripting Tool』のMBeanの移動と照会に関する項で説明しているように、WLSTが初めてWebLogic Serverインスタンスに接続すると、変数cmo
(現在の管理オブジェクト)がすべての構成管理オブジェクトのルートDomainMBean
に初期化されます。MBeanタイプに移動すると、このSecurityConfigurationMBean
の場合、cmo
の値はSecurityConfigurationMBean
を反映したものになります。MBeanインスタンス、つまりこの場合にはPolicyStoreMBeanを実装する認可プロバイダMBean(例では変数prov
で指定)に移動するときには、WLSTによってcmo
の値が現在のMBeanインスタンスに変更されます。
この例ではPolicyStoreMBeanのaddPolicy()
メソッドを使用して、XACMLファイルからポリシー・ストアに読み込まれるポリシーを追加しています。addPolicy()
メソッドの2つのバリアント(ステータスを伴うものと伴わないもの)が示されています。
ステータスを指定しないaddPolicy()
メソッドを使用する場合、デフォルトでACTIVEに設定されます。これは、ポリシーがその対象で適用されるどのような決定でも評価されることを示します。ステータスは明示的にACTIVE、INACTIVE、またはBYREFERENCEに設定できます。INACTIVEステータスは、ポリシーが評価されずに格納されるだけであることを示します。BYREFERENCEステータスは、評価されるポリシー・セットによって参照された場合にだけ、ポリシーが評価されることを示します。
このタイプのWLSTスクリプトは、次のような方法でコマンド・ラインから呼び出せます。
java -Dhost="localhost " -Dprotocol="t3" -Dauthuser="weblogic" -Dauthpwd="weblogic" -Dport="7001" -Ddomain="mydomain" -Drealm="myrealm" -Dprovider="Authorizers/XACMLAuthorizer" -Dfile="C:/XACML/xacml-docs/policy12.xml" -Dstatus="none" weblogic.WLST XACML/scripts/XACMLaddPolicy.py
例9-5に、WLSTを使用してPolicySetをStringとして読み込む例を示します。
この例ではこのスクリプトで使用するプロパティを、次のant
スクリプトから抜粋した行に似た方法で、あらかじめ別の場所に定義してあるものと想定しています。
<sysproperty key="identifier" value="urn:sample:xacml:2.0:wlssecqa:resource:type@E@Fejb@G@M@Oapplication@ENoD DRolesOrPoliciesEar@M@Omodule@Eejb11inEarMiniAppBean.jar@M@Oejb@EMiniAppBean@ M@Omethod@EgetSubject@M@OmethodInterface@ERemote"/> <sysproperty key="version" value="1.0"/>
例9-5 WLSTを使用してPolicySetをStringとして読み込む
: : try: print("start XACMLreadPolicySet.py") protocol = System.getProperty("protocol") host = System.getProperty("host") user = System.getProperty("authuser") passwd = System.getProperty("authpwd") port = System.getProperty("port") dom = System.getProperty("domain") rlm = System.getProperty("realm") prov = System.getProperty("provider") id = System.getProperty("identifier") vers = System.getProperty("version") : : def configure(): try: url = protocol + "://" + host + ":" + port connect(user,passwd, url) path = "/SecurityConfiguration/" + dom + "/Realms/" + rlm + "/" + prov print("cd'ing to " + path) cd(path) polset = cmo.readPolicySetAsString(id, vers) print("readPolicySetAsString() returned the following policy set: " + polset) print"Add error handling." : :
XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)で説明されているように、<PolicySet>
要素には<Policy>
のセットまたは別の<PolicySet>
要素、およびそれらの評価結果を結合するための指定された手順が含まれます。詳細については、XACML 2.0のコア仕様を参照してください。
WebLogic Serverのこのリリースには、以下に示すバルク・アクセス・バージョンのロール・マッピング・プロバイダSSPIインタフェースがあります。
BulkRoleProvider
BulkRoleMapper
バルク・アクセスSSPIインタフェースを使用すると、ロール・マッピング・プロバイダにおいて、1回の呼出しで複数の判定リクエストを取得できます。これまでのように、たとえば「for」
ループで複数の呼出しを実行する必要はありません。バルクSSPIバリアントの目的は、プロバイダ実装において内部的なパフォーマンスの最適化を利用できるようにすることです。たとえば、渡されたResource
オブジェクトの多くが同じポリシーで保護されていることを検出することで、それらの判定結果が同じになると推測できるようになります。
バルク・バージョンでないSSPIインタフェースとバルク・バージョンのSSPIインタフェースの使用方法には若干の違いがあります。たとえば、BulkRoleMapper.getRoles()
メソッドはロールのMap
を返します。これは、初めにリソース、続いて名前で索引付けされ(Map<Resource, Map<String, SecurityRole>>
)、サブジェクトに許可されている指定のリソースに関連付けられたセキュリティ・ロールを表します。
カスタム・セキュリティ・プロバイダのMBeanタイプを生成する前に、以下の作業が必要です。
この情報を理解し、設計に関する判断を下したら、次の手順でカスタム・ロール・マッピング・プロバイダのMBeanタイプを作成します。
WebLogic Server環境にMBeanタイプのインストール
注意: この手順の実行方法を説明するサンプル・セキュリティ・プロバイダ(Oracle Technology Network Webサイトのhttps://codesamples.samplecode.oracle.com/servlets/tracking?id=S224 から入手可能)がいくつか用意されています。
この節で説明する手順はすべて、Windows環境での作業を想定しています。 |
MBean定義ファイル(MDF)を作成するには、次の手順に従います。
サンプル・ロール・マッピング・プロバイダのMDFをテキスト・ファイルにコピーします。
注意: サンプル・ロール・マッピング・プロバイダのMDFは、SimpleSampleRoleMapper.xml という名前です。 |
MDFで<MBeanType>
要素と<MBeanAttribute>
要素の内容をカスタム・ロール・マッピング・プロバイダに合わせて修正します。
カスタム属性および操作(つまり、<MBeanAttribute>
および<MBeanOperation>
要素)をMDFに追加します。
ファイルを保存します。
MDFを作成したら、WebLogic MBeanMakerを使用してそれを実行できます。WebLogic MBeanMakerは現在のところコマンド・ライン・ユーティリティで、入力としてMDFを受け取り、MBeanインタフェース、MBean実装、関連するMBean情報ファイルなどの中間Javaファイルをいくつか出力します。これらの中間ファイルが合わさって、カスタム・セキュリティ・プロバイダのMBeanタイプになります。
MBeanタイプの生成手順は、カスタム・ロール・マッピング・プロバイダの設計に応じて異なります。必要な設計に合わせて適切な手順を実行してください。
カスタム・ロール・マッピング・プロバイダのMDFにカスタム操作を含めない場合、次の手順に従います。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
カスタム・ロール・マッピング・プロバイダのMDFにカスタム操作を含める場合、質問に答えながら手順を進めてください。
MBeanタイプを作成するのは初めてですか。初めての場合は、次の手順に従ってください。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
MDFのすべてのカスタム操作に対して、メソッド・スタブを使用してメソッドを実装します。
ファイルを保存します。
既存のMBeanタイプの更新ですか。更新の場合は、次の手順に従ってください。
WebLogic MBeanMakerによって現在のメソッドの実装が上書きされないように、既存のMBean実装ファイルを一時ディレクトリにコピーします。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
MDFを変更して元のMDFにはないカスタム操作を含めた場合、メソッド・スタブを使用してメソッドを実装します。
完成した、つまりすべてのメソッドを実装したMBean実装ファイルを保存します。
このMBean実装ファイルを、WebLogic MBeanMakerがMBeanタイプの実装ファイルを配置したディレクトリにコピーします。このディレクトリは、ステップ3でfilesdirとして指定したものです。 (ステップ3の結果としてWebLogic MBeanMakerで生成されたMBean実装ファイルがオーバーライドされます)。
MBeanインタフェース・ファイルとは、実行時クラスまたはMBean実装が構成データを取得するために使用するMBeanのクライアント側APIです。「「Provider」SSPIの目的について」で説明されているように、これはinitializeメソッドで使用するのが一般的です。
WebLogic MBeanMakerでは、作成済みのMDFからMBeanタイプを生成するので、生成されるMBeanインタフェース・ファイルの名前は、そのMDF名の後に「MBean」というテキストが付いたものになります。たとえば、WebLogic MBeanMakerでSampleRoleMapper
MDFを実行すると、SampleRoleMapperMBean.java
というMBeanインタフェース・ファイルが生成されます。
WebLogic MBeanMakerでMDFを実行して中間ファイルを作成し、MBean実装ファイルを編集して適切なメソッドの実装を提供したら、カスタム・ロール・マッピング・プロバイダのMBeanファイルと実行時クラスをMBean JARファイル(MJF)にパッケージ化する必要があります。このプロセスも、WebLogic MBeanMakerによって自動化されます。
カスタム・ロール・マッピング・プロバイダのMJFを作成するには、次の手順に従います。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMJF=jarfile -Dfiles=filesdir weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMJF
フラグはWebLogic MBeanMakerが新しいMBeanタイプを含むJARファイルを構築すべきであることを示し、jarfileはMJFの名前、filesdirはWebLogic MBeanMakerでMJFにJAR化する対象ファイルが存在する場所を示します。
この時点でコンパイルが行われるので、エラーが発生するおそれがあります。jarfileが指定されていて、エラーが発生しなかった場合には、指定された名前のMJFが作成されます。
注意: カスタム・セキュリティ・プロバイダのJARファイルを作成する際には、一連のXMLバインディング・クラスと1つのスキーマも生成されます。そのスキーマに関連付けるネームスペースを選択できます。それにより、使用しているカスタム・クラスとOracleのカスタム・クラスとの衝突を防ぐことができます。ネームスペースのデフォルトはvendorです。-targetNameSpace引数をWebLogicMBeanMakerまたは関連するWLMBeanMaker antタスクに渡すことで、このデフォルトを変更できます。既存のMJFを更新する場合は、単純にMJFを削除して再生成します。WebLogic MBeanMakerにも -DIncludeSourceオプションがあり、それを指定すると、生成されるMJFにソース・ファイルを含めるかどうかを制御できます。ソース・ファイルには、生成されたソースとMDFそのものがあります。デフォルトはfalseです。このオプションは、-DMJFを使用しない場合には無視されます。 |
生成されたMJFは、自らのWebLogic Server環境にインストールすることも、顧客に配布してそれぞれのWebLogic Server環境にインストールしてもらうこともできます。
MBeanタイプをWebLogic Server環境にインストールするには、MJFをWL_HOME\server\lib\mbeantypes
ディレクトリにコピーします。ここで、WL_HOMEはWebLogic Serverの最上位のインストール・ディレクトリです。このインストール・コマンドによって、カスタム・ロール・マッピング・プロバイダが「デプロイ」されます。つまり、カスタム・ロール・マッピング・プロバイダをWebLogic Server管理コンソールから管理できるようになります。
注意: WL_HOME\server\lib\mbeantypes は、MBeanタイプのインストール用のデフォルト・ディレクトリです。(9.0から、セキュリティ・プロバイダを...\domaindir\lib\mbeantypes からロードすることもできるようになりました。)ただし、サーバーを起動するときに-Dweblogic.alternateTypesDirectory=<dir> コマンド・ライン・フラグを使用すれば、WebLogic Serverは追加ディレクトリでMBeanタイプを検索します。<dir>は、ディレクトリ名のカンマ区切りのリストです。このフラグを使用する場合、WebLogic Serverは常に、まずWL_HOME\server\lib\mbeantypes からMBeanタイプをロードします。次に、追加ディレクトリにあるすべての有効なアーカイブを検索して、ロードします。このとき拡張子は考慮されません。
たとえば、 |
カスタム・ロール・マッピング・プロバイダを構成することによって(「管理コンソールによるカスタム・ロール・マッピング・プロバイダの構成」を参照)、MBeanタイプのインスタンスを作成して、GUI、他のJavaコード、またはAPIからそれらのMBeanインスタンスを使用することができます。たとえば、WebLogic Server管理コンソールを使用して、属性を取得/設定したり操作を呼び出したりすることもできますし、他のJavaオブジェクトを開発して、そのオブジェクトでMBeanをインスタンス化し、それらのMBeanから提供される情報に自動的に応答させることもできます。なお、これらのMBeanインスタンスをバックアップしておくことをお薦めします。
カスタム・ロール・マッピング・プロバイダを構成するということは、ロール・マッピング・サービスを必要とするアプリケーションがアクセス可能なセキュリティ・レルムにカスタム・ロール・マッピング・プロバイダを追加するということです。
カスタム・セキュリティ・プロバイダの構成は管理タスクですが、カスタム・セキュリティ・プロバイダの開発者が行うこともできます。この節では、カスタム・ロール・マッピング・プロバイダの構成担当者向けの重要な情報を取り上げます。
注意: WebLogic Server管理コンソールを使用してカスタム・ロール・マッピング・プロバイダを構成する手順は、『Oracle WebLogic Serverの保護』のWebLogicセキュリティ・プロバイダの構成に関する項で説明されています。 |
Enterprise JavaBeans (EJB)やWebアプリケーションなどのアプリケーションの中には、Java EEの関連デプロイメント情報とWebLogic Serverデプロイメント記述子を格納するものがあります。Webアプリケーションの場合、デプロイメント記述子ファイル(web.xml
とweblogic.xml
)には、セキュリティ・ロールを含むJava EEセキュリティ・モデルの実装情報が格納されます。この情報は、WebLogic Server管理コンソールでロール・マッピング・プロバイダを初めて構成するときに格納するのが一般的です。
Java EEプラットフォームはデプロイメント記述子でWebアプリケーションおよびEJBのセキュリティを標準化しているので、WebLogic Serverではこの標準メカニズムがWebLogic Securityサービスに統合され、WebアプリケーションおよびEJBリソースを保護する方法を選択できるようになっています。デプロイメント記述子のみを使用することも管理コンソールのみを使用することもできます。また、状況によっては、この2つの方法を組み合せることもできます。
選択した方法によって、セキュリティ・モデルを適用する必要もあります。WebLogicでは、個々のデプロイメントについて複数のセキュリティ・モデルがサポートされ、使用する方法を組み込むレルム全体の構成についてはセキュリティ・モデルがサポートされます。
詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のEJBおよびWebアプリケーション・リソースの保護のオプションに関する項を参照してください。
デプロイメント記述子を使用するように構成すると、WebLogic Serverによりweb.xml
およびweblogic.xml
デプロイメント記述子ファイルからセキュリティ・ロール情報が読み込まれます(web.xml
ファイルとweblogic.xml
ファイルの例については、例9-6と例9-7を参照)。この情報は、ロール・マッピング・プロバイダのセキュリティ・プロバイダ・データベースにコピーされます。
例9-6 web.xmlファイルのサンプル
<web-app> <welcome-file-list> <welcome-file>welcome.jsp</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Success</web-resource-name> <url-pattern>/welcome.jsp</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>developers</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> <security-role> <role-name>developers</role-name> </security-role> </web-app>
カスタム・ロール・マッピング・プロバイダの開発の一環としてDeployableRoleProviderV2
SSPIを実装し、デプロイ可能なセキュリティ・ロールをサポートする場合、カスタム・ロール・マッピング・プロバイダの構成担当者(つまり、開発者または管理者)は、WebLogic Server管理コンソールで「ロール・デプロイメントを有効化」ボックスがチェックされていることを確認する必要があります。チェックがはずれていると、ロール・マッピング・プロバイダに対するデプロイメントは「オフ」と見なされます。このため、複数のロール・マッピング・プロバイダが構成されている場合、「ロール・デプロイメントを有効化」ボックスを使用して、セキュリティ・ロールのデプロイメントに使用するロール・マッピング・プロバイダを指定できます。
WebLogic Server管理コンソールを使用してカスタム・ロール・マッピング・プロバイダを構成すると、必要なロール・マッピング・サービスにアプリケーションからアクセスできるようにすることはできますが、このセキュリティ・プロバイダに関連付けられたセキュリティ・ロールを管理する方法を管理者にも提供する必要があります。たとえばWebLogicロール・マッピング・プロバイダには、ロール・エディタ・ページが管理者向けに用意されており、様々なWebLogicリソースのセキュリティ・ロールを追加、変更、または削除することができます。
カスタム・ロール・マッピング・プロバイダを開発すると、管理者はロール・エディタ・ページも右クリック・メニューも利用できません。したがって、セキュリティ・ロールを管理するための独自のメカニズムを提供する必要があります。このメカニズムでは、カスタム・ロール・マッピング・プロバイダのデータベースのセキュリティ・ロール・データ(つまり式)を読み書きできなければなりません。
それには、以下の2通りの方法があります。
WebLogic Server管理コンソールとまったく別のツールを開発する場合には、この方法を選択します。
この方法では、カスタム・ロール・マッピング・プロバイダ向けにコンソール拡張を作成する必要も、管理MBeanを開発する必要もありません。ただし、ツールでは以下のことを行う必要があります。
WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。
セキュリティ・ロールを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。
カスタム・ロール・マッピング・プロバイダのデータベースの式を読み書きします。
WebLogic Server管理コンソールとは別のツールを持っており、それを管理コンソールから起動する場合には、この方法を選択します。
この方法の場合、ツールでは以下のことを行う必要があります。
WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。
セキュリティ・ロールを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。
カスタム・ロール・マッピング・プロバイダのデータベースの式を読み書きします。
『Oracle WebLogic Server管理コンソールの拡張』で説明されているように、基本的なコンソール拡張手法を使用して管理コンソールにリンクします。