3.4. サブジェクトの認証
サブジェクトの認証には JAAS ログインが必要です。ログイン手順は次のようになります。
- アプリケーションは
LoginContextをインスタンス化し、ログイン設定の名前とCallbackHandlerを渡して、設定LoginModuleが必要とするCallbackオブジェクトを追加します。 LoginContextは、名前付きログイン設定に含まれるすべてのLoginModulesをロードするためConfigurationを確認します。このような名前付き設定が存在しない場合は、other設定がデフォルトで使用されます。- アプリケーションによって、
LoginContext.loginメソッドが呼び出されます。 - ログインメソッドはロードされたすべての
LoginModuleを呼び出します。各LoginModuleはサブジェクトを認証するため、関連するLoginModuleでハンドルメソッドを呼び出し、認証プロセスに必要な情報を取得します。必要な情報は、Callbackオブジェクトのアレイの形式でハンドルメソッドに渡されます。認証に成功すると、LoginModuleは関連のプリンシパルとクレデンシャルをサブジェクトに関連付けします。 LoginContextは認証ステータスをアプリケーションに返します。ログインメソッドから返されると認証が成功したことになります。ログインメソッドによって LoginException がスローされると認証に失敗したことになります。- 認証に成功すると、アプリケーションは
LoginContext.getSubjectメソッドを使用して認証されたサブジェクトを取得します。 - サブジェクトの認証が完了した後に
LoginContext.logoutメソッドを呼び出すと、loginメソッドによりサブジェクトに関連付けられたすべてのプリンシパルおよび関連情報を削除できます。
LoginContext クラスは、サブジェクト認証の基本メソッドを提供し、基礎となる認証技術に依存しないアプリケーションを開発する方法を提供します。LoginContext は、特定のアプリケーション向けに設定された認証サービスを決定するため Configuration を確認します。LoginModule クラスは認証サービスを表します。そのため、アプリケーション自体を変更しなくても、異なるログインモジュールをアプリケーションにプラグ可能です。次のコードは、アプリケーションがサブジェクトを認証するために必要となる手順を示しています。
開発者は、
LoginModule インターフェースの実装を作成することで、認証技術を統合します。これにより、管理者は異なる認証技術を 1 つのアプリケーションにプラグできます。複数の LoginModule をチェーン化し、複数の認証技術を認証プロセスに加えることが可能です。たとえば、1 つの LoginModule がユーザー名およびパスワードベースの認証を行い、別の LoginModule をスマートカードリーダや生体認証などのハードウェアデバイスへ接続するインターフェースとすることが可能です。
LoginModule のライフサイクルは、クライアントがログインメソッドを作成し公開するLoginContext オブジェクトによって決定されます。このプロセスには 2 つのフェーズがあり、プロセスの手順は次のようになります。
LoginContextは引数のないパブリックコンストラクターを使用して、設定されたLoginModuleを作成します。- 各
LoginModuleは、初期化メソッドへの呼び出しによって初期化されます。Subject引数は null 以外になることが保証されます。初期化メソッドのシグネチャーはpublic void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)です。 loginメソッドは、認証プロセスを開始するために呼び出されます。たとえば、あるメソッド実装はユーザーにユーザー名とパスワードの入力を求め、NIS や LDAP などのネーミングサービスに保存されたデータに対してこの情報を検証することがあります。別の実装は、スマートカードや生体認証デバイスにインターフェースとして接続したり、基礎となるオペレーティングシステムからユーザー情報を抽出したりすることがあります。各LoginModuleによるユーザーアイデンティティーの検証は、JAAS 認証のフェーズ 1 とみなされます。loginメソッドのシグネチャーはboolean login() throws LoginExceptionです。LoginExceptionは失敗を意味します。true の戻り値はメソッドが成功したことを示し、false の戻り値はログインモジュールが無視されることを示します。LoginContextの全体的な認証が成功すると、各LoginModuleでcommitが呼び出されます。フェーズ 1 がLoginModuleに対して成功すると、コミットメソッドはフェーズ 2 を続行し、関連するプリンシパル、パブリッククレデンシャル、プライベートクレデンシャルをサブジェクトに関連付けます。フェーズ 1 がLoginModuleに対して失敗すると、commitはユーザー名やパスワードなどの以前保存した認証状態をすべて削除します。commitメソッドのシグネチャーはboolean commit() throws LoginExceptionです。LoginExceptionがスローされると、コミットフェーズの完了に失敗したことを示します。true が返されるとメソッドが成功したことを示し、false が返されるとログインモジュールが無視されることを示します。LoginContextの全体的な認証が失敗すると、各LoginModuleでabortメソッドが呼び出されます。abortメソッドはログインまたは初期化メソッドによって作成されたすべての認証状態を削除または破棄します。abortメソッドのシグネチャーはboolean abort() throws LoginExceptionです。LoginExceptionがスローされるとabortフェーズの完了に失敗したことを示します。true が返されるとメソッドが成功したことを示し、false が返されるとログインモジュールが無視されることを示します- ログイン成功後に認証状態を削除するため、アプリケーションは
LoginContextでlogoutを呼び出します。これにより、各LoginModuleでlogoutメソッドが呼び出されます。logoutメソッドは、commit操作中に当初サブジェクトに関連付けられていたプリンシパルとクレデンシャルを削除します。クレデンシャルは削除時に破棄されるはずです。logoutメソッドのシグネチャーはboolean logout() throws LoginExceptionです。LoginExceptionがスローされるとログアウトプロセスの完了に失敗したことを示します。true が返されるとメソッドが成功したことを示し、false が返されるとログインモジュールが無視されることを示します。
LoginModule がユーザーと通信して認証情報を取得する必要がある場合、CallbackHandler オブジェクトを使用します。アプリケーションは、 CallbackHandler インターフェースを実装して LoginContext に渡し、基礎となるログインモジュールに直接認証情報を送信します。
ログインモジュールは、
CallbackHandler を使用して、パスワードやスマートカード PIN などのユーザー入力による情報を取得したり、ステータスなどの情報をユーザーに提供したりします。アプリケーションによる CallbackHandler の指定を可能にすることで、基礎となる LoginModule がアプリケーションとユーザーが対話するさまざまな方法に依存しないようにします。たとえば、GUI アプリケーションの CallbackHandler の実装は、ウィンドウを表示してユーザーの入力を求めることがあります。一方でアプリケーションサーバーなどの GUI でない環境の CallbackHandler 実装は、アプリケーションサーバー API を使用してクレデンシャル情報を取得することがあります。 CallbackHandler インターフェースには実装するメソッドが 1 つあります。
void handle(Callback[] callbacks)
throws java.io.IOException,
UnsupportedCallbackException;
void handle(Callback[] callbacks)
throws java.io.IOException,
UnsupportedCallbackException;
最後に説明する認証クラスは
Callback インターフェースです。これは複数のデフォルト実装が提供されているタグ付けインターフェースで、前述の例で使用した NameCallback と PasswordCallback が含まれます。LoginModule は Callback を使用し、認証メカニズムで必要となる情報を要求します。LoginModule は認証のログインフェーズの間に Callback のアレイを直接 CallbackHandler.handle メソッドに渡します。callbackhandler がハンドルメソッドに渡された Callback オブジェクトの使用方法が分からない場合は、UnsupportedCallbackException をスローしてログイン呼び出しを中止します。