ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発
12cリリース1(12.1.1)
B65927-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

9 ロール・マッピング・プロバイダ

この章では、ロール・マッピング・プロバイダの概念と機能、およびカスタム・ロール・マッピング・プロバイダの開発手順について説明します。

ロール・マッピングとは、実行時にプリンシパル(ユーザーまたはグループ)をセキュリティ・ロールに動的に割り当てるプロセスのことです。WebLogic Serverでは、ロール・マッピング・プロバイダは、WebLogicリソースを操作しようとしているサブジェクト内のプリンシパルに適用されるセキュリティ・ロールを調べます。通常、この操作ではWebLogicリソースへのアクセスを取得する必要があるので、ロール・マッピング・プロバイダは認可プロバイダと共に使用するのが一般的です。

以下の節では、ロール・マッピング・プロバイダの概念と機能、およびカスタム・ロール・マッピング・プロバイダの開発手順について説明します。

ロール・マッピングの概念

ロール・マッピング・プロバイダを開発する前に、以下の概念を理解しておく必要があります。

セキュリティ・ロール

セキュリティ・ロールは、WebLogicリソースへの同じアクセス権限を持つユーザーまたはグループの集合です。グループと同様、セキュリティ・ロールを使用すると、複数のユーザーによるWebLogicリソースへのアクセスを一度に制御できます。ただし、セキュリティ・ロールはWebLogic Serverドメインの特定のリソースをスコープとしており(WebLogic Serverドメイン全体をスコープとするグループとは異なる)、動的に定義することが可能です。「動的セキュリティ・ロール計算」を参照してください。


注意:

セキュリティ・ロールの詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。WebLogicリソースの詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』セキュリティ・プロバイダとWebLogicリソースに関する項およびポリシーで保護できるリソースのタイプに関する項を参照してください。


