16.2. カスタムモジュール
AuthenticationManager は Subject プリンシパルセットの特定の使用パターンを必要とします。AuthenticationManager と動作するログインモジュールを書くには、JAAS サブジェクトクラスの情報ストレージ機能と、これらの機能の想定される使用方法を理解する必要があります。
LoginModule 実装を紹介します。
Subject に関連するセキュリティー情報を取得できます。
Subject アイデンティティーおよびロールに対し、EAP は getPrincipals() および getPrincipals(java.lang.Class) から取得したプリンシパルセットを選択します。使用パターンは次のとおりです。
- ユーザーアイデンティティー (例: ユーザー名、従業員 ID など) は
java.security.PrincipalオブジェクトとしてSubjectPrincipalsセットに保存されます。ユーザーアイデンティティーを示すPrincipal実装は、プリンシパルの名前に基づいた比較および等価が必要になります。適切な実装はorg.jboss.security.SimplePrincipalクラスとして使用可能です。必要な場合は、他のPrincipalインスタンスをSubjectPrincipalsに追加できます。 - 割り当てられたユーザーロールも
Principalsセットに保存され、java.security.acl.Groupインスタンスを使用して名前付きロールセットにグループ化されます。Groupインターフェースはjava.security.Principalのサブインスタンスで、PrincipalやGroupのコレクションを定義します。 - 任意の数のロールセットを
Subjectに割り当てできます。
- EAP セキュリティーフレームワークは、
RolesおよびCallerPrincipalという名前の 2 つのロールセットを使用します。Rolesグループは、Subjectが認証されたアプリケーションドメインで知られる名前付きロールのPrincipalのコレクションです。このロールセットは、現在の呼び出し側が名前付きアプリケーションドメインロールに属するかどうかを確認するために EJB が使用できるEJBContext.isCallerInRole(String)などのメソッドによって使用されます。メソッドパーミッションチェックを実行するセキュリティーインターセプターロジックもこのロールセットを使用します。CallerPrincipalGroupは、アプリケーションドメインのユーザーに割り当てられた単一のPrincipalアイデンティティーで構成されます。EJBContext.getCallerPrincipal()メソッドはCallerPrincipalを使用して、アプリケーションドメインが操作環境アイデンティティーからアプリケーションに適したユーザーアイデンティティーへマップできるようにします。SubjectにCallerPrincipalGroupがない場合、アプリケーションアイデンティティーは操作環境アイデンティティーと同じになります。
16.2.1. サブジェクト使用パターンのサポート リンクのコピーリンクがクリップボードにコピーされました!
Subject 使用パターンを正しく簡単に実装するため、適切に Subject を使用できるようにするテンプレートパターンを認証された Subject に追加するログインモジュールが EAP に含まれています。
2 つのログインモジュールでより汎用的なのが org.jboss.security.auth.spi.AbstractServerLoginModule クラスです。
javax.security.auth.spi.LoginModule の実装を提供し、操作環境セキュリティーインフラストラクチャー固有の主要タスクに対して抽象メソッドを提供します。このクラスの主な詳細は、例16.20「AbstractServerLoginModule クラスの一部」を参照してください。JavaDoc のコメントでサブクラスの役割が説明されています。
重要
loginOk インスタンス変数が極めて重要になります。ログインに成功した場合はこれを true に設定する必要があります。ログインに失敗した場合は、ログインメソッドをオーバーライドするサブクラスによって false に設定する必要があります。この変数が適切に設定されないと、コミットメソッドは適切にサブジェクトを更新しません。
例16.20 AbstractServerLoginModule クラスの一部
カスタムログインモジュールに適している 2 つ目の抽象ベースログインモジュールは org.jboss.security.auth.spi.UsernamePasswordLoginModule です。
char[] パスワードを認証クレデンシャルとすることで、カスタムログインモジュールの実装をさらに簡素化します。また、このログインモジュールは、匿名ユーザー (null のユーザー名とパスワードによって示される) をロールを持たないプリンシパルへマップすることをサポートします。クラスの主な詳細は以下を参照してください。JavaDoc のコメントでサブクラスの役割が説明されています。
例16.21 UsernamePasswordLoginModule クラスの一部
文字別ベースのユーザー名とクレデンシャルが、作成中のカスタムログインモジュールの認証技術で使用できるかどうかを基に AbstractServerLoginModule と UsernamePasswordLoginModule のどちらをサブクラス化するかを決定します。文字別ベースのセマンティックが有効な場合は UsernamePasswordLoginModule をサブクラス化し、その他の場合は AbstractServerLoginModule をサブクラスします。
カスタムログインモジュールが実行する手順は、選択するベースログインモジュールクラスによって異なります。セキュリティーインフラストラクチャーと統合するカスタムログインモジュールを作成する場合は、EAP セキュリティーマネージャーが想定する形式の認証された Principal 情報がログインモジュールによって提供されるようにするため、最初に AbstractServerLoginModule または UsernamePasswordLoginModule をサブクラス化します。
AbstractServerLoginModule をサブクラス化する場合は、以下をオーバーライドする必要があります。
void initialize(Subject, CallbackHandler, Map, Map): 解析するカスタムオプションがある場合。boolean login(): 認証を行うため。ログインに成功した場合は必ずloginOkインスタンス変数を true に設定します。失敗した場合は false に設定します。Principal getIdentity():log()手順によって認証されたユーザーのPrincipalオブジェクトを返します。Group[] getRoleSets(): 最低でも、login()の間に認証されたPrincipalへ割り当てられたロールが含まれるRolesという名前のGroupを返します。次に一般的なGroupの名前はCallerPrincipalで、セキュリティードメインアイデンティティーではなくユーザーのアプリケーションアイデンティティーを提供します。
UsernamePasswordLoginModule をサブクラス化する場合は、以下をオーバーライドする必要があります。
void initialize(Subject, CallbackHandler, Map, Map): 解析するカスタムオプションがある場合。Group[] getRoleSets(): 最低でも、login()の間に認証されたPrincipalへ割り当てられたロールが含まれるRolesという名前のGroupを返します。次に一般的なGroupの名前はCallerPrincipalで、セキュリティードメインアイデンティティーではなくユーザーのアプリケーションアイデンティティーを提供します。String getUsersPassword():getUsername()メソッドより使用可能な現在のユーザー名の想定されるパスワードを返します。callbackhandlerがユーザー名と候補のパスワードを返した後、getUsersPassword()メソッドはlogin()内から呼び出されます。