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

前
 
次
 

4 認証プロバイダ

認証は、呼出し側が、特定のユーザーまたはシステムのかわりに動作していることを証明する際に使用するメカニズムです。認証は、ユーザー名とパスワードの組合せなどの資格証明を使用して「あなたは誰」という問いに答えます。

WebLogic Serverでは、ユーザーまたはシステム・プロセスのIDを証明するために認証プロバイダを使用します。認証プロバイダでは、ID情報を記憶したり、トランスポートしたり、その情報が必要な場合にサブジェクトを通じてシステムの様々なコンポーネントで利用できるようにしたりします。認証プロセスでは、プリンシパル検証プロバイダが、サブジェクト内に格納されるプリンシパル(ユーザーおよびグループ)のセキュリティを強化するため、それらのプリンシパルに署名して信頼性を検証します。(詳細については、第6章「プリンシパル検証プロバイダ」を参照してください。)

以下の節では、認証プロバイダの概念と機能、およびカスタム認証プロバイダの開発手順について説明します。

認証の概念

カスタム認証プロバイダの開発の詳細に立ち入る前に、以下の概念を理解しておくことが大切です。

ユーザー/グループ、プリンシパル、サブジェクト

ユーザーは、人を表すという点でオペレーティング・システムのユーザーに似ています。一方、グループはユーザーのカテゴリで、肩書きなどの共通の特徴で分類されたものです。ユーザーをグループに分類すると、多数のユーザーに対するアクセス許可を管理しやすくなります。ユーザーおよびグループの詳細は、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』のユーザー、グループおよびセキュリティ・ロールに関する項を参照してください。

WebLogic Serverのようなアプリケーション・サーバーでは、ユーザーもグループもプリンシパルとして使用することができます。プリンシパルは、認証の結果としてユーザーまたはグループに割り当てられるIDです。JAAS (Java Authentication and Authorization Service)では、プリンシパルなどの認証情報のコンテナとしてサブジェクトを使用することになっています。同じサブジェクト内に格納されている各プリンシパルは、ある人の財布に入っている複数のカードのように、同じユーザーのIDを異なる観点で表しています。たとえば、持ち主の身元を銀行に示すためにATMカードがあり、所属する組織に示すためにメンバーシップ・カードがある、という具合です。JAASの詳細は、「Java Authentication and Authorization Service (JAAS)」を参照してください。


注意:

サブジェクトは、WebLogic Server 6.xのユーザーに取ってかわるものです。

図4-1に、ユーザー、グループ、プリンシパル、およびサブジェクト間の関係を示します。

図4-1 ユーザー、グループ、プリンシパル、およびサブジェクト間の関係

図4-1の説明が続きます
「図4-1 ユーザー、グループ、プリンシパル、およびサブジェクト間の関係」の説明

認証に成功すると、その一環として、プリンシパルは署名され、その後の使用に備えてサブジェクトに格納されます。プリンシパルに署名するのはプリンシパル検証プロバイダであり、実際にプリンシパルをサブジェクトに格納するのはLoginModuleです。後で、サブジェクト内に格納されたプリンシパルに呼出し側がアクセスしようとすると、そのプリンシパルが署名されてから変更されていないことをプリンシパル検証プロバイダが確認したうえで、そのプリンシパルが呼出し側に返されます(それ以外のセキュリティ条件がすべて満たされている場合)。


注意:

プリンシパル検証プロバイダとLoginModuleの詳細は、それぞれ第6章「プリンシパル検証プロバイダ」「LoginModule」を参照してください。

WebLogic Serverユーザーまたはグループを表すプリンシパルは、weblogic.security.spiパッケージのWLSUserインタフェースとWLSGroupインタフェースを実装する必要があります。

初期ユーザーおよびグループの指定

認証プロバイダでは、実行中のWebLogic Serverで認証を実行する前にユーザーとグループのリストが必要です。一部の認証プロバイダを使用すると、管理者は外部データベースを構成し(LDAPサーバーまたはDBMSにユーザーおよびグループを追加するなど)、そのデータベースを使用するようにプロバイダを構成できます。管理者が外部データベースのツールを使用してユーザーとグループをあらかじめ指定するので、これらのプロバイダはどのようにユーザーとグループが指定されたかを認識する必要はありません。