weblogic.security.serviceパッケージのSecurityRoleインタフェースは、セキュリティ・ロールの抽象的な記法を表すために用いられます(詳細は、Oracle WebLogic Server APIリファレンス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 JavaBean (EJB)であれば、アクセスを許可するかどうかを決めるビジネス・ポリシーを知らなくても、Java EEのisCallerInRole()メソッドを用いてデータベース内のレコードからフィールドを取得することができます。

動的セキュリティ・ロール計算を作成する場合のロール・マッピング・プロバイダとWebLogicセキュリティ・フレームワークとの対話を図9-1に示し、続いてそれについて説明します。

図9-1 ロール・マッピング・プロバイダとロール・マッピング・プロセス

図9-1の説明が続きます
「図9-1 ロール・マッピング・プロバイダとロール・マッピング・プロセス」の説明

一般に、ロール・マッピングは以下のように実行されます。

  1. ユーザーまたはシステム・プロセスがWebLogicリソースをリクエストし、特定の操作を実行しようとします。

  2. リクエストされたWebLogicリソースのタイプを処理するリソース・コンテナがリクエストを受け取ります。たとえばEJBコンテナはEJBリソースに対するリクエストを受け取ります。


    注意:

    リソース・コンテナは、「セキュリティ・プロバイダとWebLogicリソース」で説明されているWebLogicリソースのいずれかを処理するコンテナです。


  3. リソース・コンテナは、リクエストのコンテキストに関連付けられている情報を取得するためにロール・マッピング・プロバイダで使用する場合のあるContextHandlerオブジェクトを作成します。


    注意:

    ContextHandlerの詳細は、「ContextHandlerとWebLogicリソース」を参照してください。


    リソース・コンテナは、サブジェクト(ユーザーおよびグループ・プリンシパルを含む)、WebLogicリソースの識別子、そして場合によっては追加入力を提供するContextHandlerオブジェクトを渡してWebLogicセキュリティ・フレームワークを呼び出します。


    注意:

    サブジェクトの詳細は、「ユーザー/グループ、プリンシパル、サブジェクト」を参照してください。リソース識別子の詳細は、「WebLogicリソース識別子」を参照してください。


  4. WebLogicセキュリティ・フレームワークは、適用するセキュリティ・ロールのリストを取得するために、構成済みの各ロール・マッピング・プロバイダを呼び出します。この仕組みは次のとおりです。

    1. ロール・マッピング・プロバイダはContextHandlerを用いて、リクエストに関する様々な情報をリクエストします。また、ロール・マッピング・プロバイダは、リクエストする情報のタイプを表す一連のCallbackオブジェクトを作成します。そのCallbackオブジェクト群は、handleメソッドを通じて、配列としてContextHandlerに渡されます。

      ロール・マッピング・プロバイダは、必要なコンテキスト情報を取得するのに、ContextHandlerを複数回呼び出す場合があります。ロール・マッピング・プロバイダでContextHandlerが呼び出される回数はその実装によって異なります。

    2. コンテキスト情報と、セキュリティ・ポリシー、サブジェクト、およびWebLogicリソースを格納する関連セキュリティ・プロバイダ・データベースを使用することで、ロール・マッピング・プロバイダは、サブジェクト内のユーザー・プリンシパルとグループ・プリンシパルで表されるリクエスト側に特定のセキュリティ・ロールの資格があるかどうかを決定します。

      セキュリティ・ポリシーは、指定されたセキュリティ・ロールを付与すべきかどうかを判定する際に評価される一連の式すなわちルールとして表されます。これらのルールを使用する際に、ロール・マッピング・プロバイダは、取得したコンテキスト情報の値を式のパラメータに代入しなければならない場合があります。さらに、ユーザー・プリンシパルまたはグループ・プリンシパルのID情報が、式のパラメータ値として必要になることもあります。


      注意:

      セキュリティ・ポリシーのルールは、WebLogic Server管理コンソールとJava EEデプロイメント記述子で設定します。詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のセキュリティ・ポリシーに関する項を参照してください。


    3. リクエスト側に特定のセキュリティ・ロールの資格があるとセキュリティ・ポリシーに指定されている場合には、そのセキュリティ・ロールがサブジェクトに適用されるセキュリティ・ロールのリストに追加されます。

    4. このプロセスは、WebLogicリソースまたはリソース・コンテナに適用されるセキュリティ・ポリシーがすべて評価されるまで続行されます。

  5. セキュリティ・ロールのリストはWebLogicセキュリティ・フレームワークに返され、アクセス決定などの操作の一環として使用できるようになります。

カスタム・ロール・マッピング・プロバイダはスレッド・セーフか

最高のパフォーマンスを実現するため、デフォルトでは、アプリケーションおよびモジュールのデプロイメント中にセキュリティ・ポリシーおよびロールに対して並列変更を実行できます。この理由から、セキュリティ・レルムに構成されているデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている必要があります。WebLogicのデプロイ可能なXACML認可プロバイダおよびロール・マッピング・プロバイダは、この要件を満たしています。

ただし、カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダで並列呼出しがサポートされている場合とサポートされていない場合があります。カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダが並列呼出しをサポートしない場合、並列セキュリティ・ポリシーとロール変更を無効にして、かわりに各アプリケーションとモジュールがキューに配置され、連続してデプロイされる同期メカニズムを実行する必要があります。


注意:

同期化メカニズムを有効にした場合、定義済のWebLogic Serverプロバイダも含めて、レルム内に構成されているすべてのデプロイ可能なプロバイダが影響を受けます。同期化メカニズムを有効にすると、これらのプロバイダのパフォーマンスに悪影響を与える可能性があります。


この同期化強制メカニズムを有効にする方法については、『Oracle WebLogic Serverの保護』を参照してください。

カスタム・ロール・マッピング・プロバイダを開発する必要があるか

WebLogic Serverのデフォルト(つまりアクティブな)セキュリティ・レルムにはWebLogicロール・マッピング・プロバイダが含まれています。WebLogicロール・マッピング・プロバイダは、デフォルト・ユーザーとWebLogicリソースのそれぞれについて、保護されている特定のリソースに関する特定のユーザー(サブジェクト)の動的セキュリティ・ロールを計算します。また、WebLogicロール・マッピング・プロバイダは、システム内のセキュリティ・ロールのデプロイメントとアンデプロイメントをサポートしています。WebLogicロール・マッピング・プロバイダは、WebLogic認可プロバイダと同じセキュリティ・ポリシー・エンジンを使用します。自社の既存のロール・マッピング・メカニズムを使用する場合は、カスタム・ロール・マッピング・プロバイダを作成してそれを既存のメカニズムに結合できます。

カスタム・ロール・マッピング・プロバイダでアプリケーションのバージョン管理をサポートする必要があるか

セキュリティ・レルムのすべての認可プロバイダ、ロール・マッピング・プロバイダ、および資格証明マッピング・プロバイダは、アプリケーションのデプロイにバージョンを使用するために、アプリケーションのバージョン管理をサポートする必要があります。認可、ロール・マッピング、または資格証明マッピング用にカスタム・セキュリティ・プロバイダを開発する際に、バージョン管理されたアプリケーションをサポートする必要がある場合は、第14章「バージョン管理可能なアプリケーションのプロバイダ」の説明に従って、バージョン管理可能なアプリケーションのSSPIを実装する必要があります。

カスタム・ロール・マッピング・プロバイダの開発方法

WebLogicロール・マッピング・プロバイダが開発者のニーズを満たさない場合、次の手順でカスタム・ロール・マッピング・プロバイダを開発することができます。

  1. 適切なSSPIを使用してランタイム・クラスの作成または必要に応じてバルク認可プロバイダを実装

  2. 必要に応じてロール・コンシューマSSPIを実装

  3. WebLogic MBeanMakerを使用してMBeanタイプを生成する

  4. 管理コンソールによるカスタム・ロール・マッピング・プロバイダの構成

  5. セキュリティ・ロールを管理するためのメカニズムの提供

適切なSSPIによるランタイム・クラスの作成

ランタイム・クラスを作成する前に、以下の作業が必要です。

この情報を理解し、設計に関する判断を下したら、次の手順でカスタム・ロール・マッピング・プロバイダのランタイム・クラスを作成します。

カスタム・ロール・マッピング・プロバイダのランタイム・クラスの作成例については、「例:サンプル・ロール・マッピング・プロバイダのランタイム・クラスの作成」を参照してください。

RoleProvider SSPIの実装

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メソッドの詳細は、Oracle WebLogic Server APIリファレンスを参照してください。

DeployableRoleProviderV2 SSPIの実装


注意:

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メソッドの詳細は、Oracle WebLogic Server APIリファレンスを参照してください。

ApplicationInfoインタフェース

ApplicationInfoインタフェースは、アプリケーションのデプロイメントに関するデータをセキュリティ・プロバイダに渡します。このデータを使用すると、アプリケーションを一意に識別できます。

セキュリティ・フレームワークは、ユーザーの利便を図るためにApplicationInfoインタフェースを実装します。このインタフェースのメソッドを実装する必要はありません。

DeployableAuthorizationProviderV2インタフェースとDeployableRoleProviderV2インタフェースはApplicationInfoを使用します。たとえば、DeployableRoleProviderV2のメソッドの実装を例にあげます。セキュリティ・フレームワークは、DeployableRoleProviderV2startDeployRolesメソッドを呼び出し、このアプリケーションのApplicationInfoインタフェースを渡します。ApplicationInfoデータは、アプリケーションのデプロイ時に管理コンソールで提供される情報を基に決められます。

startDeployRolesメソッドは、DeployableRoleProviderV2の他のメソッドでこの後使用できるDeployRoleHandleを戻します。

ApplicationInfoインタフェースを使用すると、このアプリケーションのアプリケーション識別子、コンポーネント名、およびコンポーネントの種類を取得できます。コンポーネントの種類は、ApplicationInfo.ComponentTypeクラスの定義に従って、APPLICATIONCONTROL_RESOURCEEJB、またはWEBAPPのいずれかです。

次のコードは、このタスクを実行する方法の一例です。

public DeployRoleHandle startDeployRoles(ApplicationInfo appInfo)
    throws DeployHandleCreationException
     :
// Obtain the application information...
    String appId = appInfo.getApplicationIdentifier();
    ComponentType compType = appInfo.getComponentType();
    String compName = appInfo.getComponentName();

セキュリティ・フレームワークは、DeployableRoleProviderV2deleteApplicationRolesメソッドを呼び出し、このアプリケーションのApplicationInfoインタフェースを渡します。deleteApplicationRolesメソッドは、アプリケーションのすべてのロールを削除し、アプリケーションが削除された時点でWebLogic Serverドメイン内の管理サーバーでのみ呼び出されます。

RoleMapper SSPIの実装

RoleMapper SSPIを実装するには、以下のメソッドの実装を提供する必要があります。

  • getRoles

    public Map getRoles(Subject subject, Resource  resource, ContextHandler handler)
    

    getRolesメソッドは、場合によりContextHandlerに指定されたオプショナルな情報を使用して、特定のWebLogicリソースに関して特定のサブジェクトに関連付けられているセキュリティ・ロールを返します。ContextHandlerの詳細は、「ContextHandlerとWebLogicリソース」を参照してください。

RoleMapper SSPIとgetRolesメソッドの詳細は、Oracle WebLogic Server APIリファレンスを参照してください。

レルム・アダプタ認証プロバイダと互換性のあるカスタム・ロール・マッピング・プロバイダを開発する

認証プロバイダは、サブジェクト内へのユーザーおよびグループの格納を担当するセキュリティ・プロバイダです。ユーザーおよびグループはその後、ロール・マッピング・プロバイダなど、他のタイプのセキュリティ・プロバイダによって、サブジェクトから抽出されます。セキュリティ・レルム内で構成された認証プロバイダがレルム・アダプタ認証プロバイダである場合、ユーザーおよびグループの情報は、他の認証プロバイダとは少し異なる形でサブジェクト内に格納されます。したがって、このユーザーおよびグループの情報もまた、少し異なる方法で抽出する必要があります。

例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インタフェースのメソッドを使用して、セキュリティ・ロールに関する基本的な情報を取得したり、取得した情報を別のセキュリティ・ロールと比較したりできます。これらのメソッドは、セキュリティ・プロバイダの利便性のために設計されています。


注意:

SecurityRole実装は、getRoles()メソッドによってMapとして返されます。(RoleProvider SSPIの実装を参照)。


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クラスを示しています。このランタイム・クラスには次の実装が含まれています。

例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 "";
}
}

