LoginModule 開発者ガイド
LoginModule
LoginModule 実装への命名
LoginModule メソッドの実装
LoginModule およびアプリケーションのコンパイル
LoginModule
LoginModule 実装のドキュメント化
LoginModule JAR ファイルおよびドキュメントの有効化
当初、JavaTM 認証・承認サービス (JavaTM Authentication and Authorization Service: JAAS) は、JavaTM 2 SDK, Standard Edition (J2SDK), v 1.3 のオプションパッケージでした。JAAS は、J2SDK 1.4 より Java TM Standard Edition Development Kit に統合されています。
JAAS は、認証されたアイデンティティーにおけるサブジェクト (被認証) ベースの認証を提供します。このドキュメントでは、JAAS の認証面、特に
LoginModuleインタフェースに焦点を当てて解説します。このドキュメントの対象読者
このドキュメントは、認証技術を実装する
LoginModuleを記述する必要がある、経験を積んだプログラマ向けに書かれています。関連ドキュメント
このドキュメントでは、読者がすでに次のドキュメントを読んでいることを前提としています。
JAAS API のさまざまなクラスおよびインタフェースについての説明も含まれます。詳細は、JAAS API 仕様の javadoc を参照してください。
- javax.security.auth パッケージ
- javax.security.auth.callback パッケージ
- javax.security.auth.kerberos パッケージ
- javax.security.auth.login パッケージ
- javax.security.auth.spi パッケージ
- javax.security.auth.x500 パッケージ
- com.sun.security.auth パッケージ
- com.sun.security.auth.callback パッケージ
- com.sun.security.auth.login パッケージ
- com.sun.security.auth.module パッケージ
以下の「チュートリアル」は、JASS 認証および承認を利用するすべてのユーザーを対象としています。
以下のチュートリアルは、JAAS 認証および承認チュートリアルと似ていますが、Kerberos LoginModule の使用方法の解説が含まれるため、使用する前に Kerberos をインストールする必要があります。
この 2 つのチュートリアルは、認証と安全な通信のための基盤技術として Kerberos を利用する「Java GSS-API および JAAS の一連のチュートリアル」に含まれています。
はじめに
LoginModuleドキュメントでは、認証技術のプロバイダが実装する必要のあるインタフェースについて説明します。ログインモジュールはアプリケーションへのプラグインとして機能し、特定タイプの認証を提供します。アプリケーションは
LoginContextアプリケーションプログラミングインタフェース (API) への書き込みを実行するのに対し、認証技術のプロバイダはLoginModuleインタフェースを実装します。の認証にConfigurationには、特定のログインアプリケーションで使用するLoginModuleを指定します。アプリケーション自体を変更せずに、複数の異なるログインモジュールをアプリケーションのプラグインとして使用できます。
LoginContextは、Configurationの読み取りと特定のLoginModuleのインスタンス化を行います。各LoginModuleはSubject、CallbackHandler、共有のLoginModuleの状態、およびLoginModule固有のオプションを使ってインスタンス化されます。
Subjectは、認証中のユーザーまたはサービスを表します。認証が成功すると、関連するPrincipalおよび資格を保持するLoginModuleによりSubjectが更新されます。ログインモジュールは、たとえばユーザー名とパスワードを取得するために、CallbackHandlerを使ってユーザーと通信します。login メソッドの解説を参照してください。CallbackHandlerは null の場合もあることに留意してください。SubjectCallbackHandlerを必要とするログインモジュールは、nullのCallbackHandlerで初期化されると、LoginExceptionをスローする場合があります。共有状態を使用して、複数のログインモジュール間で情報を共有することもできます (オプション)。ログインモジュール固有のオプションは、ログイン
Configuration内で、このログインモジュール用に構成されたオプションを表します。これらのオプションは、ログインモジュール自体により定義されます。またその動作制御は、ログインモジュールの内部で行われます。たとえば、ログインモジュールでデバッグ/テスト機能をサポートするオプションを定義する場合を考えましょう。オプションの定義では、鍵と値で構成される構文 (debug=true など) が使用されます。ログインモジュールは、キーを使って値を取得できるよう、オプションをMapとして格納します。ログインモジュールが定義可能なオプションの数に制限はありません。呼び出し元アプリケーションは、認証プロセスを
LoginContextのloginメソッド呼び出しによって呼び出された単一の操作であると見なします。ただし、ログインモジュール内部の認証プロセスは、明確な 2 つのフェーズに分かれています。最初のフェーズでは、LoginContextのloginメソッドにより、Configuration内に指定された各ログインモジュールのloginメソッドが呼び出されます。ログインモジュールのloginメソッドは、実際の認証を実行してから (たとえば、パスワードの入力を促し、入力されたパスワードを検証する)、認証状態を非公開の状態情報として保存します。終了後に、true(成功した場合) またはfalse(無視する場合) を返すか、LoginExceptionをスローして障害を指定します。障害が発生した場合、ログインモジュールは認証を再試行できません。また、遅延の発生も認められません。これらのタスクの実行は、アプリケーションが担当します。アプリケーションが認証の再実行を試みると、ログインモジュールのloginが再度呼び出されます。次のフェーズでは、
LoginContextの認証がすべて成功した (関連する required、requisite、sufficient、および optional LoginModule の login メソッドの呼び出しに成功した) 場合、各LoginModuleのcommitメソッドが呼び出されます。LoginModuleフラグ (required、requisite、sufficient、および optional) については、javax.security.auth.login.Configurationのドキュメントと『JAAS リファレンスガイド』の「付録 B: サンプルログイン構成」 を参照してください。ログインモジュールのcommitメソッドは、非公開での保存状態をチェックして、認証が成功したかどうかを確認します。LoginContextの認証全体が成功し、ログインモジュール自体の認証が成功すると、commitメソッドにより、関連するプリンシパル (認証済みの識別情報) およびクレデンシャル (暗号化鍵などの認証データ) がSubjectに関連付けられます。ログインモジュールの認証全体が失敗した (ログインモジュールの関連する REQUIRED、REQUISITE、SUFFICIENT、および OPTIONAL LoginModule の
loginメソッドが成功しなかった) 場合、各LoginModuleのabortメソッドが呼び出されます。この場合、LoginModuleは、当初保存されていた認証状態をすべて削除/破棄します。
Subjectのログアウトには、1 つのフェーズだけが関係しています。LoginContextは、ログインモジュールのlogoutメソッドを呼び出します。次に、ログインモジュールのlogoutメソッドは、ログアウト処理 (Subjectからのプリンシパルやクレデンシャルの削除、またはセッション情報の記録など) を実行します。
以下は、ログインモジュールの実装およびテストに必要なステップです。
- ステップ 1: 認証技術の理解
- ステップ 2:
LoginModule実装への命名- ステップ 3: 抽象
LoginModuleメソッドの実装- ステップ 4: サンプルアプリケーションの選択または記述
- ステップ 5:
LoginModuleおよびアプリケーションのコンパイル- ステップ 6: テストの準備
- ステップ 6a:
LoginModuleとアプリケーションコードを JAR ファイルに配置- ステップ 6b:JAR ファイルの格納場所を決定
- ステップ 6c:
LoginModuleとアプリケーションの JAR ファイルにアクセス権を設定- ステップ 6d: ログインモジュールを参照する構成を作成
- ステップ 7: Test Use of the
LoginModule- ステップ 8:
LoginModule実装のドキュメント化- ステップ 9:
LoginModuleJAR ファイルおよびドキュメントの有効化以下では、新規ログインモジュールの実装およびテストの手順を示します。いくつかのステップで実行する内容の例については、「SampleLoginModule」および「JAAS リファレンスガイド」を参照してください。
ステップ 1: 認証技術の理解
最初に、新規LoginModuleプロバイダが実装する認証技術について理解した上で、要件を決定します。まず、ログインモジュールがユーザーとの通信 (ユーザー名とパスワードの取得など) を必要とするかどうかを決定する必要があります。ユーザーとの通信が必要な場合は、
CallbackHandlerインタフェースとjavax.security.auth.callbackパッケージに関する知識が必要です。javax.security.auth.callbackパッケージには、使用できるCallback実装が含まれています。独自のCallback実装を作成することもできます。ログインモジュールは、アプリケーションによって指定され、ログインモジュールのinitializeメソッドに渡されたCallbackHandlerを呼び出します。ログインモジュールは、CallbackHandlerに適切なCallbackからなる配列を渡します。ステップ 3 の login メソッドを参照してください。ログインモジュール実装がエンドユーザーと通信しない設定にすることもできます。その場合には、ログインモジュールから
callbackパッケージにアクセスする必要はありません。次に、ユーザーに提供する構成オプションを決定する必要があります。ユーザーは、現在の Configuration 実装に適した形式 (たとえばファイル形式) で構成情報を指定します。各オプションに対して、オプション名と戻り値を決定します。たとえば、ログインモジュールを構成して、特定の認証サーバーホストへの問い合わせを行う場合、オプションのキー名 (例、「auth_server」) およびこのオプションに指定可能なサーバーホスト名 (例、「server_one.foo.com」や「server_two.foo.com」など) を確認します。
ステップ 2:
LoginModule実装への命名ログインモジュールの適切なパッケージおよびクラス名を決定します。たとえば、IBM により開発されたログインモジュールには
com.ibm.auth.Moduleと命名できます。ここで、com.ibm.authはパッケージ名、ModuleはLoginModuleクラス実装の名前です。ステップ 3: 抽象
LoginModuleメソッドの実装各メソッドの詳細については、以下の 「
LoginModuleインタフェースは、実装の必要な 5 つの abstract メソッドを指定します。LoginModuleAPI」 を参照してください。
LoginModule実装は、これらのメソッドに加え、引数をとらない public のコンストラクタを提供する必要があります。このことにより、LoginContextによるインスタンス化が適切に行われるようになります。ログインモジュール実装でこの種のコンストラクタが提供されない場合、引数を取らないデフォルトコンストラクタが自動的にObjectクラスから継承されます。public void initialize (Subject subject,
CallbackHandler handler,
Map<java.lang.String, ?> sharedState,
Map<java.lang.String, ?> options) { ... }
initializeメソッドが呼び出され、関連する認証および状態情報でログインモジュールの初期化が行われます。このメソッドは、ログインモジュールをインスタンス化した後 (かつほかの public メソッドを呼び出す前)、すぐに
LoginContextにより呼び出されます。このメソッド実装は、将来の使用に備えて指定された引数を格納します。
initializeメソッドは、指定された sharedState をチェックして、他のログインモジュールから提供された認証状態を確認します。また、指定されたオプション options チェックして、ログインモジュール動作に影響を及ぼす構成オプションを確認します。将来の使用に備えて、変数内にオプションの値を格納することもできます。注: JAAS ログインモジュールは、PAM (
use_first_pass、try_first_pass、use_mapped_pass、およびtry_mapped_pass) に定義されたオプションを使って、シングルサインオンを行います。詳細については、「Making Login Services Independent of Authentication Technologies」を参照してください。以下は、ログインモジュールがサポートする一般的なオプションの一覧です。ただし、これはガイドラインにすぎません。モジュールは、次のオプションのサブセットを随意サポートします。
try_first_pass-trueの場合、スタック内の最初のログインモジュールが入力されたパスワードを保存し、それ以降のログインモジュールはこれを使用しようとする。認証に失敗した場合、ログインモジュールは新しいパスワードを要求し、認証を再試行する
use_first_pass-trueの場合、スタック内の最初のログインモジュールが入力されたパスワードを保存し、それ以降のログインモジュールはこれを使用しようとする。ログインモジュールは、認証に失敗しても新しいパスワードを要求しない
try_mapped_pass-trueの場合、スタック内の最初のログインモジュールが入力されたパスワードを保存し、それ以降のログインモジュールはこれをサービス固有のパスワードにマッピングしようとする。認証に失敗した場合、ログインモジュールは新しいパスワードを要求し、認証を再試行する
use_mapped_pass-trueの場合、スタック内の最初のログインモジュールが入力されたパスワードを保存し、それ以降のログインモジュールはこれをサービス固有のパスワードにマッピングしようとする。ログインモジュールは、認証に失敗しても新しいパスワードを要求しない
moduleBanner-trueの場合、ログインモジュールは、CallBackHandler の呼び出し時に最初の Callback として TextOutputCallback を提供する。この Callback には、認証を実行しているログインモジュールに関する情報が記述されている
debug-trueの場合、ログインモジュールに対してデバッグ情報の出力を指示する
initializeメソッドは、認識できない状態やオプションを無視できます。ただし、この種のイベントが発生した場合、それを記録する方が望ましい場合もあります。このログインモジュール (およびその他の構成済み
LoginContext) を呼び出すLoginContextはすべて、指定されたsubjectおよびsharedStateへの同一の参照を共有します。subjectおよびsharedStateへの変更は、すべてのLoginContextにより認識されます。boolean login() throws LoginException;
loginメソッドが呼び出され、Subjectの認証が行われます。これが認証の第 1 フェーズです。このメソッド実装は、実際の認証を実行します。たとえば、ユーザー名およびパスワードの入力を求めてから、パスワードデータベースに対しパスワードの検証を試みます。別のサンプル実装として、フィンガープリントリーダに指を挿入するようユーザーに指示し、入力されたフィンガープリントをフィンガープリントデータベースと照合する場合が考えられます。
ログインモジュールがユーザーとの通信 (ユーザー名とパスワードの取得など) を必要とする場合、この通信を直接行うことはできません。ユーザーと通信する方法はいくつも考えられます。ログインモジュールがユーザーと通信する際、特定の方法に依存しないようにするのが望ましい方法です。ユーザーと通信し、適切な結果 (ユーザー名、パスワードなど) を設定するためには、
LoginModuleのloginメソッドから、initializeメソッドに渡されたCallbackHandlerのhandleメソッドを呼び出すほうがよいでしょう。LoginModuleはCallbackHandlerに適切なCallback(ユーザー名に対しては NameCallback、パスワードに対しては PasswordCallback) からなる配列を渡し、CallbackHandlerは要求に従ってユーザーと通信し、Callback内に適切な値を設定します。たとえば、NameCallbackを処理する場合、CallbackHandlerはユーザーから名前を取得し、NameCallbackのsetNameメソッドを呼び出してその名前を格納します。認証プロセスに、ネットワーク経由の通信が含まれる場合もあります。たとえば、このメソッド実装が Kerberos の kinit と等価な機能を実行する場合、KDC とのコンタクトが必要になります。パスワードデータベースのエントリがリモートネームサービス内に存在する場合、Java Naming and Directory Interface (JNDI) を利用するなどして、そのネームサービスとコンタクトを取る必要があります。実装は、基盤となるオペレーティングシステムと通信する必要もあります。たとえば、ユーザーが Solaris や Windows NT などのオペレーティングシステムにログインしている場合、このメソッドは基盤となるオペレーティングシステムの識別情報のインポートのみを行います。
loginメソッドには、次の処理を行う必要があります。
- このログインモジュールを無視するかどうかを決定します。たとえば、ユーザーがこのログインモジュールと無関係な識別情報を使って認証を試みた場合 (たとえば、ユーザーが NIS を使い、root で認証を試みた場合) は、ログインモジュールを無視する必要があります。このログインモジュールを無視する必要がある場合、
loginの戻り値はfalseになります。それ以外の場合、次の処理を行います。
- ユーザーとの通信が必要な場合は
CallbackHandlerのhandleメソッドを呼び出します。
- 認証を実行します。
- 認証結果 (成功または失敗) を格納します。
- 認証に成功した場合は、関連状態情報をすべて保存します。この情報は、
commitメソッドで使用される可能性があります。
- 認証に成功した場合は
trueを返し、認証に失敗した場合はLoginException(FailedLoginExceptionなど) をスローする
loginメソッド実装が、新規プリンシパルまたはクレデンシャル情報を保存済みのSubjectオブジェクトに関連付けることはできません。このメソッドは、認証のみを実行して、認証結果および対応する認証状態を格納します。あとで、commitまたはabortメソッドからこの結果および状態へのアクセスが行われます。結果および状態は、他のログインモジュールと共有ではないので、通常、sharedStateMapには保存できません。たとえば、ログインモジュールがパスワードを共有するように構成されている場合であれば、このメソッドにとって、sharedState の
Mapに状態情報を保存することは有利です。この場合、入力されたパスワードは、共有状態として保存されます。パスワードの共有により、パスワードを 1 回入力するだけで後続のログインモジュールでも認証された状態を維持することができます。次に、sharedState のMapから名前とパスワードを格納および保存する際の標準的な規約を示します。
javax.security.auth.login.name- 名前を保存/取得するための共有状態マップキーとして使用
javax.security.auth.login.password- パスワードを保存/取得するための共有状態マップキーとして使用認証に失敗した場合、
loginメソッドは認証を再試行できません。この処理はアプリケーションが担当します。LoginModule.login()内から何度もログインを試みるよりも、アプリケーションから繰り返しLoginContextのloginメソッドを呼び出すことをお勧めします。boolean commit() throws LoginException;
commitメソッドが呼び出され、認証プロセスの確認が行われます。これは、第 1 認証フェーズが成功した場合の第 2 認証フェーズです。LoginContext全体の認証が成功した場合 (関連する REQUIRED、REQUISITE、SUFFICIENT、およびOPTIONAL のLoginModuleが成功した場合)、commitメソッドが呼び出されます。このメソッドは、
loginメソッドにより保存された認証結果および対応する認証状態にアクセスします。認証結果から
loginメソッドの失敗が明らかになった場合、commitメソッドは最初に保存された対応する状態をすべて削除/破棄します。保存された結果からログインモジュールの
loginメソッドの成功が明らかになった場合は、対応する状態情報から関連するプリンシパルおよびクレデンシャルの情報が構築されます。このプリンシパルおよびクレデンシャルの情報が、initializeメソッドによって格納されたSubjectに追加されます。プリンシパルおよびクレデンシャルの追加後は、不要な状態フィールドを迅速に破棄する必要があります。たとえば、認証プロセスで格納されたユーザー名やパスワードは破棄されます。
commitメソッドは、確認の成功または失敗を示す非公開の状態を保存する必要があります。次に、ログインモジュールの
commitメソッドから返される結果を図示します。各ボックスは、発生する可能性がある状況を表します。たとえば、上部左側のボックスは、以前のloginメソッド呼び出しとcommitメソッド自体の呼び出しに成功した場合に返される結果を示しています。\ LOGIN \ COMMIT \ \ 成功 失敗 +--------------+-----------------+ | | | 成功 | TRUE が返される | EXCEPTION がスローされる | | | | +--------------+-----------------+ | | | 失敗 | FALSE が返される | FALSE が返される | | | | +--------------+-----------------+
boolean abort() throws LoginException;
abortメソッドが呼び出され、認証プロセスが強制的に中断されます。これは、第 1 認証フェーズが失敗した場合の第 2 認証フェーズです。abortメソッドは、LoginContextの全体の認証に失敗した場合に呼び出されます。このメソッドは、最初に、
loginメソッド (およびcommitメソッド) によって保存されているログインモジュールの認証結果および対応する認証状態にアクセスし、情報を消去および破棄します。たとえば、ユーザー名およびパスワードは破棄されます。ログインモジュールの認証に失敗した場合、非公開の状態を消去する必要は生じません。
次に、ログインモジュールの
abortメソッドから返される結果を図示します。最初の図は、以前のlogin呼び出しが成功したことを想定しています。たとえば、上部左側のボックスは、以前のloginメソッド呼び出しとcommitメソッドの呼び出しに成功し、さらにabortメソッド自体の呼び出しにも成功した場合に返される結果を示しています。\ COMMIT \ ABORT (LOGIN メソッドが成功した場合) \ \ 成功 失敗 +--------------+-----------------+ | | | 成功 | TRUE が返される | EXCEPTION がスローされる | | | | +--------------+-----------------+ | | | 失敗 | TRUE が返される | EXCEPTION がスローされる | | | | +--------------+-----------------+2 番目の図は、以前の
loginメソッドの呼び出しに失敗した場合に返される結果を示しています。たとえば、上部左側のボックスは、以前のloginメソッド呼び出しには失敗したが、commitメソッドの呼び出しには成功し、さらにabortメソッド自体の呼び出しにも成功した場合に返される結果を示しています。\ COMMIT \ ABORT (LOGIN メソッドが失敗した場合) \ \ 成功 失敗 +--------------+-----------------+ | | | 成功 | FALSE が返される | FALSE が返される | | | | +--------------+-----------------+ | | | 失敗 | FALSE が返される | FALSE が返される | | | | +--------------+-----------------+boolean logout() throws LoginException;
logoutメソッドが呼び出され、Subjectからログアウトします。このメソッドは、プリンシパルを削除し、
commit操作中にSubjectに関連付けられたクレデンシャルを削除/破棄します。このメソッドは、Subject内の既存のプリンシパルやクレデンシャル、またはほかのログインモジュールによって追加されたプリンシパルやクレデンシャルに対しては、一切の操作を実行できません。
Subjectが読み取り専用 (SubjectのisReadOnlyメソッドが true を返す) の場合、このメソッドはcommit操作中にSubjectに関連付けられているクレデンシャルのみを破棄します (クレデンシャルを削除することはできません)。Subjectが読み取り専用であり、commit操作中にSubjectと関連付けられたクレデンシャルを破棄できない (このクレデンシャルがDestroyableインタフェースを実装していない) 場合、このメソッドはLoginExceptionをスローする可能性があります。
logoutメソッドは、ログアウトに成功した場合はtrueを返し、それ以外の場合は LoginException をスローします。ステップ 4: サンプルアプリケーションの選択または記述
テスト用として、既存のサンプルアプリケーションを選択するか、新しいサンプルアプリケーションを作成します。アプリケーションの要件とテストに使用できるサンプルアプリケーションについては、「JAAS リファレンスガイド」を参照してください。
ステップ 5:
LoginModuleおよびアプリケーションのコンパイルテストに使用する新しいログインモジュールおよびアプリケーションをコンパイルします。ステップ 6: テストの準備
ステップ 6a:
LoginModuleとアプリケーションコードを JAR ファイルに配置ステップ 6c でポリシー内の JAR ファイルを参照できるように、ログインモジュールおよびアプリケーションコードを別々の JAR ファイルに格納します。以下は、JAR ファイルを作成するサンプルコマンドです。
jar cvf <JAR file name> <list of classes, separated by spaces>このコマンドにより、指定されたクラスを含む、指定された名前の JAR ファイルが作成されます。
jar ツールの詳細については、jar (Solaris 用) (Microsoft Windows 用) を参照してください。
ステップ 6b:JAR ファイルの格納場所を決定
本来、アプリケーションはユーザーの好みの場所に格納できます。
LoginModuleも、ユーザーまたはその他のクライアントの好みの場所に格納できます。完全に信頼できるLoginModuleは、JRE のlib/ext(標準拡張) ディレクトリに格納できます。
lib/extディレクトリ内にあるログインモジュールとその他のディレクトリにあるログインモジュールを両方ともテストする必要があります。これは、ログインモジュールにセキュリティー関連操作の実行に必要なアクセス権を明示的に付与しなければならない場合と、そうでない場合があるためです。JRE の
lib/extディレクトリ内のログインモジュールは、インストール済み拡張機能と見なされるので、これにアクセス権を付与する必要はありません。インストール済み拡張機能には、デフォルトのシステムポリシーファイルにより、すべてのアクセス権が付与されます。一方、それ以外のディレクトリ内のログインモジュールには、ポリシーファイル内の
grant文を使うなどしてアクセス権を付与する必要があります。
LoginModuleJAR ファイルがインストール済み拡張機能と見なされない場合は、このファイルの格納場所を指定してテストを行います。次のステップでは、指定された場所にある JAR ファイルにアクセス権を付与します。ステップ 6c:
LoginModuleとアプリケーションの JAR ファイルにアクセス権を設定ログインモジュールやアプリケーションが、セキュリティーチェックをトリガーするセキュリティー関連タスク (ネットワーク接続の確立、ローカルディスク上のファイルの読み取り、書き込みなど) を実行するとします。これらがインストール済み拡張機能 (ステップ 6b を参照) ではなく、セキュリティーマネージャーがインストールされている環境で実行される場合は、アクセス権を付与する必要があります。
通常、
LoginModuleはPrincipalとクレデンシャルを認証済みのサブジェクトに関連付けます。このため、LoginModuleは、アクセス権として、modifyPrincipals、modifyPublicCredentials、modifyPrivateCredentials というターゲット名の AuthPermission を必要とします。以下のコード例
MyLM.jarには、ログインモジュールにアクセス権を付与する文が含まれています。この種の文は、ポリシーファイルに記述されます。この例では、MyLM.jarファイルは/localWorkディレクトリに格納されるものとします。grant codeBase "file:/localWork/MyLM.jar" { permission javax.security.auth.AuthPermission "modifyPrincipals"; permission javax.security.auth.AuthPermission "modifyPublicCredentials"; permission javax.security.auth.AuthPermission "modifyPrivateCredentials"; };注: ログインモジュールの呼び出しは、常に
AccessController.doPrivileged内で行われるため、doPrivileged自体を呼び出す必要はありません。doPrivilegedを呼び出すと、意図せずにセキュリティーホールを作り出してしまう可能性があります。たとえば、ログインモジュールがCallbackHandler内でアプリケーション提供のdoPrivilegedを呼び出す場合、他の場合にはアクセス不可能なリソースへのアクセスがアプリケーションのCallbackHandlerに許可されるため、セキュリティーホールが作り出されます。ステップ 6d: ログインモジュールを参照する構成を作成
JAAS はプラグイン可能な認証アーキテクチャーをサポートするため、アプリケーションを変更せずに新しいログインモジュールを使用できます。新しいログインモジュールの使用を示すためには、ログイン
Configurationを更新するだけで済みます。Sun Microsystems のデフォルトの
Configuration実装は、 com.sun.security.auth.login.ConfigFile.html で説明するように、構成ファイルから構成情報を読み取ります。テスト用の構成ファイルを作成します。たとえば、以前取り上げた IBM のアプリケーション用ログインモジュールを構成する場合、次のような内容の構成ファイルを使用することになります。
AppName { com.ibm.auth.Module REQUIRED debug=true; };AppNameは、アプリケーションがログイン構成ファイル内のこのエントリを参照するために使用する任意の名前です。アプリケーションはこの名前をLoginContextコンストラクタの第 1 引数として指定します。
ステップ 7: ログインモジュールの試用
最後に、アプリケーションとログインモジュールの使用をテストします。アプリケーションの実行時、使用するログイン構成ファイルを指定します。たとえば、
MyApp.jarにMyAppという名前のアプリケーションが格納されていて、構成ファイルの名前がtest.confだとします。この場合、次のようにしてアプリケーションを実行し、構成ファイルを指定できます。java -classpath MyApp.jar -Djava.security.auth.login.config=test.conf MyAppコマンド全体は、1 行で入力してください。ここでは、読みやすくするために複数行に分けて表示してあります。
my.policyという名前のポリシーファイルを指定し、インストールされているセキュリティーマネージャーを使ってアプリケーションを実行するには、次のように入力します。java -classpath MyApp.jar -Djava.security.manager -Djava.security.policy=my.policy -Djava.security.auth.login.config=test.conf MyAppコマンド全体は、1 行で入力してください。
debug オプションを付けてログインモジュールを構成すると、適正に動作することを確認できます。
コードをデバッグし、必要に応じてテストを続行します。問題が発生する場合は、上記のすべての手順が完了していることを確認してください。
ユーザーによる入力と、構成ファイルに指定した
LoginModuleオプションを確実に変更してください。異なったインストールオプション (ログインモジュールをインストール済み拡張機能にする、クラスパス内に配置する、など) および実行環境 (セキュリティーマネージャーを実行する、または実行しない) を使用するテストも実行してください。インストールオプションの詳細については、ステップ 6b を参照してください。特に、セキュリティーマネージャーがインストールされていてログインモジュールとアプリケーションがインストール済み拡張機能でない場合は、ログインモジュールを確実に動作させるため、ステップ 6c のようにして必要なアクセス権を付与したあと、インストールおよび実行環境をテストする必要があります。
テスト中にログインモジュールアプリケーションを変更する必要が生じた場合は、適切な変更を加え、再コンパイルし (ステップ 5)、JAR ファイル内の変更されたコードを配置し(ステップ 6a)、JAR ファイルを再インストール (ステップ 6b) します。さらに、必要に応じてアクセス権を変更または追加し (ステップ 6c)、ログイン構成ファイルを変更し (ステップ 6d)、アプリケーションを再実行します。その後、必要に応じて同じステップを繰り返します。
ステップ 8:
LoginModule実装のドキュメント化次のステップでは、ログインモジュールのクライアント用ドキュメントを記述します。たとえば、次のようなドキュメントを記述できます。
- README またはユーザーガイド
- ログインモジュール実装が使用する認証プロセス
- ログインモジュールのインストール方法
- ログインモジュールで有効な構成オプション。各オプションには、そのオプションの制御内容、オプション名、戻り値 (または値の型) を指定
- ログインモジュールがインストール済み拡張機能ではなく、セキュリティーマネージャーとともに実行される場合に必要なアクセス権
- 新規ログインモジュールを参照するサンプル
Configurationファイル
- ログインモジュールに必要なアクセス権を付与するサンプルポリシーファイル
- API ドキュメント。ソースコードを記述する際、javadoc コメントをソースコード内に挿入すると、API javadoc の生成が容易になる
ステップ 9:
LoginModuleJAR ファイルおよびドキュメントの有効化最後のステップでは、
LoginModuleJAR ファイルおよびドキュメントをクライアントから使用できるようにします。