| Oracle® Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発 11gリリース1(10.3.6) B61623-04 |
|
![]() 前 |
![]() 次 |
ロール・マッピングとは、実行時にプリンシパル(ユーザーまたはグループ)をセキュリティ・ロールに動的に割り当てるプロセスのことです。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セキュリティ・フレームワークで評価される式に含まれるパラメータの値として使用されます。この機能は、デプロイメント記述子またはWebLogic Server管理コンソールを通じて静的に定義されたセキュリティ・ロールの計算も担当します。
|
注意: 認証済みユーザーに対するセキュリティ・ロールの計算は、Java EE仕様で定義されているロール・ベース・アクセス制御(RBAC)によるセキュリティ機能を拡張したものです。動的なセキュリティ・ロール計算を作成するには、WebLogic Server管理コンソールでロール文を定義します。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。 |
WebLogicセキュリティ・フレームワークは、認可判定の一環として、セキュリティ・レルム用に構成されている各ロール・マッピング・プロバイダを呼び出します。関連情報については、「認可プロセス」を参照してください。
ロール・マッピング・プロバイダによる動的セキュリティ・ロール関連計算の結果、一連のセキュリティ・ロールが一度にサブジェクト内のプリンシパルに割り当てられます。その後、これらのセキュリティ・ロールを用いて、保護対象WebLogicリソース、リソース・コンテナ、およびアプリケーション・コードについての認可判定が行われます。たとえば、Enterprise JavaBeans (EJB)であれば、アクセスを許可するかどうかを決めるビジネス・ポリシーを知らなくても、Java EEのisCallerInRole()メソッドを用いてデータベース内のレコードからフィールドを取得することができます。
動的セキュリティ・ロール計算を作成する場合のロール・マッピング・プロバイダとWebLogicセキュリティ・フレームワークとの対話を図9-1に示し、続いてそれについて説明します。
一般に、ロール・マッピングは以下のように実行されます。
ユーザーまたはシステム・プロセスがWebLogicリソースをリクエストし、特定の操作を実行しようとします。
リクエストされたWebLogicリソースのタイプを処理するリソース・コンテナがリクエストを受け取ります。たとえばEJBコンテナはEJBリソースに対するリクエストを受け取ります。
リソース・コンテナは、リクエストのコンテキストに関連付けられている情報を取得するためにロール・マッピング・プロバイダで使用する場合のあるContextHandlerオブジェクトを作成します。
リソース・コンテナは、サブジェクト(ユーザーおよびグループ・プリンシパルを含む)、WebLogicリソースの識別子、そして場合によっては追加入力を提供するContextHandlerオブジェクトを渡してWebLogicセキュリティ・フレームワークを呼び出します。
WebLogicセキュリティ・フレームワークは、適用するセキュリティ・ロールのリストを取得するために、構成済みの各ロール・マッピング・プロバイダを呼び出します。この仕組みは次のとおりです。
ロール・マッピング・プロバイダはContextHandlerを用いて、リクエストに関する様々な情報をリクエストします。また、ロール・マッピング・プロバイダは、リクエストする情報のタイプを表す一連のCallbackオブジェクトを作成します。そのCallbackオブジェクト群は、handleメソッドを通じて、配列としてContextHandlerに渡されます。
ロール・マッピング・プロバイダは、必要なコンテキスト情報を取得するのに、ContextHandlerを複数回呼び出す場合があります。ロール・マッピング・プロバイダでContextHandlerが呼び出される回数はその実装によって異なります。
コンテキスト情報と、セキュリティ・ポリシー、サブジェクト、およびWebLogicリソースを格納する関連セキュリティ・プロバイダ・データベースを使用することで、ロール・マッピング・プロバイダは、サブジェクト内のユーザー・プリンシパルとグループ・プリンシパルで表されるリクエスト側に特定のセキュリティ・ロールの資格があるかどうかを決定します。
セキュリティ・ポリシーは、指定されたセキュリティ・ロールを付与すべきかどうかを判定する際に評価される一連の式すなわちルールとして表されます。これらのルールを使用する際に、ロール・マッピング・プロバイダは、取得したコンテキスト情報の値を式のパラメータに代入しなければならない場合があります。さらに、ユーザー・プリンシパルまたはグループ・プリンシパルのID情報が、式のパラメータ値として必要になることもあります。
|
注意: セキュリティ・ポリシーのルールは、WebLogic Server管理コンソールとJava EEデプロイメント記述子で設定します。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のセキュリティ・ポリシーに関する項を参照してください。 |
リクエスト側に特定のセキュリティ・ロールの資格があるとセキュリティ・ポリシーに指定されている場合には、そのセキュリティ・ロールがサブジェクトに適用されるセキュリティ・ロールのリストに追加されます。
このプロセスは、WebLogicリソースまたはリソース・コンテナに適用されるセキュリティ・ポリシーがすべて評価されるまで続行されます。
セキュリティ・ロールのリストはWebLogicセキュリティ・フレームワークに返され、アクセス決定などの操作の一環として使用できるようになります。
最高のパフォーマンスを実現するため、デフォルトでは、アプリケーションおよびモジュールのデプロイメント中にセキュリティ・ポリシーおよびロールに対して並列変更を実行できます。この理由から、セキュリティ・レルムに構成されているデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている必要があります。WebLogicのデプロイ可能なXACML認可プロバイダおよびロール・マッピング・プロバイダは、この要件を満たしています。
ただし、カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダで並列呼出しがサポートされている場合とサポートされていない場合があります。カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダが並列呼出しをサポートしない場合、並列セキュリティ・ポリシーとロール変更を無効にして、かわりに各アプリケーションとモジュールがキューに配置され、連続してデプロイされる同期メカニズムを実行する必要があります。
|
注意: 同期化メカニズムを有効にした場合、定義済のWebLogic Serverプロバイダも含めて、レルム内に構成されているすべてのデプロイ可能なプロバイダが影響を受けます。同期化メカニズムを有効にすると、これらのプロバイダのパフォーマンスに悪影響を与える可能性があります。 |
この同期化強制メカニズムを有効にする方法については、『Oracle WebLogic Serverの保護』を参照してください。
WebLogic Serverのデフォルト(つまりアクティブな)セキュリティ・レルムにはWebLogicロール・マッピング・プロバイダが含まれています。WebLogicロール・マッピング・プロバイダは、デフォルト・ユーザーとWebLogicリソースのそれぞれについて、保護されている特定のリソースに関する特定のユーザー(サブジェクト)の動的セキュリティ・ロールを計算します。また、WebLogicロール・マッピング・プロバイダは、システム内のセキュリティ・ロールのデプロイメントとアンデプロイメントをサポートしています。WebLogicロール・マッピング・プロバイダは、WebLogic認可プロバイダと同じセキュリティ・ポリシー・エンジンを使用します。自社の既存のロール・マッピング・メカニズムを使用する場合は、カスタム・ロール・マッピング・プロバイダを作成してそれを既存のメカニズムに結合できます。
セキュリティ・レルムのすべての認可プロバイダ、ロール・マッピング・プロバイダ、および資格証明マッピング・プロバイダは、アプリケーションのデプロイにバージョンを使用するために、アプリケーションのバージョン管理をサポートする必要があります。認可、ロール・マッピング、または資格証明マッピング用にカスタム・セキュリティ・プロバイダを開発する際に、バージョン管理されたアプリケーションをサポートする必要がある場合は、第14章「バージョン管理可能なアプリケーションのプロバイダ」の説明に従って、バージョン管理可能なアプリケーションの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インタフェースは、アプリケーションのデプロイメントに関するデータをセキュリティ・プロバイダに渡します。このデータを使用すると、アプリケーションを一意に識別できます。
セキュリティ・フレームワークは、ユーザーの利便を図るためにApplicationInfoインタフェースを実装します。このインタフェースのメソッドを実装する必要はありません。
DeployableAuthorizationProviderV2インタフェースとDeployableRoleProviderV2インタフェースはApplicationInfoを使用します。たとえば、DeployableRoleProviderV2のメソッドの実装を例にあげます。セキュリティ・フレームワークは、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();
セキュリティ・フレームワークは、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にはWebサービス・アノテーション用のロール・コンシューマが実装されています。このリリースの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セキュリティ・フレームワークで使用できるように、RoleConsumerFactoryインタフェースが実装されています。WebLogicセキュリティ・フレームワークでは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セキュリティ・フレームワークでは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管理コンソールから管理できるようになります。
|
注意: MBeanタイプをインストールするデフォルトのディレクトリは、WL_HOME\server\lib\mbeantypesです。初めて使用するバージョンが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セキュリティ・サービスに統合され、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管理コンソールの拡張』で説明されているように、基本的なコンソール拡張手法を使用して管理コンソールにリンクします。