ロール・コンシューマSSPI

WebLogic ServerにはWebサービス・アノテーション用のロール・コンシューマが実装されています。このリリースのWebLogic Serverには、ロール・マッピング・プロバイダがロール・コレクションを取得するために使用できるSSPIがあります。

RoleConsumer SSPIは省略可能です。ロール・コレクションを消費するためには、このSSPIを実装するロール・マッピング・プロバイダのみが呼び出されます。

このSSPIでは、初期状態のロール・コレクションの配信と、更新後のロール・コレクションの配信の両方がサポートされます。

ロール・コレクションの消費においては、RoleConsumer SSPIをサポートするすべてのロール・マッピング・プロバイダが呼び出されます。各ロール・マッピング・プロバイダは、特定のロール・セットのロール・コレクションを取得するかしないかを選択できます。プロバイダでロールが永続化される場合、ロールを取得する必要があるのは一度だけです。一方、プロバイダでロールがメモリーに保持される場合、ロール・コレクションを再び取得することも可能です。

用意されているWebLogic Serverロール・マッピング・プロバイダでは、ロールはLDAP内に永続化されます。

必要なSSPIインタフェース

ロール・マッピング・プロバイダをカスタマイズしてロール・コレクションの配信をサポートするには、以下の3つのインタフェースを実装する必要があります。

  • weblogic.security.spi.RoleConsumerFactory

  • weblogic.security.spi.RoleConsumer

  • weblogic.security.spi.RoleCollectionHandler

