第12章 ログインモジュール
12.1. モジュールの使用 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JBoss Enterprise Application Platform には大部分の管理ニーズに合うバンドルされたログインモジュールが含まれています。JBoss Enterprise Application Platform はリレーショナルデーターベース、Lightweight Directory Access Protocol (ライトウェイトディレクトリアクセスプロトコル : LDAP) サーバーまたはフラットファイルからのユーザー情報を読み取ることができます。こうしたコアのログインモジュールに加えて、JBoss はユーザー情報を JBoss の非常にカスタマイズされたニーズに提供する他のログインモジュールも備えています。
12.1.1. LdapLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
LdapLoginModule
は Lightweight Directory Access Protocol (LDAP) サーバーに対して認証する LoginModule
実装です。Java Naming and Directory Interface (JNDI) LDAP プロバイダを使用してアクセス可能な LDAP サーバーにユーザー名と資格情報が保存されている場合は、LdapLoginModule
を使用します。
注記
LDAP を SPNEGO 認証と使用したり、 LDAP サーバーの使用中に認証フェーズの一部をスキップしたい場合は、SPNEGOLoginModule とチェーンされた AdvancedLDAPLogiModule の使用や、 AdvancedLDAPLoginModule のみの使用を検討してください (Negotiation ユーザーガイドを参照してください)。
- 識別名 (DN)
- Lightweight Directory Access Protocol (LDAP) では、識別名は一意的にディレクトリのオブジェクトを特定します。各識別名にはすべての他のオブジェクトからの一意の名前と場所がある必要があり、これは多くの属性値ペア (AVP) を使用することで可能になります。AVP は共通名、組織ユニットなどの情報を定義します。結果としてこうした値の組み合わせは、LDAP が必要とする一意の文字列となります。
注記
このログインモジュールは認証されていないアイデンティティとパスワードスタックにも対応します。
LDAP 接続情報は JNDI 初期コンテキストを作成するために使用する環境オブジェクトに渡される設定オプションとして提供されます。使用される標準の LDAP JNDI プロパティとして以下が挙げられます。
- java.naming.factory.initial
InitialContextFactory
実装クラス名です。これは Sun LDAP プロバイダ実装com.sun.jndi.ldap.LdapCtxFactory
にデフォルト設定されています。- java.naming.provider.url
- LDAP サーバーの LDAP URL です。
- java.naming.security.authentication
- 使用するセキュリティプロトコルのレベルです。使用可能な値は
none
、simple
、strong
などです。プロパティが定義されていない場合は、動作はサービスプロバイダより決定されます。 - java.naming.security.protocol
- セキュアなアクセスのために使用されるトランスポートプロトコルです。この設定オプションをサービスプロバイダ (例えば SSL) のタイプに設定します。プロパティが定義されていない場合は、動作はサービスプロバイダより決定されます。
- java.naming.security.principal
- サービスに呼び出し側を認証するプリンシパルのアイデンティティを指定します。これは以下のような他のプロパティから構築されます。
- java.naming.security.credentials
- サービスに呼び出し側を認証するプリンシパルの資格情報を指定します。資格情報はハッシュされたパスワード、クリアテキストのパスワード、キー、または証明書の形式を取ることができます。プロパティが定義されていない場合は、動作はサービスプロバイダより決定されます。
対応するログインモジュールの設定オプションとして以下が挙げられます。
- principalDNPrefix
- ユーザー 識別名 を形成するためにユーザー名に追加されたプレフィックスです。詳細は
principalDNSuffix
を参照してください。 - principalDNSuffix
- ユーザーの識別名を形成するときにユーザー名に追加されるサフィックスです。これはユーザーにユーザー名の入力を促し、ユーザーが完全な識別名を入力する必要がない場合に役立ちます。このプロパティと
principalDNSuffix
を使用することで、userDN
はprincipalDNPrefix + username + principalDNSuffix
として形成されます。 - useObjectCredential
- 資格情報を示す値は、JAAS
PasswordCallback
を使用したchar[]
パスワードとしてではなく、Callback
のorg.jboss.security.auth.callback.ObjectCallback
タイプを使用して、不透明なObject
として取得されるべきです。これにより、LDAP サーバーにchar[]
でない資格情報を渡すことができます。使用可能な値はtrue
とfalse
です。 - rolesCtxDN
- ユーザーロールを検索するためのコンテキストへの固定した識別名です。
- userRolesCtxDNAttributeName
- ユーザーロールを検索するためのコンテキストへの識別名を含むユーザーオブジェクトの属性名です。これはユーザーのロールを検索するコンテキストは各ユーザーに固有にできる点で、
rolesCtxDN
とは異なります。 - roleAttributeID
- ユーザーロールを含む属性名です。指定されていない場合は、
roles
にデフォルト設定されます。 - roleAttributeIsDN
- roleAttributeID にロールオブジェクトの完全な識別名、またはロール名が含まれるかを示すフラグです。ロール名は識別名によるコンテキスト名の roleNameAttributeId 属性の値から付けられます。true の場合、ロール属性はロールオブジェクトの識別名を表します。false の場合は、ロール名は
roleAttributeID
の値から付けられます。デフォルトはfalse
です。注記
特定のディレクトリスキーマ (例えば MS アクティブディレクトリ) では、ユーザーオブジェクトのロール属性は簡易な名前の代わりに、ロールオブジェクトに Distinguished Names (識別名 : DN) として保存されます。このスキーマタイプを使用する実装の場合、roleAttributeIsDN をtrue
に設定する必要があります。 - roleNameAttributeID
- ロール名を含む roleCtxDN 識別名の値により指し示されたコンテキストの属性名です。roleAttributeIsDN プロパティが
true
に設定されている場合は、このプロパティを使用してロールオブジェクトのname
属性を見つけます。デフォルトはgroup
です。 - uidAttributeID
- ユーザー ID に対応するユーザーロールを含むオブジェクトの属性名です。これを使用してユーザーロールを検索します。指定されていない場合は
uid
にデフォルト設定されます。 - matchOnUserDN
- ユーザーロールの検索がユーザーの完全な識別名と一致すべきかを指定するフラグです。
true
に設定されている場合は、完全なuserDN
は一致する値として使用されます。false
に設定されている場合は、ユーザー名のみが uidAttributeName 属性に対し一致する値として使用されます。デフォルト値はfalse
です。 - unauthenticatedIdentity
- 認証情報を含まない要求に割り当てるプリンシパルの名前です。この動作は
UsernamePasswordLoginModule
スーパークラスから引き継がれます。 - allowEmptyPasswords
- 空の (長さ 0) パスワードが LDAP サーバーに渡されるべきかを示すフラグです。一部の LDAP サーバーは空のパスワードを匿名ログインとして扱いますが、このような動作は望ましくない場合があります。空のパスワードを拒否するには、
false
に設定します。true
に設定すると、LDAP サーバーは空のパスワードを検証します。デフォルトはtrue
です。
ユーザー認証を実行するには、ログインモジュールの設定オプションに基づき LDAP サーバーに接続します。LDAP サーバーに接続するためには、本項で前述したように LDAP JNDI プロパティから構成される環境を持つ
InitialLdapContext
を作成します。
Context.SECURITY_PRINCIPAL は principalDNPrefix と principalDNSuffix オプション値と組み合わせてコールバックハンドラから取得されたユーザーの識別名に設定されており、Context.SECURITY_CREDENTIALS プロパティは useObjectCredential オプションに応じて
String
パスワード、または Object
資格情報のどちらかに設定されます。
認証が成功した (
InitialLdapContext
インスタンスが作成された) 時点で、ユーザーのロールは roleAttributeName と uidAttributeName オプション値に設定された検索属性を持つ rolesCtxDN
ロケーションに関する検索を実行することでクエリされます。ロール名は検索結果セットのロール属性の toString
メソッドを呼び出すことで取得されます。
例12.1 LDAP ログインモジュール認証ポリシー
この認証ポリシーはセキュリティドメイン認証ポリシーのパラメータの使用方法について記述しています。
testLDAP <login-module> 設定の
java.naming.factory.initial
、java.naming.factory.url
、java.naming.security
オプションは次の条件を示しています。
- Sun LDAP JNDI プロバイダ実装が使用されます。
- LDAP サーバーはポート 1389 のホスト
ldaphost.jboss.org
にあります。 - LDAP 簡易認証メソッドを使用して、LDAP サーバーと接続します。
ログインモジュールは、認証を試行しているユーザーを表す識別名 (DN) を使用して LDAP サーバーへの接続を試行します。この DN は前述のとおり、渡された principalDNPrefix、ユーザー名、principalDNSuffix から構成されています。例12.2「LDIF ファイルの例」 では、ユーザー名
jsmith
は uid=jsmith,ou=People,dc=jboss,dc=org
にマップされます。
注記
例では、LDAP サーバーがユーザーのエントリ (この例では
theduke
) の userPassword
属性を使用してユーザーを認証すると仮定しています。ほとんどの LDAP サーバーはこの方法で動作します。ただし、LDAP サーバーが違う方法で認証を行う場合は、ご使用の実稼働環境の要件に応じて LDAP を設定する必要があります。
認証が成功した時点で、uidAttributeID がユーザーと一致するエントリに対し
rolesCtxDN
のサブツリー検索を行うことにより、承認がベースとなるロールが取得されます。matchOnUserDN が true の場合、検索はユーザーの完全な DN に基づきます。そうでない場合は、検索は入力した実際のユーザー名に基づきます。この例では、検索は uid=jduke,ou=People,dc=jboss,dc=org
と等しい member
属性を持つすべてのエントリの ou=Roles,dc=jboss,dc=org
で行います。検索はロールエントリで cn=JBossAdmin
を検索します。
検索は roleAttributeID オプションで指定された属性を返します。この例では、属性は
cn
です。返された属性は JBossAdmin
であるため、jsmith
ユーザーは JBossAdmin
ロールに割り当てられます。
ローカルの LDAP サーバーは多くの場合アイデンティティと認証サービスを備えていますが、承認サービスを使用することはできません。これはアプリケーションロールが常に LDAP グループに適切にマップされているとは限らず、LDAP 管理者は中心の LDAP サーバーで外部のアプリケーション固有のデータを許可したくない場合が多いからです。一般的に LDAP 認証モジュールはデーターベースのログインモジュールなど開発中のアプリケーションにより適したロールを提供できる別のログインモジュールとペアとなっています。
このデータが動作する対象のディレクトリの構造を表す LDAP Data Interchange Format (LDAP データ交換形式 : LDIF) ファイルは 例12.2「LDIF ファイルの例」 に記載されています。
- LDAP データ交換形式 (LDIF)
- プレーンテキストデータは、LDAP ディレクトリのコンテンツと更新要求を表すために使用される形式を交換します。ディレクトリのコンテンツは各オブジェクトまたは各更新要求に対して 1 つの記録として表されます。コンテンツは追加、修正、削除、名前変更の要求で構成されています。
例12.2 LDIF ファイルの例
12.1.2. LdapExtLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
- 識別名 (DN)
- Lightweight Directory Access Protocol (LDAP) では、識別名は一意的にディレクトリのオブジェクトを特定します。各識別名には他のオブジェクトとは異なる一意の名前と場所が必要なため、複数の属性値ペア (AVP) を使用して対応します。AVP は共通名や組織単位などの情報を定義します。結果としてこうした値の組み合わせは、LDAP が必要とする一意の文字列となります。
org.jboss.security.auth.spi.LdapExtLoginModule
は、認証のためにバインドするユーザーと関連するロールを検索します。ロールクエリーは、DN を再帰的に従いロール階層構造をナビゲートします。
LoginModule オプションには、選択された LDAP JNDI プロバイダーによりサポートされるすべてのオプションが含まれます。標準的なプロパティ名の例は以下のとおりです。
- Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
- Context.SECURITY_PROTOCOL = "java.naming.security.protocol"
- Context.PROVIDER_URL = "java.naming.provider.url"
- Context.SECURITY_AUTHENTICATION = "java.naming.security.authentication"
- Context.REFERRAL = "java.naming.referral"
ログインモジュール実装論理は次の順番に従います。
- 最初の LDAP サーバーバインドは bindDN プロパティと bindCredential プロパティを使用して認証されます。bindDN はユーザーとロールのために baseCtxDN ツリーと rolesCtxDN ツリーの両方を検索するパーミッションを持つユーザーです。認証に使用する user DN は、baseFilter プロパティで指定されたフィルターを使用してクエリされます。
- 結果として得られた userDN は userDN を InitialLdapContext 環境 Context.SECURITY_PRINCIPAL として使用し LDAP サーバーにバインドすることにより認証されます。Context.SECURITY_CREDENTIALS プロパティはコールバックハンドラーにより取得される String パスワードに設定されます。
- これに成功すると、rolesCtxDN、roleAttributeID、roleAttributeIsDN、roleNameAttributeID、roleFilter のオプションを使用して関連するユーザーロールがクエリされます。
LdapExtLoginModule プロパティ
- baseCtxDN
- ユーザー検索を開始するコンテキストの固定 DN を指定します。
- bindDN
- ユーザークエリやロールクエリの LDAP サーバーに対してバインドするために使用する DN を指定します。baseCtxDN プロパティと rolesCtxDn プロパティで読み取り/検索パーミッションを持つ DN に bindDN を設定します。
- bindCredential
- bindDN のパスワード。bindCredential は、jaasSecurityDomain が指定されている場合に暗号化できます。このプロパティによって外部コマンドはパスワードを読み取ることができます。たとえば、
{EXT}cat file_with_password
のようになります。 - jaasSecurityDomain
java.naming.security.principal
を復号化するために使用される JaasSecurityDomain の JMX ObjectName。暗号化された形式のパスワードはJaasSecurityDomainencrypt64(byte[])
メソッドによって返されます。暗号化形式のパスワードの生成には org.jboss.security.plugins.PBEUtils を使用することもできます。- baseFilter
- 認証するユーザーのコンテキストを特定するために使用される検索フィルター。ログインモジュールコールバックから取得される入力ユーザー名/userDN は、
{0}
表現が存在するフィルターに代入されます。この代入の動作は標準的なDirContext.search(Name, String, Object[], SearchControls cons)
メソッドから生じます。一般的なサンプル検索フィルターは(uid={0})
です。 - rolesCtxDN
- ユーザーロールを検索するコンテキストの固定 DN。これは実際のロールが存在する DN ではなく、ユーザーロールを含むオブジェクトが存在する DN になります。たとえば、アクティブディレクトリではユーザーカウントが存在する DN になります。
- roleFilter
- 認証されたユーザーに関連するロールを特定するために使用される検索フィルター。ログインモジュールコールバックから取得される入力ユーザー名/userDN は、
{0}
表現が存在するフィルターに代入されます。認証された userDN は{1}
が表示されたフィルターに代入されます。入力ユーザー名に一致する検索フィルターの例は(member={0})
です。認証された userDN に一致するのは(member={1})
です。 - roleAttributeIsDN
- roleAttributeID にロールオブジェクトの完全な DN またはロール名が含まれるかを示すフラグです。ロール名は識別名によるコンテキスト名の roleNameAttributeId 属性の値から派生します。
true
に設定された場合、ロール属性はロールオブジェクトの識別名を表します。false
に設定された場合は、ロール名はroleAttributeID
の値から付けられます。デフォルト値はfalse
です。注記
特定のディレクトリスキーマ (例えば MS アクティブディレクトリ) では、ユーザーオブジェクトのロール属性は簡易な名前の代わりに、ロールオブジェクトに Distinguished Names (識別名 : DN) として保存されます。このスキーマタイプを使用する実装の場合、roleAttributeIsDN をtrue
に設定する必要があります。 - roleAttributeID
- ユーザーロールを含む属性の名前。roleAttributeIsDN が
true
に設定されている場合、このプロパティは roleNameAttributeID 属性をクエリするコンテキストの DN になります。roleAttributeIsDN プロパティがfalse
に設定されている場合、このプロパティはロール名の属性名になります。 - roleNameAttributeID
- ロール名を含む roleCtxDN 識別名の値により指し示されたコンテキストの属性名です。roleAttributeIsDN プロパティが
true
に設定されている場合は、このプロパティを使用してロールオブジェクトのname
属性を見つけます。デフォルトはgroup
です。 - roleRecursion
- ロール検索が該当する一致コンテキストをトラバースするレベルを指定します。デフォルト値は
0
(無効) です。 - searchTimeLimit
- ユーザー/ロール検索のタイムアウト (ミリ秒単位)。デフォルト値は 10000 (10 秒) です。
- searchScope
- 検索スコープをいずれかの文字列に設定します。デフォルト値は SUBTREE_SCOPE です。他のサポートされる値は以下のとおりです。
- OBJECT_SCOPE : 名前付ロールコンテキストのみを検索します。
- ONELEVEL_SCOPE : 名前付きロールコンテキスト以下で直接検索します。
- SUBTREE_SCOPE : ロールコンテキストが DirContext でない場合は、オブジェクトのみを検索します。ロールコンテキストが DirContext の場合、名前付きオブジェクト自体を含む名前付きオブジェクトをルートとするサブツリーを検索します。
- allowEmptyPasswords
empty(length==0)
パスワードを LDAP サーバーに渡すかどうかを示すフラグ。空のパスワードは、一部の LDAP サーバーで匿名ログインとして扱われます。false
に設定された場合、空のパスワードは拒否されます。true
に設定された場合、LDAP サーバーは空のパスワードを検証します。デフォルト値はtrue
です。- defaultRole
- 認証されたすべてのユーザーに含まれるロール。
- parseRoleNameFromDN
- DN がクエリによって返されたかを示すフラグに roleNameAttributeID が含まれます。
true
に設定すると、DN は roleNameATtributeID に対してチェックされます。false
に設定すると、DN は roleNameAttributeID に対してチェックされません。このフラグは LDAP クエリのパフォーマンスを向上することができます。 - parseUsername
- DN が username によって解析されるかを示すフラグです。
true
に設定すると、DN は usernameに対して解析されます。false
に設定すると、DN は username に対して解析されません。このオプションは usernameBeginString と usernameEndString と共に使用されます。 - usernameBeginString
- username を公開するため、DN の最初から削除する文字列を定義します。このオプションは usernameEndString と共に使用されます。
- usernameEndString
- username を公開するため、DN の最後から削除する文字列を定義します。このオプションは usernameBeginString と共に使用されます。
図12.1 LDAP 構造の例
例12.3 2 LDAP 設定の例
この LDAP 構造例のモジュール設定の概要はコード例に示されています。
例12.4 3 LDAP 設定の例
この LDAP 構造例のモジュール設定の概要はコード例に示されています。
例12.5 4 LDAP 設定の例
この LDAP 構造例のモジュール設定の概要はコード例に示されています。
例12.6 デフォルトの ActiveDirectory 設定
以下の例はデフォルトの Active Directory 設定を表します。
例12.7 再帰的ロール ActiveDirectory 設定
以下の例では、ActiveDirectory 内で再帰的ロール検索を実装します。例12.6「デフォルトの ActiveDirectory 設定」 との主な違いは、ロール検索がユーザーの DN を使用してメンバー属性を検索するために置換されることです。ログインモジュールはロールの DN を使用してグループがメンバーであるグループを検出します。
12.1.3. パスワードスタック リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
複数のログインモジュールはスタックでチェーン化でき、認証コンポーネントおよび承認コンポーネントを提供する各ログインモジュールがあります。これは多くの使用事例で動作しますが、認証と承認が複数のユーザー管理ストア全体で分かれる場合があります。
「LdapLoginModule」 では、LDAP とリレーショナルデーターベースを組み合わせ、どちらかのシステムでユーザーが認証されるようにする方法を説明しています。ここで、ユーザーは中心の LDAP サーバーで管理され、アプリケーション固有のロールはアプリケーションのリレーショナルデーターベースに保存されているケースを考えてみましょう。パスワードスタックのモジュールオプションはこの関係を確立します。
パスワードスタックを使用するには、各ログインモジュールは <module-option>
password-stacking
属性を useFirstPass
に設定しなければなりません。パスワードスタックに設定された以前のモジュールがユーザーを認証している場合、その他すべてのスタックモジュールはユーザーが認証されたと見なし、承認ステップへのロールセットの提供のみ実行しようとします。
password-stacking
オプションが useFirstPass
に設定されている場合、このモジュールは最初にログインモジュールの共有状態マップにあるプロパティ名 javax.security.auth.login.name で共有ユーザー名を探し、 プロパティ名 javax.security.auth.login.password でパスワードを探します。
見つかった場合は、これらのプロパティはプリンシパル名とパスワードとして使用されます。見つからない場合は、プリンシパル名とパスワードはこのログインモジュールで設定され、プリンシパル名はプロパティ名 javax.security.auth.login.name、パスワードはプロパティ名 javax.security.auth.login.password で保存されます。
注記
パスワードスタックを使用する場合、必要になるようすべてのモジュールを設定します。これにより全モジュールが考慮され、ロールを承認プロセスに提供できるようにします。
例12.8 パスワードスタックのサンプル
この例はパスワードスタックの使用方法を示しています。
12.1.4. パスワードのハッシュ化 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ほとんどのログインモジュールはクライアント提供のパスワードとユーザー管理システムに保存されているパスワードとを比較する必要があります。こうしたモジュールは通常プレーンテキストのパスワードと動作しますが、プレーンテキストのパスワードがサーバー側で保存されないようにハッシュされたパスワードに対応するよう設定することができます。
例12.9 パスワードのハッシュ化
以下は、プリンシパル名
nobody
を認証されていないユーザーに割り当て、usersb64.properties
ファイルにパスワードの Base 64 エンコード化と MD5 ハッシュが含まれるログインモジュール設定です。usersb64.properties
ファイルはデプロイメントクラスパスの一部となり、/conf
ディレクトリに保存することができます。
- hashAlgorithm
- パスワードをハッシュするために使用する
java.security.MessageDigest
アルゴリズムの名前です。デフォルトはないため、ハッシュを有効にするにはこのオプションを指定します。一般的な値はMD5
とSHA
です。 - hashEncoding
base64
、hex
またはrfc2617
の 3 つのエンコーディングタイプのうち 1 つを指定する文字列です。デフォルトはbase64
です。- hashCharset
- クリアテキストのパスワードをバイト配列に変換するために使用するエンコーディング文字セットです。プラットフォームのエンコーディングがデフォルトです。
- hashUserPassword
- ユーザーが提出するパスワードにハッシュアルゴリズムが適用される必要があることを指定します。ハッシュされたユーザーパスワードはログインモジュールの値と比較され、パスワードのハッシュとして要求されます。デフォルトは
true
です。 - hashStorePassword
- サーバー側に保存されているパスワードにハッシュアルゴリズムが適用される必要があることを指定します。これはダイジェスト認証に使用され、ユーザーは比較するサーバーからの要求固有のトークンとともにユーザーパスワードのハッシュを提出します。ハッシュアルゴリズム (ダイジェストでは
rfc2617
) は、サーバー側のハッシュを計算するために使用され、クライアントから送られるハッシュ値と一致しなければなりません。
コードでパスワードを生成する必要がある場合、
org.jboss.security.Util
クラスは、指定されたエンコーディングを使用してパスワードをハッシュ化する静的ヘルパーメソッドを提供します。 次の例は base64 でエンコードされ、MD5 にてハッシュ化されたパスワードになります。
String hashedPassword = Util.createPasswordHash("MD5", Util.BASE64_ENCODING, null, null, "password");
String hashedPassword = Util.createPasswordHash("MD5",
Util.BASE64_ENCODING, null, null, "password");
OpenSSL はコマンドラインでハッシュ化されたパスワードを即座に生成できる別の方法を提供します。次の例もbase64 でエンコードされ、MD5 でハッシュ化されたパスワードを作成します。この例では、base64 でエンコードされた形式に変換するため、プレーンテキストのパスワード
password
が OpenSSL のダイジェスト関数へパイプされた後、別の OpenSSL 関数にパイプされています。
echo -n password | openssl dgst -md5 -binary | openssl base64
echo -n password | openssl dgst -md5 -binary | openssl base64
両方の場合とも、ハッシュ化されたパスワードは
X03MO1qnZdYdgyfeuILPmQ==
になります。前述の例のアプリケーションポリシーに指定されたユーザープロパティファイル usersb64.properties
にこの値を保存する必要があります。
12.1.5. 認証されていないアイデンティティ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
すべての要求が認証された形式で受け取られるとは限りません。
unauthenticated identity
は関連付けられた認証情報を持たない要求に特定のアイデンティティ (ゲストなど) を割り当てるログインモジュール設定オプションです。これを使用して、保護されていないサーブレットが特定のロールを必要としない EJB でメソッドを呼び出すことができます。そのようなプリンシパルには関連付けられたロールがないため、セキュアでない EJB または確認されていないパーミッション制約に関連付けられた EJB メソッドにのみアクセスできます。
- unauthenticatedIdentity: これは認証情報を含まない要求に割り当てられる必要があるプリンシパル名を定義します。
12.1.6. UsersRolesLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
UsersRolesLoginModule
は Java プロパティファイルからロードされた複数のユーザーとユーザーロールに対応する簡易ログインモジュールです。ユーザー名からパスワードへのマッピングファイルは users.properties
と呼ばれ、ユーザー名からロールへのマッピングファイルは roles.properties
と呼ばれます。
対応するログインモジュールの設定オプションとして以下が挙げられます。
- usersProperties
- ユーザー名からパスワードへのマッピング含むプロパティリソース (ファイル) の名前です。これはデフォルトで
<filename_prefix>-users.properties
に設定されます。 - rolesProperties
- ユーザー名からロールへのマッピング含むプロパティリソース (ファイル) の名前です。これはデフォルトで
<filename_prefix>-roles.properties
に設定されます。
このログインモジュールは、パスワードスタック、パスワードハッシュ、認証されていないアイデンティティに対応します。
プロパティファイルは、initialize メソッドのスレッドコンテキストクラスローダーを使用して初期化中にロードされます。そのため、こうしたファイルは Java EE deployment JAR、JBoss の設定ディレクトリ、JBoss サーバーまたはシステムクラスパスのどのディレクトリにも置くことができます。このログインモジュールの第一の目的は、アプリケーションでデプロイされたプロパティファイルを使用して複数のユーザーとロールのセキュリティ設定を簡単にテストすることです。
例12.10 UserRolesLoginModule
例12.10「UserRolesLoginModule」 では、
ejb3-sampleapp-users.properties
ファイルは各ユーザーエントリが 1 行ずつになっている username=password
形式を使用します。
username1=password1 username2=password2 ...
username1=password1
username2=password2
...
例12.10「UserRolesLoginModule」 で参照された
ejb3-sampleapp-roles.properties
ファイルは、オプションのグループ名の値が付いたパターン username=role1,role2,
を使用します。例は次の通りです。
username1=role1,role2,... username1.RoleGroup1=role3,role4,... username2=role1,role3,...
username1=role1,role2,...
username1.RoleGroup1=role3,role4,...
username2=role1,role3,...
ejb3-sampleapp-roles.properties
に存在している user name.XXX プロパティ名のパターンを使用して、ユーザー名のロールを特定の名前付きロールグループに割り当てます。プロパティ名の XXX
の部分はグループ名を表します。user name=... の形式は user name.Roles=... の省略形で、Roles
グループ名は JaasSecurityManager
がユーザーのパーミッションを定義するロールを含むために必要な標準名です。
次は
jduke
ユーザー名の定義と同等です。
jduke=TheDuke,AnimatedCharacter jduke.Roles=TheDuke,AnimatedCharacter
jduke=TheDuke,AnimatedCharacter
jduke.Roles=TheDuke,AnimatedCharacter
12.1.7. DatabaseServerLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
DatabaseServerLoginModule
は認証とロールマッピングに対応する Java Database Connectivity-based (JDBC) ログインモジュールです。ユーザー名、パスワード、ロール情報がリレーショナルデーターベースに保存されている場合は、このログインモジュールを使用します。
注記
このモジュールは、パスワードスタック、パスワードハッシュ、認証されていないアイデンティティに対応します。
DatabaseServerLoginModule
は 2 つの論理テーブルに基づいています。
Table Principals(PrincipalID text, Password text) Table Roles(PrincipalID text, Role text, RoleGroup text)
Table Principals(PrincipalID text, Password text)
Table Roles(PrincipalID text, Role text, RoleGroup text)
Principals
テーブルはユーザー PrincipalID
を有効なパスワードに関連付け、Roles
テーブルはユーザー PrincipalID
をそのロールのセットに関連付けます。ユーザーパーミッションに使用されるロールは Roles
の RoleGroup
列の値がある行に含まれている必要があります。
ログインモジュールが使用する SQL クエリを指定できるという点でこれらのテーブルは論理的です。唯一の要件は、
java.sql.ResultSet
が前述した Principals
および Roles
テーブルと同じ論理構造を持つことです。その結果は列インデックスに基づいてアクセスされるため、テーブルと列の実際の名前は関連していません。
この概念を明確にするために、すでに宣言されているとおりの
Principals
および Roles
の 2 つのテーブルを持つデーターベースを考えてみましょう。次のステートメントで以下のデータを持つテーブルを生成します。
Principals
テーブルのechoman
のPassword
を持つPrincipalID
java
Roles
テーブルのRoles
RoleGroup
のEcho
という名前のロールを持つPrincipalID
java
Roles
テーブルのCallerPrincipal
RoleGroup
のcaller_java
という名前のロールを持つPrincipalID
java
INSERT INTO Principals VALUES('java', 'echoman') INSERT INTO Roles VALUES('java', 'Echo', 'Roles') INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')
INSERT INTO Principals VALUES('java', 'echoman')
INSERT INTO Roles VALUES('java', 'Echo', 'Roles')
INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')
対応するログインモジュールの設定オプションとして以下が挙げられます。
- dsJndiName
- 論理テーブル
Principals
およびRoles
を含むデーターベースのDataSource
の JNDI 名です。指定されていない場合は、java:/DefaultDS
にデフォルト設定されます。 - principalsQuery
- 準備されたステートメントのクエリで、
select Password from Principals where PrincipalID=?
と同等です。指定されていない場合は、これが使用される正確な準備されたステートメントとなります。 - rolesQuery
- 準備されたステートメントのクエリで
select Role, RoleGroup from Roles where PrincipalID=?
と同等です。指定されていない場合は、これが使用される正確な準備されたステートメントとなります。 - ignorePasswordCase
- パスワード比較で大文字と小文字の区別を無視するべきかを示すプール型のフラグです。これは、ハッシュされたパスワードの大文字と小文字の区別が重要でないハッシュされたパスワードのエンコードに役立つことがあります。
- principalClass
Principal
実装クラスを指定するオプションです。これはプリンシパル名に文字列引数を取るコンストラクタに対応する必要があります。
DatabaseServerLoginModule
設定の例として、以下のように作成することができます。
CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64)) CREATE TABLE UserRoles(username VARCHAR(64), userRoles VARCHAR(32))
CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64))
CREATE TABLE UserRoles(username VARCHAR(64), userRoles VARCHAR(32))
対応する
login-config.xml
エントリは以下のようになります。
12.1.8. BaseCertLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
BaseCertLoginModule
は X509 証明書に基づいてユーザーを認証します。このログインモジュールの一般的な使用事例は Web 層の CLIENT-CERT
認証です。
このログインモジュールは認証のみ行います。セキュアな Web または EJB コンポーネントへのアクセスを完全に定義するためには、承認ロールの取得が可能な別のログインモジュールと組み合わせる必要があります。このログインモジュールの 2 つのサブクラスである
CertRolesLoginModule
と DatabaseCertLoginModule
は、動作を拡張しプロパティファイルまたはデーターベースのいずれかから承認ロールを取得します。
BaseCertLoginModule
ではユーザー検証を実行するために KeyStore
が必要です。これは org.jboss.security.SecurityDomain
実装から取得します。一般的には SecurityDomain
実装は この jboss-service.xml
設定の一部で示されているように org.jboss.security.plugins.JaasSecurityDomain
MBean を使用して設定します。
この設定では
jmx-console
という名前を持つセキュリティドメインと java:/jaas/jmx-console
という名前のもとで JNDI を通じて使用可能な SecurityDomain
実装を作成します。セキュリティドメインは JBossSX セキュリティドメインの名前付けパターンに従います。
手順12.1 Web アプリケーションを証明書とロールベースの承認でセキュアにする
この手順ではクライアント証明書とロールベースの承認を使用して、
jmx-console.war
などの Web アプリケーションをセキュアにする方法について説明します。
リソースとロールを宣言します
web.xml
を修正し、認証と承認に使用される許可されたロールとセキュリティドメインとともにリソースがセキュアされることを宣言します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow JBoss セキュリティドメインを指定します
jboss-web.xml
ファイルで、必須のセキュリティドメインを指定します。<jboss-web> <security-domain>jmx-console</security-domain> </jboss-web>
<jboss-web> <security-domain>jmx-console</security-domain> </jboss-web>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ログインモジュール設定を指定します
今指定した jmx-console セキュリティドメインに対しログインモジュール設定を定義します。conf/login-config.xml
ファイルで行います。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
手順12.1「Web アプリケーションを証明書とロールベースの承認でセキュアにする」 では
BaseCertLoginModule
がクライアント証明書の認証に使用され、UsersRolesLoginModule
が password-stacking=useFirstPass
オプションにより承認にのみ使用されることを示しています。localhost.keystore
と jmx-console-roles.properties
ともクライアント証明書に関連付けられたプリンシパルにマップするエントリが必要です。
デフォルトでは、プリンシパルは 例12.11「証明書の例」 で指定された DN などクライアント証明書の識別名を使用して作成されます
例12.11 証明書の例
localhost.keystore
は CN=unit-tests-client, OU=JBoss Inc., O=JBoss Inc., ST=Washington, C=US
のエイリアスで保存された 例12.11「証明書の例」 の証明書が必要となります。jmx-console-roles.properties
も同じエントリに対しエントリが必要です。DN には通常区切り記号として扱われる文字列が含まれるため、以下のようにバックスラッシュ ('\
') を使用して許可されていない文字列をエスケープします。
A sample roles.properties file for use with the UsersRolesLoginModule
# A sample roles.properties file for use with the UsersRolesLoginModule
CN\=unit-tests-client,\ OU\=JBoss\ Inc.,\ O\=JBoss\ Inc.,\ ST\=Washington,\ C\=US=JBossAdmin
admin=JBossAdmin
12.1.9. IdentityLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
IdentityLoginModule
はハードコードされたユーザー名をモジュールに対して認証されるすべてのサブジェクトに関連付ける簡易ログインモジュールです。principal
オプションで指定された名前を使用して SimplePrincipal
インスタンスを作成します。
注記
このモジュールはパスワードスタックに対応します。
このログインモジュールは、固定アイデンティティをサービスに提供する必要がある場合や、特定のプリンシパルと関連するロールに関連付けられたセキュリティをテストするときの開発環境に役立ちます。
対応するログインモジュールの設定オプションとして以下が挙げられます。
- principal
SimplePrincipal
に対して使用する名前で、すべてのユーザーはこの名前として認証されます。プリンシパルオプションが指定されていない場合、プリンシパル名はguest
にデフォルト設定されます。- roles
- ユーザーに割り当てられるロールをコンマで区切った一覧です。
XMLLoginConfig 設定エントリのサンプルは以下のとおりです。エントリはすべてのユーザーを
jduke
という名前のプリンシパルとして認証し、TheDuke
および AnimatedCharacter
のロール名を割り当てます。
12.1.10. RunAsLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
RunAsLoginModule
(org.jboss.security.auth.spi.RunAsLoginModule
) はヘルパーモジュールで、run as role を認証のログインフェーズの期間にスタックにプッシュし、コミットまたは中止中のいずれかで run as role をポップします。
このログインモジュールの目的は、認証を実行するためにセキュアなリソースにアクセスする必要がある他のログインモジュールにロールを提供することです (例えば、セキュアな EJB にアクセスするログインモジュールなど)。
RunAsLoginModule
は run as role を確立する必要があるログインモジュールより先に設定する必要があります。
唯一のログインモジュールの設定オプションは以下のとおりです。
- roleName
- ログインフェーズの間に run as role として使用するロール名です。指定されていない場合は、デフォルトの
nobody
が使用されます。
12.1.11. RunAsIdentity の作成 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JBoss Enterprise Application Platform が EJB メソッドへのアクセスをセキュアにするため、メソッド呼び出しが実行された時にユーザーアイデンティティは既知とならなければなりません。
サーバーのユーザーアイデンティティは
javax.security.auth.Subject
インスタンスまたは org.jboss.security.RunAsIdentity
インスタンスのいずれかで表されます。これらのクラスは共に、アイデンティティとそのアイデンティティが所有するロールの一覧を表す 1 つ以上のプリンシパルを保存します。javax.security.auth.Subject
の場合は、資格情報の一覧も保存されます。
ejb-jar.xml
デプロイメント記述子の <assembly-descriptor> セクションでは、様々な EJB メソッドにアクセスするためにユーザーが必要な 1 つ以上のロールを指定します。これらの一覧を比較することで、EJB メソッドにアクセスするためにユーザーが必要なロールの 1 つを持っているかが分かります。
例12.12 org.jboss.security.RunAsIdentity の作成
ejb-jar.xml
ファイルで、<session> 要素の子として定義された <run-as> ロールを持つ <security-identity> 要素を指定します。
この宣言では「Admin」RunAsIdentity ロールが作成される必要があることを意味します。
Admin ロールにプリンシパルの名前を付けるには、
jboss-web.xml
ファイルの <run-as-principal>
要素を定義します。
ejb-jar.xml
および jboss-web.xml
ファイルの <security-identity>
要素はデプロイメント時に解析されます。その後、<run-as>
ロール名と <run-as-principal>
の名前が org.jboss.metadata.SecurityIdentityMetaData
クラスに保存されます。
例12.13 RunAsIdentity への複数ロールの割り当て
RunAsIdentity にさらにロールを割り当てるには、
jboss-web.xml
デプロイメント記述子 <assembly-descriptor>
要素グループのプリンシパルにロールをマップします。
例12.12「org.jboss.security.RunAsIdentity の作成」 では 「Mark」の
<run-as-principal>
が作成されました。この例の設定は「Support」ロールを追加することで「Admin」ロールを拡張します。新しいロールには当初定義されたプリンシパル「John」などの追加のプリンシパルが含まれています。
ejb-jar.xml
および jboss.xml
ファイルの <security-role>
要素はデプロイメント時に解析されます。<role-name>
と <principal-name>
データは org.jboss.metadata.SecurityIdentityMetaData
クラスに保存されます。
12.1.12. ClientLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ClientLoginModule
(org.jboss.security.ClientLoginModule
) は呼び出し側アイデンティティと資格情報を確立するために JBoss クライアントにより使用されることを目的とした LoginModule
の実装です。これは単に org.jboss.security.SecurityAssociation.principal
を callbackhandler
によって入力された NameCallback
の値に設定し、また org.jboss.security.SecurityAssociation.credential
を callbackhandler
によって入力された PasswordCallback
の値に設定します。
ClientLoginModule
は、クライアントが現在のスレッドの呼び出し側を確立するために唯一サポートされているメカニズムです。スタンドアローンのクライアントアプリケーションとサーバー環境 (セキュリティ環境は透過的に JBossSX を使用するように設定されていない場面で JBoss EJB クライアントとして働きます) の両方とも ClientLoginModule
を使用する必要があります。
このログインモジュールは認証は行わないことに注意してください。そのログインモジュールに提供されたログイン情報をサーバー上の後続の認証に対して JBoss サーバー EJB 呼び出しレイヤにコピーするだけです。ユーザーのクライアント側認証を実行する必要がある場合は、
ClientLoginModule
に加えて別のログインモジュールを設定する必要があるでしょう。
対応するログインモジュールの設定オプションとして以下が挙げられます。
- multi-threaded
- ログインスレッドがプリンシパルと資格情報ストレージソースに接続する方法を指定する値です。true に設定する場合、各ログインスレッドは独自のプリンシパルと資格情報ストレージを持ち、それぞれ別々のスレッドが独自のログインを実行します。これは複数のユーザーアイデンティティが別々のスレッドでアクティブであるクライアント環境で役立ちます。false に設定する場合、ログインアイデンティティと資格情報は VM のすべてのスレッドに適用するグローバル変数です。デフォルト設定は
false
です。 - password-stacking
LdapLoginModule
などの他のログインモジュールを使用してクライアントのクライアント側認証をアクティブにします。password-stacking
オプションがuseFirstPass
に設定されている場合、モジュールは最初にログインモジュールの共有状態マップのjavax.security.auth.login.name
とjavax.security.auth.login.password
をそれぞれ使用して共有のユーザー名とパスワードを探します。その結果、これより前に設定されたモジュールは有効な JBoss ユーザー名とパスワードを確立することができます。- restore-login-identity
login()
メソッドへのエントリで見えるSecurityAssociation
プリンシパルと資格情報が中止またはログアウトのいずれかで保存、回復されているかを指定する値です。これが必要なのは、アイデンティティを変更してもともとの呼び出し側のアイデンティティを回復する場合です。true
に設定されている場合は、プリンシパルと資格情報は中止またはログアウトで保存、回復されます。false
に設定されている場合は、中止とログアウトはSecurityAssociation
をクリアにします。デフォルト値はfalse
です。
12.1.13. SPNEGOLoginModule リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
SPNEGOLoginModule
(org.jboss.security.negotiation.spnego.SPNEGOLoginModule
) は、KDC で呼び出し側のアイデンティティと資格情報を確立する LoginModule
の実装です。モジュールは SPNEGO (Simple and Protected GSSAPI Negotiation メカニズム) を実装する JBoss Negotiation プロジェクトの一部です。AdvancedLDAPLoginModule とチェーンされた設定でこの認証を使用し、LDAP サーバーと連携できるようにすることができます。 JBoss Negotiation の詳細については、JBoss Negotiation ユーザーガイドを参照してください。