ただし、一部の認証プロバイダは、独自のユーザーとグループのリストを作成および管理します。ManageableSampleAuthenticatorプロバイダ(Oracle Technology Network Webサイトのhttps://codesamples.samplecode.oracle.com/servlets/tracking?id=S224から入手可能)がそれに当てはまります。この場合、認証プロバイダは、ユーザーとグループの初期セットがどのように指定されたかを認識する必要があります。これを行う方法としては、プロバイダの初期化メソッドで、ユーザーとグループがまだないことを通知し、ユーザーとグループの初期セットを指定してリストを作成するというものがあります。

一部のプロバイダは、セキュリティ・レルムごとにユーザーとグループの個別のリストを持っているので、新しいレルムで最初にリストを使用する場合に、ユーザーとグループの初期セットを作成する必要があります。たとえば、ManageableSampleAuthenticatorプロバイダは、ユーザーとグループの個別のプロパティ・ファイルをレルムごとに作成します。この認証プロバイダのinitializeメソッドは、レルム名を取得して、そのレルムのプロパティ・ファイルが存在するかどうかを判別し、存在しない場合は、ユーザーとグループの初期セットでプロパティ・ファイルを作成します。

LoginModule

LoginModuleは、認証プロバイダの必須コンポーネントであり、境界認証用に別個のLoginModuleを開発する必要がある場合はIDアサーション・プロバイダのコンポーネントにもなります。

LoginModuleは、認証処理における「馬車馬」のような存在です。すべてのLoginModuleは、セキュリティ・レルム内のユーザーの認証と、サブジェクト内への必要なプリンシパル(ユーザー/グループ)の格納を担当します。境界認証に使用されないLoginModuleも、提示された証明情報(たとえば、ユーザーのパスワード)が正しいかどうかを確認します。


注意:

IDアサーション・プロバイダと境界認証の詳細は、第5章「IDアサーション・プロバイダ」を参照してください。

セキュリティ・レルムに複数の認証プロバイダが構成されている場合、各認証プロバイダのLoginModuleは同じサブジェクトにプリンシパルを格納します。したがって、ある認証プロバイダのLoginModuleによって、WebLogic Serverユーザー(WLSUserインタフェースの実装)を表すプリンシパル「Joe」が追加された場合、セキュリティ・レルム内の他のすべての認証プロバイダは、「Joe」に出会ったときに同じ人物を参照する必要があります。つまり、他の認証プロバイダのLoginModuleは、同じ人物を参照するために、WebLogic Serverユーザーを表す別のプリンシパル(「Joseph」など)をサブジェクトに追加しようとしてはなりません。ただし、別の認証プロバイダのLoginModuleは、WLSUser以外のタイプのプリンシパルを「Joseph」という名前で追加することができます。

LoginModuleインタフェース

LoginModuleは、ユーザー名とパスワードの組合せ、スマート・カード、バイオメトリック装置などの様々な認証メカニズムを扱うように作成することができます。LoginModuleを開発するには、JAAS (Java Authentication and Authorization Service)に基づき、認証情報のコンテナとしてサブジェクトを使用するjavax.security.auth.spi.LoginModuleインタフェースを実装します。LoginModuleインタフェースを使用すると、単一アプリケーション用に様々な種類の認証技術をプラグインすることができ、WebLogicセキュリティ・フレームワークはマルチパート認証用に複数のLoginModule実装をサポートするように設計されています。さらに、LoginModuleインスタンス間に依存関係を設けたり、それらのインスタンス間で資格証明を共有することもできます。ただし、LoginModuleと認証プロバイダの関係は1対1です。つまり、網膜スキャン認証を扱うLoginModuleと、スマート・カードのようなハードウェア・デバイスとのインタフェースを取るLoginModuleを用意するには、それぞれにLoginModuleインタフェースの実装が含まれる2つの認証プロバイダを開発して構成する必要があります。詳細については、「JAAS LoginModuleインタフェースの実装」を参照してください。


注意:

LoginModuleは、独自に開発するのではなくサード・パーティのセキュリティ・ベンダーから入手することもできます。

LoginModuleとマルチパート認証

複数の認証プロバイダ(その結果として複数のLoginModule)を構成する方法は、認証プロセスの全体的な結果に影響します。これは、さまざまな要素から成る認証で特に重要です。まず、LoginModuleは認証プロバイダのコンポーネントであるため、認証プロバイダが構成された順序で呼び出されます。通常、認証プロバイダの構成には、WebLogic Server管理コンソールを使用します。(詳細については、「認証プロバイダの順序の指定」を参照)次に、各LoginModuleの制御フラグがどのように設定されるかによって、認証プロセスでのエラーの処理方法が決まります。図4-2は、それぞれ別の認証プロバイダに属する3つのLoginModuleが関わるサンプル・フローを示すとともに、様々な認証結果でサブジェクトに何が起こるのかを示しています。

図4-2 LoginModuleのサンプル・フロー

図4-2の説明が続きます
「図4-2 LoginModuleのサンプル・フロー」の説明

カスタム認証プロバイダ#1の制御フラグがREQUIREDに設定されていた場合、ユーザー認証ステップで認証が失敗すると、認証プロセス全体が失敗します。また、ユーザーがWebLogic認証プロバイダ(またはカスタム認証プロバイダ#2)によって認証されなかった場合、認証プロセス全体が失敗します。認証プロセスがこのように失敗した場合、3つのLoginModuleすべてがロールバックされ、サブジェクトにプリンシパルが格納されません。


注意:

LoginModule制御フラグの設定とLoginModuleインタフェースの詳細は、『Java Authentication and Authorization Service (JAAS) 1.0 LoginModule Developer's Guide』(http://download.oracle.com/javase/6/docs/technotes/guides/security/)およびJava SE 6.0 API仕様のLoginModuleインタフェース(http://download.oracle.com/javase/6/docs/api/javax/security/auth/spi/LoginModule.html)をそれぞれ参照してください。

JAAS (Java Authentication and Authorization Service)

クライアントが認証の必要なアプリケーション、アプレット、Enterprise JavaBean (EJB)、あるいはサーブレットのいずれであろうと、WebLogic Serverでは、JAAS (Java Authentication and Authorization Service)クラスを用いて、信頼性とセキュリティを確保しつつクライアントに対する認証を行います。JAASは、プラガブルな認証モジュール(PAM)フレームワークのJavaバージョンを実装します。このフレームワークにより、アプリケーションは基底の認証技術から独立することができます。このため、PAMフレームワークを利用することで、アプリケーションに修正を加えることなく新しいまたは更新された認証技術を使用することができます。

WebLogic Serverは、リモートのファット・クライアントの認証および内部の認証でJAASを使用します。したがって、JAASに直に関与する必要があるのは、カスタム認証プロバイダの開発者とリモート・ファット・クライアント・アプリケーションの開発者だけです。シン・クライアントのユーザーまたはコンテナ内のファット・クライアント・アプリケーション(サーブレットからEnterprise JavaBeansを呼び出すものなど)の開発者は、JAASを直接使用したり、その知識を身につけたりする必要はありません。

JAASがWebLogicセキュリティ・フレームワークとどう連携するか

通常、JAASクラスとWebLogicセキュリティ・フレームワークを用いた認証は、以下のように実行されます:

  1. クライアント側アプリケーションがユーザーまたはシステム・プロセスから認証情報を取得します。このときのメカニズムは、クライアントのタイプごとに異なります。

  2. クライアント側アプリケーションでは、認証情報が格納されたCallbackHandlerを任意に作成できます。

    1. クライアント側アプリケーションは、LoginContextクラスを使用してCallbackHandlerをローカル(クライアント側) LoginModuleに渡します。ローカルLoginModuleは、WebLogic Serverの一部として提供されているUsernamePasswordLoginModuleの場合があります。

    2. ローカルLoginModuleは、認証情報が格納されたCallbackHandlerを適切なWebLogic Serverコンテナ(RMI、EJB、サーブレット、IIOPなど)に渡します。


      注意:

      CallbackHandlerは、可変個の引数を複合オブジェクトとしてメソッドに渡すことができるようにする高度に柔軟なJAAS規格です。CallbackHandlerのタイプは、NameCallback、PasswordCallback、およびTextInputCallbackの3つで、いずれもjavax.security.auth.callbackパッケージに収められています。NameCallbackとPasswordCallbackは、それぞれユーザー名とパスワードを返します。TextInputCallbackは、ユーザーがログイン・フォームの追加フィールド(ユーザー名とパスワードを取得するフィールド以外のフィールド)に入力したデータにアクセスするために使用します。TextInputCallbackはフォームの追加フィールドにつき1つ必要で、各TextInputCallbackのプロンプト文字列はフォームのフィールド名と一致する必要があります。WebLogic Serverは、フォームベースのWebアプリケーション・ログインに対してのみTextInputCallbackを使用します。CallbackHandlerの詳細は、Java SE 6.0 API仕様のCallbackHandlerインタフェース(http://download.oracle.com/javase/6/docs/api/javax/security/auth/callback/CallbackHandler.html)を参照してください。

      LoginContextクラスの詳細は、Java SE 6.0 API仕様のLoginContextクラス(http://download.oracle.com/javase/6/docs/api/javax/security/auth/spi/LoginModule.html)を参照してください。

      UsernamePasswordLoginModuleの詳細は、WebLogic Server APIリファレンスJavadocUsernamePasswordLoginModuleクラスを参照してください。

      クライアント側LoginModuleを使用しない場合、ユーザー名とパスワードを他の方法で(たとえば初期JNDIルックアップの一部として)指定できます。


  3. WebLogic Serverコンテナは、WebLogicセキュリティ・フレームワークに働きかけを行います。認証情報が格納されたクライアント側CallbackHandlerが存在する場合、それがWebLogicセキュリティ・フレームワークに渡されます。

  4. WebLogicセキュリティ・フレームワークにより、渡された認証情報を使用して、構成されている認証プロバイダごとにCallbackHandlerが作成されます。これらはWebLogicセキュリティ・フレームワークによってサーバー側に作成された内部的なCallbackHandlerであり、クライアントのCallbackHandlerとは関係ありません。

  5. WebLogicセキュリティ・フレームワークは、認証プロバイダに関連付けられたLoginModule (認証情報を処理するために指定された特定のLoginModule)を呼び出します。


    注意:

    LoginModuleの詳細は、「LoginModule」を参照してください。

    LoginModuleが認証情報を利用してクライアントを認証しようとします。

  6. 認証に成功すると、以下の処理が行われます。

    1. プリンシパル検証プロバイダによってプリンシパル(ユーザーおよびグループ)が署名され、プログラムによるサーバー呼出し間での信頼性が確保されます。プリンシパル検証プロバイダの詳細は、第6章「プリンシパル検証プロバイダ」を参照してください。

    2. LoginModuleは署名済みのプリンシパルをサブジェクトに関連付けます。そのオブジェクトが認証対象のユーザーまたはシステム・プロセスを表します。サブジェクトとプリンシパルの詳細については、「ユーザー/グループ、プリンシパル、サブジェクト」を参照してください。


      注意:

      サーバー側ですべてが行われる認証の場合、プロセスはステップ3から始まり、WebLogic Serverコンテナはステップ4の前にweblogic.security.services.authentication.loginメソッドを呼び出します。

例:スタンドアロンのT3アプリケーション

スタンドアロンのT3アプリケーションの場合にJAASクラスがWebLogicセキュリティ・フレームワークとどう連携するかを図4-3に示し、続いてそれについて説明します。

図4-3 JAASクラスとWebLogic Serverを用いた認証

図4-3の説明が続きます
「図4-3 JAASクラスとWebLogic Serverを用いた認証」の説明

この例で、JAASクラスとWebLogicセキュリティ・フレームワークを用いた認証は以下のように実行されます。

  1. T3アプリケーションがユーザーまたはシステム・プロセスから認証情報(ユーザー名、パスワード、およびURL)を取得します。

  2. T3アプリケーションは、認証情報が格納されたCallbackHandlerを作成します。

    1. T3アプリケーションは、LoginContextクラスを使用してCallbackHandlerUsernamePasswordLoginModuleに渡します。


      注意:

      weblogic.security.auth.login.UsernamePasswordLoginModuleは標準のJAAS javax.security.auth.spi.LoginModuleインタフェースを実装し、クライアント側のAPIを使用してWebLogic Serverインスタンスに対するWebLogicクライアントの認証を行います。これは、T3クライアントとIIOPクライアントの両方で使用できます。このLoginModuleの呼出し側では、CallbackHandlerを実装してユーザー名(NameCallback)、パスワード(PasswordCallback)、およびURL (URLCallback)を渡す必要があります。

    2. UsernamePasswordLoginModuleは、認証情報(ユーザー名、パスワード、およびURL)が格納されたCallbackHandlerをWebLogic Server RMIコンテナに渡します。

  3. WebLogic Server RMIコンテナは、WebLogicセキュリティ・フレームワークに働きかけを行います。認証情報が格納されたクライアント側CallbackHandlerがWebLogicセキュリティ・フレームワークに渡されます。

  4. WebLogicセキュリティ・フレームワークにより、渡されたユーザー名、パスワード、およびURLの格納されたCallbackHandlerが、構成されている認証プロバイダごとに作成されます。これらはWebLogicセキュリティ・フレームワークによってサーバー側に作成された内部的なCallbackHandlerであり、クライアントのCallbackHandlerとは関係ありません。

  5. WebLogicセキュリティ・フレームワークは、認証プロバイダに関連付けられたLoginModule (認証情報を処理するために指定された特定のLoginModule)を呼び出します。

    LoginModuleが認証情報を利用してクライアントを認証しようとします。

  6. 認証に成功すると、以下の処理が行われます。

    1. プリンシパル検証プロバイダによってプリンシパル(ユーザーおよびグループ)が署名され、プログラムによるサーバー呼出し間での信頼性が確保されます。

    2. LoginModuleは署名済みのプリンシパルをサブジェクトに関連付けます。そのオブジェクトが認証対象のユーザーまたはシステムを表します。

    3. WebLogicセキュリティ・フレームワークは認証ステータスをT3クライアント・アプリケーションに返し、T3クライアント・アプリケーションは認証済みのサブジェクトをWebLogicセキュリティ・フレームワークから受け取ります。

認証プロセス

図4-4に、ファット・クライアント・ログインの認証プロセスの仕組みを示します。JAASはサーバー上で動作してログインを実行します。シン・クライアント・ログイン(ブラウザ・クライアント)の場合でも、JAASはサーバー上で動作します。

図4-4 認証プロセス

図4-4の説明が続きます
「図4-4 認証プロセス」の説明


注意:

JAASプロセスを直接扱うのは、カスタム認証プロバイダの開発者だけです。クライアント・アプリケーションは、JNDI初期コンテキスト作成またはJAASのいずれかを使用してユーザー名とパスワードを受け渡します。

ユーザーがユーザー名とパスワードの組合せを使用してシステムにログインしようとすると、WebLogic Serverはそのユーザーのユーザー名とパスワードを検証することによって信頼を確立し、JAASの要件に従って、プリンシパルが格納されたサブジェクトを返します。図4-4にも示されているように、このプロセスではLoginModuleとプリンシパル検証プロバイダを使用する必要があります。これらについては、それぞれ「LoginModule」第6章「プリンシパル検証プロバイダ」で詳しく解説されています。

呼出し側のIDの確認に成功すると、認証コンテキストが確立され、IDが確認されたユーザーまたはシステムに関しては、そのコンテキストを通じて他のエンティティに対する認証を行うことができます。認証コンテキストはまた、アプリケーション・コンポーネントに委託することもでき、それによって、そのコンポーネントは別のアプリケーション・コンポーネントを呼び出しつつ、元の呼出し側として動作できるようになります。

カスタム認証プロバイダを開発する必要があるか

WebLogic Serverのデフォルト(アクティブ)セキュリティ・レルムには、WebLogic認証プロバイダが含まれます。


注意:

WebLogic認証プロバイダをWebLogic認可プロバイダと組み合せれば、WebLogic Serverリリース6.xで利用できたファイル・レルムの機能のかわりになります。

WebLogic認証プロバイダは、ユーザー名とパスワードの委託認証をサポートし、組込みLDAPサーバーを利用してユーザーとグループの情報を格納します。WebLogic認証プロバイダを使用すると、ユーザーとグループ・メンバーシップを編集、表示、および管理できます。

WebLogic Serverでは、デフォルトのセキュリティ・レルムにおいて、以下の認証プロバイダをWebLogic認証プロバイダのかわりとして使用したり、WebLogic認証プロバイダと併用したりすることもできます。

デフォルトでは、これらの認証プロバイダは使用可能ですが、WebLogicデフォルト・セキュリティ・レルムには構成されていません。

追加の認証タスクを実行する場合は、カスタム認証プロバイダを開発する必要があります。


注意:

初期状態ではサポートされていない種類のトークン(新規、カスタム、サード・パーティのトークンなど)を使用して境界認証を行うには、カスタムIDアサーション・プロバイダを開発する必要があります。詳細については、第5章「IDアサーション・プロバイダ」を参照してください。

カスタム認証プロバイダの開発方法

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

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

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

  3. 管理コンソールによるカスタム認証プロバイダの構成

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

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

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

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

AuthenticationProviderV2 SSPIの実装


注意:

AuthenticationProvider SSPIは、このリリースのWebLogic Serverでは非推奨になっています。AuthenticationProviderV2 SSPIをかわりに使用してください。

AuthenticationProviderV2 SSPIを実装するには、「「Provider」SSPIの目的について」で説明されているメソッドと以下のメソッドの実装を提供する必要があります。

  • getLoginModuleConfiguration

    public AppConfigurationEntry getLoginModuleConfiguration()
    

    getLoginModuleConfigurationメソッドは、認証プロバイダの関連付けられたLoginModuleに関する情報を取得します。その情報は、AppConfigurationEntryとして返されます。AppConfigurationEntryは、LoginModuleのクラス名、認証プロバイダの関連するMBeanを通じて渡されたLoginModuleの制御フラグ、および他の構成情報をLoginModuleに渡すことを可能にするLoginModuleの構成オプション・マップの格納されたJAAS (Java Authentication and Authorization Service)クラスです。

    (javax.security.auth.loginパッケージ内にある)AppConfigurationEntryクラスとLoginModuleの制御フラグ・オプションの詳細は、Java SE 6.0 API仕様のAppConfigurationEntryクラス(http://download.oracle.com/javase/6/docs/api/javax/security/auth/login/AppConfigurationEntry.html)およびConfigurationクラス(http://download.oracle.com/javase/6/docs/api/javax/security/auth/login/Configuration.html)を参照してください。LoginModuleの詳細は、「LoginModule」を参照してください。セキュリティ・プロバイダとMBeanの詳細は、「MBeanタイプが必要な理由について」を参照してください。

  • getAssertionModuleConfiguration

    public AppConfigurationEntry
    getAssertionModuleConfiguration()
    

    getAssertionModuleConfigurationメソッドは、IDアサーション・プロバイダの関連付けられたLoginModuleに関する情報を取得します。その情報は、AppConfigurationEntryとして返されます。AppConfigurationEntryは、LoginModuleのクラス名、IDアサーション・プロバイダの関連するMBeanを通じて渡されたLoginModuleの制御フラグ、および他の構成情報をLoginModuleに渡すことを可能にするLoginModuleの構成オプション・マップの格納されたJAASクラスです。


    注意:

    getAssertionModuleConfigurationメソッドの実装はnullを返す場合があります(IDアサーション・プロバイダが認証プロバイダと同じLoginModuleを使用する場合)。

    IDアサーション・プロバイダのassertidentity()メソッドは、IDアサーションが発生するたびに呼び出されますが、サブジェクトがキャッシュされている場合、LoginModuleは呼び出されないことがあります。-Dweblogic.security.identityAssertionTTLフラグを使うと、この動作を変更する(たとえば、5分というデフォルトTTLを変更する、またはフラグを -1に設定してキャッシュを無効にする)ことができます。

    トークンが有効なだけでなく、ユーザーも引続き有効であること(ユーザーが削除されていないことなど)を確認するのは、IDアサーション・プロバイダの役割です。

    EJBの<run-as-principal>要素とカスタム認証プロバイダを併用する場合には、getAssertionModuleConfiguration()メソッドを使用します。このメソッドが実行するIDアサーションによって、<run-as-principal>要素に指定されているプリンシパルが検証されます。


  • getPrincipalValidator

    public PrincipalValidator getPrincipalValidator()
    

    getPrincipalValidatorメソッドは、プリンシパル検証プロバイダのランタイム・クラス(PrincipalValidator SSPI実装)の参照を取得します。WebLogicプリンシパル検証プロバイダは、ほとんどの場合に使用できます。WebLogicプリンシパル検証プロバイダの返し方の例については、例4-1を参照してください。プリンシパル検証プロバイダの詳細は、第6章「プリンシパル検証プロバイダ」を参照してください。

  • getIdentityAsserter

    public IdentityAsserterV2 getIdentityAsserter()
    

    AuthenticationProviderV2のgetIdentityAsserterメソッドは、新しいIDアサーション・プロバイダのランタイム・クラス(IdentityAsserterV2 SSPI実装)の参照を取得します。

    ほとんどの場合、このメソッドの戻り値はnullになります(例については例4-1を参照)。IDアサーション・プロバイダの詳細は、第5章「IDアサーション・プロバイダ」を参照してください。

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

JAAS LoginModuleインタフェースの実装

JAAS javax.security.auth.spi.LoginModuleインタフェースを実装するには、以下のメソッドを実装する必要があります。

  • initialize

    public void initialize (Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
    

    initializeメソッドはLoginModuleを初期化します。引数として取るのは、結果として得られるプリンシパルを格納するサブジェクト、認証プロバイダが認証情報のコンテナにコールバックするのに使用するCallbackHandler、任意の共有状態情報のマップ、および構成オプション(すなわち、LoginModuleに渡す任意の付加的情報)のマップです。

    CallbackHandlerは、可変個の引数を複合オブジェクトとしてメソッドに渡すことができるようにする高度に柔軟なJAAS規格です。CallbackHandlerの詳細は、Java SE 6.0 API仕様のCallbackHandlerインタフェース(http://download.oracle.com/javase/6/docs/api/javax/security/auth/callback/CallbackHandler.html)を参照してください。

  • login

    public boolean login() throws LoginException
    

    loginメソッドは、ユーザーを認証し、認証情報のコンテナにコールバックすることでそのユーザーのプリンシパルを作成しようと試みます。複数のLoginModuleが複数の認証プロバイダの一部として構成されている場合、このメソッドはLoginModuleごとにその構成の順序で呼び出されます。ログインが成功したかどうか(すなわち、プリンシパルが作成されたかどうか)についての情報は、LoginModuleごとに格納されます。

  • commit

    public boolean commit() throws LoginException
    

    commitメソッドは、loginメソッドで作成されたプリンシパルをサブジェクトに追加しようと試みます。このメソッドも、複数の認証プロバイダの一部として構成されているLoginModuleごとに呼び出され、順番に実行されます。コミットが成功したかどうかの情報は、LoginModuleごとに格納されます。

  • abort

    public boolean abort() throws LoginException
    

    abortメソッドは、構成されている認証プロバイダの一部として構成されているLoginModuleのコミットが失敗した(つまり、関連するREQUIREDREQUISITESUFFICIENT、およびOPTIONAL LoginModuleが成功しなかった)場合にLoginModuleごとに呼び出されます。abortメソッドは、LoginModuleのプリンシパルをサブジェクトから削除し、実行されたアクションを効果的にロールバックします。使用可能な制御フラグ設定の詳細は、Java SE 6.0 API仕様のLoginModuleインタフェース(http://download.oracle.com/javase/6/docs/api/javax/security/auth/spi/LoginModule.html)を参照してください。

  • logout

    public boolean logout() throws LoginException
    

    logoutメソッドは、ユーザーをシステムからログアウトさせようとします。また、サブジェクトのリセットも行うので、関連付けられているプリンシパルは格納されなくなります。


    注意:

    LoginModule.logoutメソッドはWebLogic認証プロバイダまたはカスタム認証プロバイダに対して呼び出されることはありません。これは単に、いったんプリンシパルが作成されサブジェクト内に入れられると、WebLogicセキュリティ・フレームワークはこのサブジェクトのライフサイクルを制御しなくなるからです。したがって、JAAS LoginContext を作成してログインおよびサブジェクトの取得を行う、開発者によって記述されたユーザー・コードでも、 LoginContext.logout メソッドを呼び出す必要があります。ユーザー・コードが、JAASを直接使用するJavaクライアントで実行される場合、このコードには LoginContext.logout メソッドを呼び出すというオプションがあります。これにより、サブジェクトはクリアされます。ユーザー・コードがサーブレットで実行される場合、サーブレットはサーブレット・セッションからユーザーをログアウトすることができます。これにより、サブジェクトはクリアされます。

JAAS LoginModuleインタフェースと前述のメソッドの詳細は、『Java Authentication and Authorization Service (JAAS) 1.0 Developer's Guide』(http://download.oracle.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html)およびJava SE 6.0 API仕様のLoginModuleインタフェース(http://download.oracle.com/javase/6/docs/api/javax/security/auth/spi/LoginModule.html)を参照してください。

LoginModuleからカスタム例外のスロー

記述したLoginModuleからカスタム例外をスローすることができます。そうすると、カスタム例外をアプリケーションおよび、実行された適切なアクションで捕捉できます。たとえば、LoginModuleからPasswordChangeRequiredExceptionがスローされると、その例外をアプリケーションで捕捉して、パスワードの変更が可能なページへユーザーを導くのに使用できます。

LoginModuleからカスタム例外をスローし、それをアプリケーション内で捕捉する場合には、以下のことを確認する必要があります。

  1. 例外を捕捉するアプリケーションがサーバー上で実行されています。(ファット・クライアントはカスタム例外を捕捉できません。)

  2. サーブレットが、コンパイル時でもデプロイメント時でもカスタム例外クラスにアクセスできます。これは、必要に応じて次の方法のいずれかで行えます。

方法1 :システム・クラスパスおよびコンパイラ・クラスパスを介してカスタム例外を使えるようにする
  1. LoginExceptionを拡張する例外クラスを記述します。

  2. LoginModuleインタフェースおよびAuthenticationProviderインタフェースを実装するクラスでカスタム例外クラスを使用します。

  3. セキュリティ・プロバイダの ランタイム・クラスをコンパイルする際に、カスタム例外クラスをシステム・クラスパスおよびコンパイラ・クラスパスの両方に入れます。

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

方法2 :アプリケーション・クラスパスを介してカスタム例外を使えるようにする
  1. LoginExceptionを拡張する例外クラスを記述します。

  2. LoginModuleインタフェースおよびAuthenticationProviderインタフェースを実装するクラスでカスタム例外クラスを使用します。

  3. カスタム例外のソースをアプリケーションのビルドのクラスパスに入れ、それをアプリケーションのJAR/WARファイルのクラスパスに含めます。

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

  5. WebLogic MBeanMakerで生成されたMJF (MBean JARファイル)にカスタム例外クラスを追加します。

  6. アプリケーションのコンパイル時にMJFを含めます。

例:サンプル認証プロバイダのランタイム・クラスの作成

例4-1は、サンプル認証プロバイダの2つのランタイム・クラスの1つであるSimpleSampleAuthenticationProviderImpl.javaクラスを示しています。このランタイム・クラスには次の実装が含まれています。

  • initializegetDescription、およびshutdownというSecurityProviderインタフェースから継承した3つのメソッド(「「Provider」SSPIの目的について」を参照)。

  • getLoginModuleConfigurationgetAssertionModuleConfigurationgetPrincipalValidator、およびgetIdentityAsserterというAuthenticationProviderV2 SSPIの4つのメソッド(「AuthenticationProviderV2 SSPIの実装」を参照)。


    注意:

    例4-1の太字のコードは、クラス宣言とメソッド・シグネチャを示しています。

例4-1 SimpleSampleAuthenticationProviderImpl.java

package examples.security.providers.authentication.simple;
import java.util.HashMap;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import weblogic.management.security.ProviderMBean;
import weblogic.security.provider.PrincipalValidatorImpl;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;
public final class SimpleSampleAuthenticationProviderImpl implements AuthenticationProviderV2
{
   private String description;
   private SimpleSampleAuthenticatorDatabase database;
   private LoginModuleControlFlag controlFlag;
   public void initialize(ProviderMBean mbean, SecurityServices services)
   {
      System.out.println("SimpleSampleAuthenticationProviderImpl.initialize");
      SimpleSampleAuthenticatorMBean myMBean = (SimpleSampleAuthenticatorMBean)mbean;
      description = myMBean.getDescription() + "\n" + myMBean.getVersion();
      database = new SimpleSampleAuthenticatorDatabase(myMBean);
      String flag = myMBean.getControlFlag();
      if (flag.equalsIgnoreCase("REQUIRED")) {
        controlFlag = LoginModuleControlFlag.REQUIRED;
      } else if (flag.equalsIgnoreCase("OPTIONAL")) {
        controlFlag = LoginModuleControlFlag.OPTIONAL;
      } else if (flag.equalsIgnoreCase("REQUISITE")) {
        controlFlag = LoginModuleControlFlag.REQUISITE;
      } else if (flag.equalsIgnoreCase("SUFFICIENT")) {
        controlFlag = LoginModuleControlFlag.SUFFICIENT;
      } else {
        throw new IllegalArgumentException("invalid flag value" + flag);
      }
   }
   public String getDescription()
   {
      return description;
   }
   public void shutdown()
   {
      System.out.println("SimpleSampleAuthenticationProviderImpl.shutdown");
   }
   private AppConfigurationEntry getConfiguration(HashMap options)
   {
      options.put("database", database);
      return new 
        AppConfigurationEntry(
          "examples.security.providers.authentication.Simple.Simple.SampleLoginModuleImpl",
          controlFlag,
          options
        );
   }
   public AppConfigurationEntry getLoginModuleConfiguration()
   {
      HashMap options = new HashMap();
      return getConfiguration(options);
   }
   public AppConfigurationEntry getAssertionModuleConfiguration()
   {
      HashMap options = new HashMap();
      options.put("IdentityAssertion","true");
      return getConfiguration(options);
   }
   public PrincipalValidator getPrincipalValidator() 
   {
      return new PrincipalValidatorImpl();
   }
   public IdentityAsserterV2 getIdentityAsserter()
   {
      return null;
   }
}

例4-2は、サンプル認証プロバイダの2つのランタイム・クラスの1つであるSampleLoginModuleImpl.javaクラスを示しています。このランタイム・クラスは、JAAS LoginModuleインタフェースを実装するので(「JAAS LoginModuleインタフェースの実装」を参照)、そのinitializelogincommitabort、およびlogoutメソッドの実装を含んでいます。


注意:

例4-2の太字のコードは、クラス宣言とメソッド・シグネチャを示しています。

例4-2 SimpleSampleLoginModuleImpl.java

package examples.security.providers.authentication.simple;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.spi.LoginModule;
import weblogic.management.utils.NotFoundException;
import weblogic.security.spi.WLSGroup;
import weblogic.security.spi.WLSUser;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;
final public class SimpleSampleLoginModuleImpl implements LoginModule 
{
   private Subject subject;
   private CallbackHandler callbackHandler;
   private SimpleSampleAuthenticatorDatabase database;
   // Determine whether this is a login or assert identity 
   private boolean isIdentityAssertion;
   // Authentication status
   private boolean loginSucceeded;
   private boolean principalsInSubject;
   private Vector principalsForSubject = new Vector();
   public void initialize(Subject subject, CallbackHandler callbackHandler, Map  
   sharedState, Map options) 
   {
      // only called (once!) after the constructor and before login
      System.out.println("SimpleSampleLoginModuleImpl.initialize");
      this.subject = subject;
      this.callbackHandler = callbackHandler;
      // Check for Identity Assertion option
      isIdentityAssertion =
         "true".equalsIgnoreCase((String)options.get("IdentityAssertion"));
      database = (SimpleSampleAuthenticatorDatabase)options.get("database");
   }
   public boolean login() throws LoginException  
   {
      // only called (once!) after initialize
      System.out.println("SimpleSampleLoginModuleImpl.login");
      // loginSucceeded       should be false
      // principalsInSubject  should be false

      Callback[] callbacks = getCallbacks();
      String userName = getUserName(callbacks);
      if (userName.length() > 0) {
         if (!database.userExists(userName)) {
            throwFailedLoginException("Authentication Failed: User " + userName 
            + " doesn't exist.");
         }
        if (!isIdentityAssertion) {
         String passwordWant = null;
         try {
            passwordWant = database.getUserPassword(userName);
         } catch (NotFoundException shouldNotHappen) {}
            String passwordHave = getPasswordHave(userName, callbacks);
            if (passwordWant == null || !passwordWant.equals(passwordHave)) {
               throwFailedLoginException(
                 "Authentication Failed: User " + userName + " bad password." 
               );
            }
         }
         } else { 
          // anonymous login - let it through?
         System.out.println("\tempty userName");
         }
         loginSucceeded = true;
         principalsForSubject.add(new WLSUserImpl(userName));
         addGroupsForSubject(userName);
         return loginSucceeded;
   }
   public boolean commit() throws LoginException 
   {
      // only called (once!) after login
      // loginSucceeded      should be true or false
      // principalsInSubject should be false
      // user      should be null if !loginSucceeded, null or not-null otherwise
      // group     should be null if user == null, null or not-null otherwise

      System.out.println("SimpleSampleLoginModule.commit");
      if (loginSucceeded) {
         subject.getPrincipals().addAll(principalsForSubject);
         principalsInSubject = true;
         return true;
      } else {
         return false;
      }
   }
   public boolean abort() throws LoginException 
   {
      // The abort method is called to abort the authentication process. This is
      // phase 2 of authentication when phase 1 fails. It is called if the
      // LoginContext's overall authentication failed.
      // loginSucceeded      should be true or false
      // user      should be null if !loginSucceeded, otherwise null or not-null
      // group     should be null if user == null, otherwise null or not-null
      // principalsInSubject      should be false if user is null, otherwise true 
      //                          or false

      System.out.println("SimpleSampleLoginModule.abort");
      if (principalsInSubject) {
         subject.getPrincipals().removeAll(principalsForSubject);
         principalsInSubject = false;
      }
      return true;
   }
   public boolean logout() throws LoginException 
   {
      // should never be called
      System.out.println("SimpleSampleLoginModule.logout");
      return true;
   }
   private void throwLoginException(String msg) throws LoginException
   {
      System.out.println("Throwing LoginException(" + msg + ")");
      throw new LoginException(msg);
   }
   private void throwFailedLoginException(String msg) throws FailedLoginException
   {
      System.out.println("Throwing FailedLoginException(" + msg + ")");
      throw new FailedLoginException(msg);
   }
   private Callback[] getCallbacks() throws LoginException
   {
      if (callbackHandler == null) {
         throwLoginException("No CallbackHandler Specified");
      }
      if (database == null) {
         throwLoginException("database not specified");
      }
      Callback[] callbacks;
      if (isIdentityAssertion) {
         callbacks = new Callback[1];
      } else {
         callbacks = new Callback[2];
         callbacks[1] = new PasswordCallback("password: ",false);
      }
      callbacks[0] = new NameCallback("username: ");
      try {
          callbackHandler.handle(callbacks);
      } catch (IOException e) {
         throw new LoginException(e.toString());
      } catch (UnsupportedCallbackException e) {
         throwLoginException(e.toString() + " " + e.getCallback().toString());
      }
      return callbacks;
   }
   private String getUserName(Callback[] callbacks) throws LoginException
   {
      String userName = ((NameCallback)callbacks[0]).getName();
      if (userName == null) {
         throwLoginException("Username not supplied.");
      }
      System.out.println("\tuserName\t= " + userName);
      return userName;
   }
   private void addGroupsForSubject(String userName)
   {
      for (Enumeration e = database.getUserGroups(userName);
         e.hasMoreElements();) {
            String groupName = (String)e.nextElement();
            System.out.println("\tgroupName\t= " + groupName);
            principalsForSubject.add(new WLSGroupImpl(groupName));
      }
   }
   private String getPasswordHave(String userName, Callback[] callbacks) throws 
   LoginException
   {
      PasswordCallback passwordCallback = (PasswordCallback)callbacks[1];
      char[] password = passwordCallback.getPassword();
      passwordCallback.clearPassword();
      if (password == null || password.length < 1) {
         throwLoginException("Authentication Failed: User " + userName + ".  
            Password not supplied");
      }
      String passwd = new String(password);
      System.out.println("\tpasswordHave\t= " + passwd);
      return passwd;
   }
}

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

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

この情報を理解し、設計に関する判断を下したら、次の手順でカスタム認証プロバイダのMBeanタイプを作成します。

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

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

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

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


    注意:

    この手順の実行方法を説明するサンプル・セキュリティ・プロバイダ(Oracle Technology Network Webサイトのhttps://codesamples.samplecode.oracle.com/servlets/tracking?id=S224から入手可能)がいくつか用意されています。

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


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

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

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


    注意:

    サンプル認証プロバイダのMDFは、SimpleSampleAuthenticator.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タイプの作成手順は、カスタム認証プロバイダの設計に応じて異なります。必要な設計に合わせて適切な手順を実行してください。

オプショナルSSPI MBeanとカスタム操作を追加しない場合

カスタム認証プロバイダのMDFにオプショナルSSPI 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. 「WebLogic MBeanMakerによるMBean JARファイル(MJF)の作成」に進みます。

オプショナルSSPI MBeanまたはカスタム操作を追加する場合

カスタム認証プロバイダのMDFにオプショナルSSPI MBeanまたはカスタム操作を実装する場合、以下の質問に答えながら手順を進めてください。

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. オプショナルSSPI MBeanをMDFに実装した場合は、次の手順に従います。

    1. MBean実装ファイルを見つけます。

      WebLogic MBeanMakerによって生成されるMBean実装ファイルには、MBeanNameImpl.javaという名前が付けられます。たとえば、SampleAuthenticatorという名前のMDFの場合、編集されるMBean実装ファイルはSampleAuthenticatorImpl.javaという名前になります。

    2. MDFで実装したオプショナルSSPI MBeanごとに、各メソッドを実装します。オプショナルSSPI MBeanが継承するメソッドもすべて実装してください。

  4. MDFにカスタム属性/操作を含めた場合は、メソッド・スタブを使用してメソッドを実装します。

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

  6. 「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. オプショナルSSPI MBeanをMDFに実装した場合は、次の手順に従います。

    1. MBean実装ファイルを見つけて開きます。

      WebLogic MBeanMakerによって生成されるMBean実装ファイルには、<MBeanName>Impl.javaという名前が付けられます。たとえば、SampleAuthenticatorという名前のMDFの場合、編集されるMBean実装ファイルはSampleAuthenticatorImpl.javaという名前になります。

    2. ステップ1で一時ディレクトリに保存した既存のMBean実装ファイルを開きます。

    3. 既存のMBean実装ファイルを、WebLogic MBeanMakerによって生成されたMBean実装ファイルと同期させます。

      これには、メソッドの実装を既存のMBean実装ファイルから新しく生成されたMBean実装ファイルにコピー(または、新しく生成されたMBean実装ファイルから既存のMBean実装ファイルに新しいメソッドを追加)し、いずれのMBean実装ファイルにも入っているメソッドのメソッド・シグネチャへの変更が、使用するMBean実装ファイルに反映されていることを確認するといった作業が必要です。

    4. MDFを修正して元のMDFにはないオプショナルSSPI MBeanを実装した場合は、各メソッドを実装します。オプショナルSSPI MBeanが継承するメソッドもすべて実装してください。

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

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

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

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

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

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

WebLogic MBeanMakerでは、作成済のMDFからMBeanタイプを生成するので、生成されるMBeanインタフェース・ファイルの名前は、そのMDF名の後に「MBean」というテキストが付いたものになります。たとえば、WebLogic MBeanMakerを使用してSimpleSampleAuthenticator MDFを実行すると、SimpleSampleAuthenticatorMBean.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インスタンスをバックアップしておくことをお薦めします。

管理コンソールによるカスタム認証プロバイダの構成

カスタム認証プロバイダを構成するということは、そのカスタム認証プロバイダをセキュリティ・レルムに追加するということです。追加されたカスタム認証プロバイダには、認証サービスを必要とするアプリケーションからアクセスできます。

カスタム・セキュリティ・プロバイダの構成は管理タスクですが、カスタム・セキュリティ・プロバイダの開発者が行うこともできます。この節では、カスタム認証プロバイダの構成担当者にとって重要な情報を提供します。

ユーザー・ロックアウトの管理

カスタム認証プロバイダを使用する一環として、ユーザー・ロックアウトを構成および管理する方法を検討する必要があります。以下の2つの選択肢があります。

レルム・ワイドのユーザー・ロックアウト・マネージャの使用

WebLogicセキュリティ・フレームワークは、WebLogicセキュリティ・フレームワークと直接連携してユーザー・ロックアウトを管理するレルム・ワイドのユーザー・ロックアウト・マネージャを提供します。


注意:

レルム・ワイドのユーザー・ロックアウト・マネージャとWebLogic Server 6.1 PasswordPolicyMBean(レルム・アダプタ・レベル)の両方をアクティブにできます。詳細は、WebLogic Server APIリファレンスJavadocを参照してください。

レルム・ワイドのユーザー・ロックアウト・マネージャを使用する場合、それをカスタム認証プロバイダと連携させるためには、WebLogic Server管理コンソールを使用して以下のことを行います。

  1. ユーザー・ロック・アウトを有効にします(デフォルトで有効)。

  2. 必要に応じてユーザー・ロックアウトのパラメータを修正します。


    注意:

    ユーザー・ロックアウト・マネージャへの変更は、サーバーを再起動するまで有効になりません。管理コンソールを使用して前述のタスクを実行する手順は、『Oracle WebLogic Serverの保護』のユーザー・アカウントの保護に関する項で説明されています。

独自のユーザー・ロックアウト・マネージャの実装

カスタム認証プロバイダの一部として独自のユーザー・ロックアウト・マネージャを実装する場合は、次の手順を行う必要があります。

  1. レルム・ワイドのユーザー・ロックアウト・マネージャを無効にして二重ロックアウトを防止します。(WebLogic Server管理コンソールを使用して新しいセキュリティ・レルムを作成すると、ユーザー・ロックアウト・マネージャが必ず作成されます。)このタスクを実行する手順は、『Oracle WebLogic Serverの保護』のユーザー・アカウントの保護に関する項で説明されています。

  2. WebLogicセキュリティ・フレームワークのレルム・ワイドの実装からは何も借用できないので、以下のタスクを行うことも必要です。

    1. ユーザー・ロックアウト・マネージャの実装を提供します。ユーザー・ロックアウト・マネージャに関して、セキュリティ・サービス・プロバイダ・インタフェース(SSPI)は提供されません。

    2. ユーザー・ロックアウト・マネージャの管理に使用できるMBeanを変更します。

    3. 管理コンソールからユーザー・ロックアウト・マネージャを管理する場合、コンソール拡張を使用して管理コンソールにユーザー・ロックアウト・マネージャを組み入れます。詳細は、『Oracle WebLogic Server管理コンソールの拡張』を参照してください。

認証プロバイダの順序の指定

「LoginModuleとマルチパート認証」で説明されているように、認証プロセスの結果は、複数の認証プロバイダ(その結果としてLoginModule)の構成順序によって影響を受けます。

認証プロバイダは任意の順序で構成できます。ただし、構成済の認証プロバイダの順序を変更する必要がある場合は、『Oracle WebLogic Serverの保護』の認証プロバイダの順序の変更に関する項で説明されている手順に従ってください。