これらのインタフェースについては、これ以降の節で説明します。

RoleConsumerFactory SSPIインタフェースの実装

ロール・マッピング・プロバイダには、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インタフェースの実装

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インタフェースの実装としてセキュリティ・プロバイダに渡します(このインタフェースはあらかじめ実装されているので、ユーザーが実装する必要はありません。)

RoleCollectionInfogetName()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();
}

RoleCollectionHandler SSPIインタフェースの実装

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で提供されているロール・マッピング・プロバイダでは、カスタマイズ後のロールが更新後のロール・コレクションで置き換えられません。初期状態のロール・コレクションのロールはすべて削除され、カスタマイズ後のロールと更新後のロール・コレクションのみが有効になります。ロール・コレクションの情報に異なるタイムスタンプやバージョンがある場合、更新後のロール・コレクションとして扱われます。コレクションの名前は永続キーとして使用されます。

RoleConsumerMBean

ロール・コンシューマSSPIを実装するロール・マッピング・プロバイダには、そのプロバイダでロールの消費をサポートすることを示すためにweblogic.management.security.authorization.RoleConsumerMBeanも実装する必要があります。

PolicyStoreMBean

このリリースの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 Policyファイルの形式の調べ

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構成が使用できなくなる可能性があります。エクスポートしたファイルの編集はサポートされていません。


WLSTを使用してPolicyStoreMBeanにポリシーの追加

例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

WLSTを使用してPolicySetをStringとして読み込む

例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>>)、サブジェクトに許可されている指定のリソースに関連付けられたセキュリティ・ロールを表します。

WebLogic MBeanMakerを使用してMBeanタイプを生成する

カスタム・セキュリティ・プロバイダのMBeanタイプを生成する前に、以下の作業が必要です。

この情報を理解し、設計に関する判断を下したら、次の手順でカスタム・ロール・マッピング・プロバイダのMBeanタイプを作成します。

  1. MBean定義ファイル(MDF)の作成

  2. WebLogic MBeanMakerを使用してMBeanタイプを生成する

  3. WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成

  4. WebLogic Server環境にMBeanタイプをインストールする


    注意:

    複数のセキュリティ・プロバイダのサンプルで、これらの手順の実行方法を示します。

    この節で説明する手順はすべて、Windows環境での作業を想定しています。


MBean定義ファイル(MDF)の作成

MBean定義ファイル(MDF)を作成するには、次の手順に従います。

  1. サンプル・ロール・マッピング・プロバイダのMDFをテキスト・ファイルにコピーします。


    注意:

    サンプル・ロール・マッピング・プロバイダのMDFは、SimpleSampleRoleMapper.xmlという名前です。


  2. MDFで<MBeanType>要素と<MBeanAttribute>要素の内容をカスタム・ロール・マッピング・プロバイダに合わせて修正します。

  3. カスタム属性および操作(つまり、<MBeanAttribute>および<MBeanOperation>要素)をMDFに追加します。

  4. ファイルを保存します。


    注意:

    MDF要素の構文についての詳細なリファレンスは、付録A「MBean定義ファイル(MDF)要素の構文」に収められています。


WebLogic MBeanMakerを使用してMBeanタイプを生成する

MDFを作成したら、WebLogic MBeanMakerを使用してそれを実行できます。WebLogic MBeanMakerは現在のところコマンドライン・ユーティリティで、入力としてMDFを受け取り、MBeanインタフェース、MBean実装、関連するMBean情報ファイルなどの中間Javaファイルをいくつか出力します。これらの中間ファイルが合わさって、カスタム・セキュリティ・プロバイダのMBeanタイプになります。

MBeanタイプの生成手順は、カスタム・ロール・マッピング・プロバイダの設計に応じて異なります。必要な設計に合わせて適切な手順を実行してください。

カスタム操作を追加しない場合

カスタム・ロール・マッピング・プロバイダのMDFにカスタム操作を含めない場合、次の手順に従います。

  1. 新しいDOSシェルを作成します。

  2. 次のコマンドを入力します。

    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 (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。


  3. 「WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成」に進みます。

カスタム操作を追加する場合

カスタム・ロール・マッピング・プロバイダのMDFにカスタム操作を含める場合、質問に答えながら手順を進めてください。

MBeanタイプを作成するのは初めてですか。その場合は、次の手順に従ってください:

  1. 新しいDOSシェルを作成します。

  2. 次のコマンドを入力します。

    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 (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。


  3. MDFのすべてのカスタム操作に対して、メソッド・スタブを使用してメソッドを実装します。

  4. ファイルを保存します。

  5. 「WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成」に進みます。

既存のMBeanタイプの更新ですか。その場合は、次の手順に従ってください:

  1. WebLogic MBeanMakerによって現在のメソッドの実装が上書きされないように、既存のMBean実装ファイルを一時ディレクトリにコピーします。

  2. 新しいDOSシェルを作成します。

  3. 次のコマンドを入力します。

    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 (つまりロール・マッピング・プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。


  4. MDFを変更して元のMDFにはないカスタム操作を含めた場合、メソッド・スタブを使用してメソッドを実装します。

  5. 完成した、つまりすべてのメソッドを実装したMBean実装ファイルを保存します。

  6. このMBean実装ファイルを、WebLogic MBeanMakerがMBeanタイプの実装ファイルを配置したディレクトリにコピーします。このディレクトリは、手順3でfilesdirとして指定したものです。(ステップ3の結果としてWebLogic MBeanMakerで生成されたMBean実装ファイルがオーバーライドされます)。

  7. 「WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成」に進みます。

生成されるMBeanインタフェース・ファイルについて

MBeanインタフェース・ファイルとは、ランタイム・クラスまたはMBean実装が構成データを取得するために使用するMBeanのクライアント側APIです。「「Provider」SSPIの目的について」で説明されているように、これはinitializeメソッドで使用するのが一般的です。

WebLogic MBeanMakerでは、作成済のMDFからMBeanタイプを生成するので、生成されるMBeanインタフェース・ファイルの名前は、そのMDF名の後に「MBean」というテキストが付いたものになります。たとえば、WebLogic MBeanMakerでSampleRoleMapper MDFを実行すると、SampleRoleMapperMBean.javaというMBeanインタフェース・ファイルが生成されます。

WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成

WebLogic MBeanMakerでMDFを実行して中間ファイルを作成し、MBean実装ファイルを編集して適切なメソッドの実装を提供したら、カスタム・ロール・マッピング・プロバイダのMBeanファイルとランタイム・クラスをMBean JARファイル(MJF)にパッケージ化する必要があります。このプロセスも、WebLogic MBeanMakerによって自動化されます。

カスタム・ロール・マッピング・プロバイダのMJFを作成するには、次の手順に従います。

  1. 新しいDOSシェルを作成します。

  2. 次のコマンドを入力します。

    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環境にインストールしてもらうこともできます。

WebLogic Server環境にMBeanタイプをインストールする

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タイプをロードします。その後で、追加ディレクトリにあるすべての有効なアーカイブを検索して、ロードします。このとき拡張子は考慮されません。

たとえば、-Dweblogic.alternateTypesDirectory = dirX,dirYの場合、WebLogic ServerはまずWL_HOME\server\lib\mbeantypesからMBeanタイプをロードし、次にdirXおよびdirYにある有効なアーカイブをロードします。WebLogic Serverに追加ディレクトリでMBeanタイプを検索するよう指示する際に、Javaセキュリティ・マネージャを使用している場合は、weblogic.policyファイルを更新して、MBeanタイプ(その結果として、カスタム・セキュリティ・プロバイダ)に適した許可を付与することも必要になります。詳細は、『Oracle WebLogic Serverセキュリティのプログラミング』のJavaセキュリティを使用したWebLogicリソースの保護に関する項を参照してください。


カスタム・ロール・マッピング・プロバイダを構成することによって(「管理コンソールによるカスタム・ロール・マッピング・プロバイダの構成」を参照)、MBeanタイプのインスタンスを作成して、GUI、他のJavaコード、またはAPIからそれらのMBeanインスタンスを使用することができます。たとえば、WebLogic Server管理コンソールを使用して、属性を取得/設定したり操作を呼び出したりすることもできますし、他のJavaオブジェクトを開発して、そのオブジェクトでMBeanをインスタンス化し、それらのMBeanから提供される情報に自動的に応答させることもできます。なお、これらのMBeanインスタンスをバックアップしておくことをお薦めします。

管理コンソールによるカスタム・ロール・マッピング・プロバイダの構成

カスタム・ロール・マッピング・プロバイダを構成するということは、ロール・マッピング・サービスを必要とするアプリケーションがアクセス可能なセキュリティ・レルムにカスタム・ロール・マッピング・プロバイダを追加するということです。

カスタム・セキュリティ・プロバイダの構成は管理タスクですが、カスタム・セキュリティ・プロバイダの開発者が行うこともできます。この節では、カスタム・ロール・マッピング・プロバイダの構成担当者向けの重要な情報を取り上げます。

ロール・マッピング・プロバイダとデプロイメント記述子の管理

Enterprise JavaBeans (EJB)やWebアプリケーションなどのアプリケーションの中には、Java EEの関連デプロイメント情報とWebLogic Serverデプロイメント記述子を格納するものがあります。Webアプリケーションの場合、デプロイメント記述子ファイル(web.xmlweblogic.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>

例9-7 weblogic.xmlファイルのサンプル

<weblogic-web-app> 
   <security-role-assignment> 
      <role-name>developers</role-name>
      <principal-name>myGroup</principal-name> 
   </security-role-assignment> 
</weblogic-web-app>

セキュリティ・ロール・デプロイメントの有効化

カスタム・ロール・マッピング・プロバイダの開発の一環としてDeployableRoleProviderV2 SSPIを実装し、デプロイ可能なセキュリティ・ロールをサポートする場合、カスタム・ロール・マッピング・プロバイダの構成担当者(つまり、開発者または管理者)は、WebLogic Server管理コンソールで「ロール・デプロイメントを有効化」ボックスがチェックされていることを確認する必要があります。チェックがはずれていると、ロール・マッピング・プロバイダに対するデプロイメントは「オフ」と見なされます。このため、複数のロール・マッピング・プロバイダが構成されている場合、「ロール・デプロイメントを有効化」ボックスを使用して、セキュリティ・ロールのデプロイメントに使用するロール・マッピング・プロバイダを指定できます。

セキュリティ・ロールを管理するためのメカニズムの提供

WebLogic Server管理コンソールを使用してカスタム・ロール・マッピング・プロバイダを構成すると、必要なロール・マッピング・サービスにアプリケーションからアクセスできるようにすることはできますが、このセキュリティ・プロバイダに関連付けられたセキュリティ・ロールを管理する方法を管理者にも提供する必要があります。たとえばWebLogicロール・マッピング・プロバイダには、ロール・エディタ・ページが管理者向けに用意されており、様々なWebLogicリソースのセキュリティ・ロールを追加、変更、または削除することができます。

カスタム・ロール・マッピング・プロバイダを開発すると、管理者はロール・エディタ・ページも右クリック・メニューも利用できません。したがって、セキュリティ・ロールを管理するための独自のメカニズムを提供する必要があります。このメカニズムでは、カスタム・ロール・マッピング・プロバイダのデータベースのセキュリティ・ロール・データ(つまり式)を読み書きできなければなりません。

それには、以下の2通りの方法があります。

オプション1 :セキュリティ・ロール管理用のスタンドアロン・ツールの開発

WebLogic Server管理コンソールとまったく別のツールを開発する場合には、この方法を選択します。

この方法では、カスタム・ロール・マッピング・プロバイダ向けにコンソール拡張を作成する必要も、管理MBeanを開発する必要もありません。ただし、ツールでは以下のことを行う必要があります。

  1. WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。

  2. セキュリティ・ロールを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。

  3. カスタム・ロール・マッピング・プロバイダのデータベースの式を読み書きします。

オプション2 : 管理コンソールに既存のセキュリティ・ロール管理ツールの統合

WebLogic Server管理コンソールとは別のツールを持っており、それを管理コンソールから起動する場合には、この方法を選択します。

この方法の場合、ツールでは以下のことを行う必要があります。

  1. WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。

  2. セキュリティ・ロールを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。

  3. カスタム・ロール・マッピング・プロバイダのデータベースの式を読み書きします。

  4. 『Oracle WebLogic Server管理コンソールの拡張』で説明されているように、基本的なコンソール拡張手法を使用して管理コンソールにリンクします。