第14章 ログインモジュール
14.1. モジュールの使用
14.1.1. パスワードスタッキング
password-stacking
属性を useFirstPass
に設定する必要があります。パスワードスタッキングに設定した以前のモジュールがユーザーを認証した場合、他のすべてのスタッキングモジュールがユーザーによって認証されたこととなり、承認の手順でロールの提供のみを行います。
password-stacking
オプションを useFirstPass
に設定すると、このモジュールは最初に、ログインモジュール共有状態マップで、プロパティー名 javax.security.auth.login.name と javax.security.auth.login.password で共有ユーザー名とパスワードを検索します。
例14.1 パスワードスタッキングの例
/subsystem=security/security-domain=pwdStack/authentication=classic/login-module=Ldap:add( \ code=Ldap, \ flag=required, \ module-options=[ \ ("password-stacking"=>"useFirstPass"), \ ... Ldap login module configuration ]) /subsystem=security/security-domain=pwdStack/authentication=classic/login-module=Database:add( \ code=Database, \ flag=required, \ module-options=[ \ ("password-stacking"=>"useFirstPass"), \ ... Database login module configuration ])
14.1.2. パスワードのハッシュ化
例14.2 パスワードのハッシュ化
nobody
を割り当て、usersb64.properties
ファイルのパスワードの base64 でエンコードされた SHA-256 ハッシュが含まれるログインモジュール設定です。usersb64.properties
ファイルはデプロイメントクラスパスの一部です。
/subsystem=security/security-domain=testUsersRoles:add /subsystem=security/security-domain=testUsersRoles/authentication=classic:add /subsystem=security/security-domain=testUsersRoles/authentication=classic/login-module=UsersRoles:add( \ code=UsersRoles, \ flag=required, \ module-options=[ \ ("usersProperties"=>"usersb64.properties"), \ ("rolesProperties"=>"test-users-roles.properties"), \ ("unauthenticatedIdentity"=>"nobody"), \ ("hashAlgorithm"=>"SHA-256"), \ ("hashEncoding"=>"base64") \ ])
- hashAlgorithm
- パスワードのハッシュ化に使用する
java.security.MessageDigest
アルゴリズムの名前。デフォルトがないため、ハッシュを有効にするには、このオプションを指定する必要があります。一般的な値はSHA-256
、SHA-1
、およびMD5
です。 - hashEncoding
base64
、16 進数
、またはrfc2617
の 3 つのエンコーディングタイプのいずれかを指定する文字列。デフォルトはbase64
です。- hashCharset
- クリアテキストのパスワードをバイトアレイに変換するために使用されるエンコーディング文字セット。プラットフォームのデフォルトエンコーディングはデフォルトです。
- hashUserPassword
- ユーザーが送信するパスワードに適用する必要があるハッシュアルゴリズムを指定します。ハッシュ化されたユーザーパスワードは、ログインモジュール内の値と比較されます. これは、パスワードのハッシュです。デフォルトは
true
です。 - hashStorePassword
- サーバー側に保存されているパスワードに適用する必要があるハッシュアルゴリズムを指定します。これはダイジェスト認証に使用され、ユーザーが、比較するサーバーからの要求固有のトークンとともにユーザーパスワードのハッシュを送信します。ハッシュアルゴリズム(ダイジェストでは
rfc2617
)はサーバー側のハッシュを計算するために使用されます。これは、クライアントから送信されるハッシュ化された値と一致している必要があります。
org.jboss.security.auth.spi.Util
クラスは、指定されたエンコーディングを使用してパスワードをハッシュ化する静的ヘルパーメソッドを提供します。以下の例では、base64 でエンコードされた MD5 ハッシュされたパスワードを生成します。
String hashedPassword = Util.createPasswordHash("SHA-256", Util.BASE64_ENCODING, null, null, "password");
password
- は OpenSSL ダイジェスト関数にパイプされ、base64 でエンコードされた形式に変換するために別の OpenSSL 関数にパイプされます。
echo -n password | openssl dgst -sha256 -binary | openssl base64
XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=
.この値は、上記の例のセキュリティードメイン(user b64.properties)に指定されたユーザーのプロパティー
ファイルに保存する必要があります。
14.1.3. 認証されていない ID
unauthenticatedIdentity
は、特定の ID(guest など)を、関連する認証情報を持たない要求に割り当てるログインモジュール設定オプションです。これを使用すると、保護されていないサーブレットは特定ロールを必要としない EJB でメソッドを呼び出すことができます。このようなプリンシパルには関連したロールがなく、セキュアでない EJB や、チェックされていないパーミッション制約と関連する EJB メソッドのみにアクセスできます。
- unauthenticatedIdentity: これは、認証情報のない要求に割り当てる必要のあるプリンシパル名を定義します。
14.1.4. Ldap ログインモジュール
LDAP
ログインモジュールは、LDAP(Lightweight Directory Access Protocol)サーバーに対して認証を行う LoginModule
実装です。ユーザー名および認証情報が JNDI(Java Naming and Directory Interface)LDAP プロバイダーを使用してアクセス可能な LDAP サーバーに保存されている場合は、Ldap
ログインモジュールを使用します。
AdvancedLdap
ログインモジュールを使用することを検討するか、AdvancedLdap
ログインモジュールのみを使用することを検討してください。
- 識別名(DN)
- Lightweight Directory Access Protocol(LDAP)では、識別名はディレクトリー内のオブジェクトを一意に識別します。各識別名には、他のオブジェクトと区別するための一意名と場所が必要で、これには属性と値のペア (AVP) を使用します。AVP は、共通名、組織単位などの情報を定義します。LDAP に必要となる一意な文字列は、これらの値の組み合わせになります。
- 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
- サービスに対する呼び出し元を認証する Principal のアイデンティティーを指定します。これは、以下で説明するように他のプロパティーから構築されます。
- java.naming.security.credentials
- サービスに対して呼び出し元を認証する Principal の認証情報を指定します。認証情報は、ハッシュ化されたパスワード、クリアテキストパスワード、キー、または証明書の形式を取ることができます。プロパティーが定義されていない場合、動作はサービスプロバイダーによって決定されます。
true
に設定する必要があります。
InitialLdapContext
を作成して行います。
(initialLdapContext
instance)、検索属性を roleAttributeName および uidAttributeName に設定して rolesCtxDN
の場所で検索を実行すると、ユーザーのロールがクエリーされます。ロール名は、検索結果セットでロール属性の toString
メソッドを呼び出すことで取得します。
例14.3 LDAP ログインモジュールのセキュリティードメイン
/subsystem=security/security-domain=testLDAP:add(cache-type=default) /subsystem=security/security-domain=testLDAP/authentication=classic:add /subsystem=security/security-domain=testLDAP/authentication=classic/login-module=Ldap:add( \ code=Ldap, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org:1389/"), \ ("java.naming.security.authentication"=>"simple"), \ ("principalDNPrefix"=>"uid="), \ ("principalDNSuffix"=>",ou=People,dc=jboss,dc=org"), \ ("rolesCtxDN"=>"ou=Roles,dc=jboss,dc=org"), \ ("uidAttributeID"=>"member"), \ ("matchOnUserDN"=>true), \ ("roleAttributeID"=>"cn"), \ ("roleAttributeIsDN"=>false) \ ])
java.naming.factory.initial
オプション、java.naming.factory.url
オプション、および java.naming.security
オプションは、以下の条件を示しています。
- Sun LDAP JNDI プロバイダー実装が使用されます。
- LDAP サーバーは、ポート 1389 のホスト
ldaphost.jboss.org
にあります。 - LDAP 簡易認証方法は、LDAP サーバーへの接続に使用されます。
jsmith
は uid=jsmith,ou=People,dc=jboss,dc=org
にマップされました。
userPassword
属性を使用してユーザーを認証します(この例ではtheduke
)。ほとんどの LDAP サーバーはこの方法で動作しますが、LDAP サーバーが認証ごとに異なる場合は、LDAP が実稼働環境の要件に応じて設定する必要があります。
rolesCtxDN
のサブツリー検索を実行して、承認に基づくロールを取得します。matchOnUserDN が true の場合、検索はユーザーの完全な DN を基にします。それ以外の場合は、入力した実際のユーザー名をもとに検索が行われます。この例では、uid=jsmith,ou=People,dc=jboss,dc=org
と同等の メンバー
属性を持つエントリーの検索は ou=Roles,dc=jboss,dc=org
の下にあります。検索は、roles エントリーの下に cn=JBossAdmin
を見つけます。
cn
です。返される値は JBossAdmin
であるため、jsmith
ユーザーは JBossAdmin
ロールに割り当てられます。
- LDAP データ交換形式(LDIF)
- LDAP ディレクトリーの内容を表し、リクエストを更新するために使用されるプレーンテキストデータ交換形式。ディレクトリーの内容は、各オブジェクトまたは更新要求に対して 1 つのレコードとして表されます。コンテンツは、要求の追加、変更、削除、および名前変更で構成されます。
例14.4 LDIF ファイルの例
dn: dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jsmith,ou=People,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person uid: jsmith cn: John sn: Smith userPassword: theduke dn: ou=Roles,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: Roles dn: cn=JBossAdmin,ou=Roles,dc=jboss,dc=org objectclass: top objectclass: groupOfNames cn: JBossAdmin member: uid=jsmith,ou=People,dc=jboss,dc=org description: the JBossAdmin group
14.1.5. LdapExtended ログインモジュール
- 識別名(DN)
- Lightweight Directory Access Protocol(LDAP)では、識別名はディレクトリー内のオブジェクトを一意に識別します。各識別名には、他のオブジェクトと区別するための一意名と場所が必要で、これには属性と値のペア (AVP) を使用します。AVP は、共通名、組織単位などの情報を定義します。LDAP に必要となる一意な文字列は、これらの値の組み合わせになります。
org.jboss.security.auth.spi.LdapExtLoginModule)
は、バインドするユーザーとその関連のロールを検索します。ロールは再帰的にクエリーを行い、DN に従って階層的なロール構造を移動します。
- 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 を InitialLdapContext 環境 userDN として使用して、生成される Context.SECURITY_PRINCIPAL は LDAP サーバーにバインドされ、認証されます。Context.SECURITY_CREDENTIALS プロパティーは、コールバックハンドラーが取得した String パスワードに設定されます。
- これに成功すると、関連付けられたユーザーロールは rolesCtxDN、roleAttributeID、roleAttributeIsDN、roleNameAttributeID、および roleFilter オプションを使用してクエリーされます。
- 最上位のロールは roleAttributeID に対してのみクエリーされ、roleNameAttributeID にはクエリーされません。
- roleAttributeIsDN モジュールプロパティーを false に設定すると、recurseRoles モジュールオプションが true に設定されている場合でも再帰的なロール検索が無効になります。
図14.1 LDAP 構造の例

[D]
例14.5 2 つの LDAP 設定の例
version: 1 dn: o=example2,dc=jboss,dc=org objectClass: top objectClass: organization o: example2 dn: ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: judke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke2 employeeNumber: judke2-123 sn: Duke2 uid: jduke2 userPassword:: dGhlZHVrZTI= dn: ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke dn: uid=jduke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke2 dn: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the echo role member: uid=jduke,ou=People,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke description: the duke role member: uid=jduke,ou=People,o=example2,dc=jboss,dc=org dn: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo2 description: the Echo2 role member: uid=jduke2,ou=People,dc=jboss,dc=org dn: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke2 description: the duke2 role member: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org dn: cn=JBossAdmin,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: JBossAdmin description: the JBossAdmin group member: uid=jduke,ou=People,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample2/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example2,dc=jboss,dc=org"), \ ("baseFilter"=>"(uid={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example2,dc=jboss,dc=org"), \ ("roleFilter"=>"(uid={0})"), \ ("roleAttributeIsDN"=>"true"), \ ("roleAttributeID"=>"memberOf"), \ ("roleNameAttributeID"=>"cn") \ ])
例14.6 3 つの LDAP 設定の例
dn: o=example3,dc=jboss,dc=org objectclass: top objectclass: organization o: example3 dn: ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person objectClass: inetOrgPerson uid: jduke employeeNumber: judke-123 cn: Java Duke sn: Duke userPassword: theduke dn: ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org uid: jduke dn: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the JBossAdmin group member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample3/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example3,dc=jboss,dc=org"), \ ("baseFilter"=>"(cn={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example3,dc=jboss,dc=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleAttributeID"=>"cn") \ ])
例14.7 4 つの LDAP 設定の例
dn: o=example4,dc=jboss,dc=org objectclass: top objectclass: organization o: example4 dn: ou=People,o=example4,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example4,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: jduke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: ou=Roles,o=example4,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG1 member: cn=empty dn: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG2 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org dn: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG3 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R1 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R2,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R2 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R3,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R3 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R4,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R4 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R5,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R5 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample4/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example4,dc=jboss,dc=org"), \ ("baseFilter"=>"(cn={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example4,dc=jboss,dc=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleRecursion"=>"1"), \ ("roleAttributeID"=>"memberOf") \ ])
例14.8 デフォルトの Active Directory 設定
/subsystem=security/security-domain=AD_Default/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("bindDN"=>"JBOSS\searchuser"), \ ("bindCredential"=>"password"), \ ("baseCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("baseFilter"=>"(sAMAccountName={0})"), \ ("rolesCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("roleFilter"=>"(sAMAccountName={0})"), \ ("roleAttributeID"=>"memberOf"), \ ("roleAttributeIsDN"=>"true"), \ ("roleNameAttributeID"=>"cn"), \ ("searchScope"=>"ONELEVEL_SCOPE"), \ ("allowEmptyPasswords"=>"false") \ ])
例14.9 再帰的なロールの Active Directory 設定
/subsystem=security/security-domain=AD_Recursive/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.referral"=>"follow"), \ ("bindDN"=>"JBOSS\searchuser"), \ ("bindCredential"=>"password"), \ ("baseCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("baseFilter"=>"(sAMAccountName={0})"), \ ("rolesCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleAttributeID"=>"cn"), \ ("roleAttributeIsDN"=>"false"), \ ("roleRecursion"=>"2"), \ ("searchScope"=>"ONELEVEL_SCOPE"), \ ("allowEmptyPasswords"=>"false") \ ])
14.1.6. UsersRoles ログインモジュール
UsersRoles
ログインモジュールは、Java プロパティーファイルからロードされる複数のユーザーおよびユーザーロールをサポートする簡単なログインモジュールです。デフォルトの username-to-password マッピングのファイル名は users.properties
で、デフォルトの username-to-roles マッピングのファイル名は roles.properties
です。
WAR
アーカイブの WEB-INF/classes
フォルダー)またはサーバークラスパス上の任意のディレクトリーに配置できます。このログインモジュールの主な目的は、アプリケーションとともにデプロイされたプロパティーファイルを使用して複数のユーザーおよびロールのセキュリティー設定を簡単にテストすることです。
例14.10 UsersRoles ログインモジュール
/subsystem=security/security-domain=ejb3-sampleapp/authentication=classic/login-module=UsersRoles:add( \ code=UsersRoles, \ flag=required, \ module-options=[ \ ("usersProperties"=>"ejb3-sampleapp-users.properties"), \ ("rolesProperties"=>"ejb3-sampleapp-roles.properties") \ ])
username1=password1 username2=password2 ...
ejb3-sampleapp-roles.properties
ファイルは、任意のグループ名の値で username=role1
,role2 パターンを使用します。以下に例を示します。
username1=role1,role2,... username1.RoleGroup1=role3,role4,... username2=role1,role3,...
ejb3-sampleapp-roles.properties
にある user name.XXX プロパティー名パターンは、特定の名前付きロールのグループにこのユーザー名のロールを割り当てます。ここで、プロパティー名の XXX
部分はグループ名です。user name=... フォームは、user name.Roles=... の省略形です。ここで、Roles
グループ名は、JBossAuthorizationManager
がユーザーのパーミッションを定義するロールが含まれることが想定される標準名です。
jduke
ユーザー名の同等の定義です。
jduke=TheDuke,AnimatedCharacter jduke.Roles=TheDuke,AnimatedCharacter
14.1.7. Database ログインモジュール
Database
ログインモジュールは、認証とロールマッピングをサポートする JDBC(Java Database Connectivity-based)ログインモジュールです。ユーザー名、パスワード、およびロール情報をリレーショナルデータベースに保存している場合は、このログインモジュールを使用します。
Database
ログインモジュールは 2 つの論理テーブルに基づいています。
Table Principals(PrincipalID text, Password text) Table Roles(PrincipalID text, Role text, RoleGroup text)
Principals
テーブルは PrincipalID
ユーザーと有効なパスワードと、Roles
テーブルは PrincipalID
ユーザーとそのロールセットを関連付けます。ユーザーパーミッションに使用されるロールは、Roles
の RoleGroup
コラムの値を持つ行に含まれる必要があります。
java.sql.ResultSet
は前述の Principals
および Roles
と同じ論理構造を持ちます。テーブル名およびコラムの実際の名前は、コラムのインデックスに基づいてアクセスされるため、関係ありません。
Principals
と Roles
の 2 つのテーブルが含まれるデータベースを考慮してください。以下のステートメントは、以下のデータをテーブルに追加します。
Principals
テーブルにPrincipalID
が
java
でパスワードがechoman
の javaRoles
テーブルのRoles
RoleGroup
にはPrincipalID
がjava
でロールがEcho
のデータを投入Roles
テーブルのCallerPrincipal
RoleGroup
にPrincipalID
がjava
でロールがcaller_java
である
INSERT INTO Principals VALUES('java', 'echoman') INSERT INTO Roles VALUES('java', 'Echo', 'Roles') INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')
Database ログインモジュール
設定の例は、以下のように作成できます。
CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64)) CREATE TABLE UserRoles(username VARCHAR(64), role VARCHAR(32))
/subsystem=security/security-domain=testDB/authentication=classic/login-module=Database:add( \ code=Database, \ flag=required, \ module-options=[ \ ("dsJndiName"=>"java:/MyDatabaseDS"), \ ("principalsQuery"=>"select passwd from Users where username=?"), \ ("rolesQuery"=>"select role, 'Roles' from UserRoles where username=?") \ ])
14.1.8. Certificate ログインモジュール
書
ログインモジュールは、X509 証明書に基づいてユーザーを認証します。このログインモジュールの典型的なユースケースが、web 層の CLIENT-CERT
認証です。
CertRolesLoginModule
と DatabaseCertLoginModule
は動作を拡張し、プロパティーファイルまたはデータベースから承認ロールを取得します。
Certificate
ログインモジュールオプションの詳細は、「含まれる認証モジュール」 を参照してください。
Certificate
ログインモジュールは、ユーザー検証を実行するには KeyStore
が必要です。これは、以下の設定フラグメントに示されるように、リンクされたセキュリティードメインの JSSE 設定から取得されます。
/subsystem=security/security-domain=trust-domain:add /subsystem=security/security-domain=trust-domain/jsse=classic:add( \ truststore={ \ password=>pass1234, \ url=>/home/jbosseap/trusted-clients.jks \ }) /subsystem=security/security-domain=testCert:add /subsystem=security/security-domain=testCert/authentication=classic:add /subsystem=security/security-domain=testCert/authentication=classic/login-module=Certificate:add( \ code=Certificate, \ flag=required, \ module-options=[ \ ("securityDomain"=>"trust-domain"), \ ])
手順14.1 証明書およびロールベースの承認を使用した Web アプリケーションのセキュア化
user-app.war
などの Web アプリケーションのセキュリティーを保護する方法を説明します。この例では、CertificateRoles
ログインモジュールが認証および承認に使用されます。trusted-clients.keystore
と app-roles.properties
の両方には、クライアント証明書に関連付けられたプリンシパルにマップするエントリーが必要です。
リソースおよびロールの宣言
web.xml
を変更し、認証および承認に使用される許可されるロールとセキュリティードメインと共にセキュアなリソースを宣言します。<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <security-constraint> <web-resource-collection> <web-resource-name>Protect App</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> <realm-name>Secured area</realm-name> </login-config> <security-role> <role-name>Admin</role-name> </security-role> </web-app>
セキュリティードメインの指定
jboss-web.xml
ファイルで、必要なセキュリティードメインを指定します。<jboss-web> <security-domain>app-sec-domain</security-domain> </jboss-web>
ログインモジュールの設定
管理 CLI を使用して指定したapp-sec-domain
ドメインのログインモジュール設定を定義します。[ /subsystem=security/security-domain=trust-domain:add /subsystem=security/security-domain=trust-domain/jsse=classic:add( \ truststore={ \ password=>pass1234, \ url=>/home/jbosseap/trusted-clients.jks \ }) /subsystem=security/security-domain=app-sec-domain:add /subsystem=security/security-domain=app-sec-domain/authentication=classic:add /subsystem=security/security-domain=app-sec-domain/authentication=classic/login-module=CertificateRoles:add( \ code=CertificateRoles, \ flag=required, \ module-options=[ \ ("securityDomain"=>"trust-domain"), \ ("rolesProperties"=>"app-roles.properties") \ ])
例14.11 証明書の例
[conf]$ keytool -printcert -file valid-client-cert.crt Owner: CN=valid-client, OU=Security QE, OU=JBoss, O=Red Hat, C=CZ Issuer: CN=EAP Certification Authority, OU=Security QE, OU=JBoss, O=Red Hat, C=CZ Serial number: 2 Valid from: Mon Mar 24 18:21:55 CET 2014 until: Tue Mar 24 18:21:55 CET 2015 Certificate fingerprints: MD5: 0C:54:AE:6E:29:ED:E4:EF:46:B5:14:30:F2:E0:2A:CB SHA1: D6:FB:19:E7:11:28:6C:DE:01:F2:92:2F:22:EF:BB:5D:BF:73:25:3D SHA256: CD:B7:B1:72:A3:02:42:55:A3:1C:30:E1:A6:F0:20:B0:2C:0F:23:4F:7A:8E:2F:2D:FA:AF:55:3E:A7:9B:2B:F4 Signature algorithm name: SHA1withRSA Version: 3
trusted-clients.keystore
では、CN=valid-client、OU=Security QE、OU=JBoss、O=Red Hat、C=CZ
のエイリアスで 例14.11「証明書の例」 に保存されている証明書が必要です。app-roles.properties
に同じエントリーが必要です。DN には通常区切り文字として扱われる文字が含まれるため、以下のようにバックスラッシュ('\
')を使用して問題文字をエスケープする必要があります。
# A sample app-roles.properties file CN\=valid-client,\ OU\=Security\ QE,\ OU\=JBoss,\ O\=Red\ Hat,\ C\=CZ
14.1.9. Identity ログインモジュール
Identity
ログインモジュールは、ハードコーディングされたユーザー名をモジュールに対して認証されたサブジェクトに関連付ける簡単なログインモジュールです。プリンシパル
オプションで指定した名前を使用して SimplePrincipal
インスタンスを作成します。
jduke
という名前のプリンシパルとして認証し、TheDuke
および AnimatedCharacter
のロール名を割り当てます。
/subsystem=security/security-domain=testIdentity:add /subsystem=security/security-domain=testIdentity/authentication=classic:add /subsystem=security/security-domain=testIdentity/authentication=classic/login-module=Identity:add( \ code=Identity, \ flag=required, \ module-options=[ \ ("principal"=>"jduke"), \ ("roles"=>"TheDuke,AnimatedCharacter") \ ])
14.1.10. RunAs ログインモジュール
RunAs
ログインモジュールは、認証のログインフェーズの間に 実行をロールと
してスタックにプッシュするヘルパーモジュールで、コミットまたはアボートフェーズでスタックからロール として実行
をポップします。
RunAs
ログインモジュールは、run-as
ロールの構築が必要なログインモジュールよりも先に設定する必要があります。
14.1.10.1. RunAsIdentity Creation
javax.security.auth.Subject
インスタンスまたは org.jboss.security.RunAsIdentity
インスタンスによって表されます。これらのクラスはいずれも、アイデンティティーを表す 1 つ以上のプリンシパルとアイデンティティーが所有するロールの一覧を保存します。javax.security.auth.Subject
の場合、認証情報の一覧も保存されます。
ejb-jar.xml
デプロイメント記述子の <assembly-descriptor> セクションで、ユーザーがさまざまな EJB メソッドにアクセスするために必要なロールを 1 つ以上指定します。これらの一覧の比較は、ユーザーに EJB メソッドへのアクセスに必要なロールの 1 つがあるかどうかを示します。
例14.12 org.jboss.security.RunAsIdentity Creation
ejb-jar.xml
ファイルで、<session> 要素の子として定義された <security-identity> ロールで <run-as> 要素を指定します。
<session> ... <security-identity> <run-as> <role-name>Admin</role-name> </run-as> </security-identity> ... </session>
Admin
RunAsIdentity ロールを作成する必要があることを示します。
管理
ロールのプリンシパルに名前を付けるには、jboss-ejb3 .xml ファイルに <run-as-
principal
> 要素を定義します。
<jboss:ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns:s="urn:security:1.1" version="3.1" impl-version="2.0"> <assembly-descriptor> <s:security> <ejb-name>WhoAmIBean</ejb-name> <s:run-as-principal>John</s:run-as-principal> </s:security> </assembly-descriptor> </jboss:ejb-jar>
jboss -ejb3.xml ファイルの ejb-jar.xml
と < security
> 要素の両方にある <security-
identity
> 要素はデプロイメント時に解析されます。& lt;run-as&
gt; のロール名と < run-as-principal
> 名は org.jboss.metadata.ejb.spec.SecurityIdentityMetaData
クラスに保存されます。
例14.13 RunAsIdentity への複数ロールの割り当て
jboss-ejb3.xml デプロイメント記述子 < assembly-
descriptor
> 要素グループのプリンシパルにマッピングすることで、より多くのロールを RunAsIdentity に割り当てることができます。
<jboss:ejb-jar xmlns:sr="urn:security-role" ...> <assembly-descriptor> ... <sr:security-role> <sr:role-name>Support</sr:role-name> <sr:principal-name>John</sr:principal-name> <sr:principal-name>Jill</sr:principal-name> <sr:principal-name>Tony</sr:principal-name> </sr:security-role> </assembly-descriptor> </jboss:ejb-jar>
John
の <run-as-principal>
; が作成されました。この例の設定では、Support
ロールを追加して Admin
ロールを拡張します。新しいロールには、最初に定義したプリンシパル John
を含む追加のプリンシパルが含まれます。
ejb -jar.xml
ファイルおよび jboss-ejb3.xml ファイル両方の <security-
role>
要素は、デプロイメント時に解析されます。<role-name&
gt; および <principal-name
> データは org.jboss.metadata.ejb.spec.SecurityIdentityMetaData
クラスに保存されます。
14.1.11. Client ログインモジュール
org.jboss.security. Client
LoginModule
)は、呼び出し元のアイデンティティーとクレデンシャルを確立するときに JBoss クライアントによって使用される LoginModule
の実装です。これにより、新しい SecurityContext
がプリンシパルとクレデンシャルに割り当て、SecurityContext
を ThreadLocal
セキュリティーコンテキストに設定します。
クライアント
ログインモジュールは、クライアントが現在のスレッドの呼び出し元を確立するために唯一サポートされているメカニズムです。スタンドアロンクライアントアプリケーションとサーバー環境(セキュリティー環境が EAP security サブシステムを使用するよう透過的に設定されていない JBoss EJB クライアントとして機能するため)は、Client
ログインモジュールを使用する必要があります。
Client
ログインモジュールに加えて、別のログインモジュールを設定する必要があります。
14.1.12. SPNEGO ログインモジュール
SPNEGO
ログインモジュール(org.jboss.security.negotiation.spnego.SPNEGOLoginModule
)は、KDC で呼び出し元のアイデンティティーとクレデンシャルを確立する LoginModule
の実装です。モジュールは SPNEGO(Simple および Protected GSSAPI Negotiation メカニズム)を実装し、JBoss Negotiation プロジェクトの一部です。この認証は、AdvancedLdap
ログインモジュールとチェーンされた設定で使用することができ、LDAP サーバーと連携できるようにします。
SPNEGO
または AdvancedLdap
ログインモジュールを使用するには、META-INF/jboss-deployment-structure.xml
デプロイメント記述子ファイルを編集して依存関係を手動で追加する必要があります。
例14.14 JBoss Negotiation モジュールを依存関係として追加
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security.negotiation" /> </dependencies> </deployment> </jboss-deployment-structure>
14.1.13. RoleMapping ログインモジュール
RoleMapping
ログインモジュールは、認証プロセスの最終結果であるロールを 1 つ以上の宣言的ロールへのマッピングをサポートします。たとえば、ユーザー "A" に "ldapAdmin" と "testAdmin" のロールがあり、web.xml
または ejb-jar.xml
ファイルで定義された宣言型ロールは admin
であると認証プロセスが判断された場合、このログインモジュールは admin
ロールをユーザー A
にマッピングします。
RoleMapping
ログインモジュールオプションの詳細は、「含まれる認証モジュール」 を参照してください。
RoleMapping
ログインモジュールは、以前マップされたロールのマッピングを変更するため、ログインモジュール設定でオプションのモジュールとして定義する必要があります。
例14.15 マッピングされたロールの定義
/subsystem=security/security-domain=test-domain-2/:add /subsystem=security/security-domain=test-domain-2/authentication=classic:add /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test-2-lm/:add(\ flag=required,\ code=UsersRoles,\ module-options=[("usersProperties"=>"users.properties"),("rolesProperties"=>"roles.properties")]\ ) /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test2-map/:add(\ flag=optional,\ code=RoleMapping,\ module-options=[("rolesProperties"=>"rolesMapping-roles.properties")]\ )
例14.16 マップされたロールを定義するための推奨される方法
/subsystem=security/security-domain=test-domain-2/:add /subsystem=security/security-domain=test-domain-2/authentication=classic:add /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test-2-lm/:add(\ flag=required,\ code=UsersRoles,\ module-options=[("usersProperties"=>"users.properties"),("rolesProperties"=>"roles.properties")]\ ) /subsystem=security/security-domain=test-domain-2/mapping=classic/mapping-module=test2-map/:add(\ code=PropertiesRoles,type=role,\ module-options=[("rolesProperties"=>"rolesMapping-roles.properties")]\ )
例14.17 RoleMappingLoginModule によって使用されるプロパティーファイル
ldapAdmin=admin, testAdmin
ldapAdmin
ロールが含まれている場合は、replaceRole プロパティーの値に応じて admin
ロールおよび testAdmin
ロールが追加されたり、認証されたサブジェクトを置き換えたりします。
14.1.14. bindCredential モジュールオプション
bindCredential
モジュールオプションは、DN の認証情報を保存するために使用され、複数のログインおよびマッピングモジュールで使用できます。パスワードを取得する方法は複数あります。
- 管理 CLI コマンドのプレーンテキストです。
bindCredential
モジュールのパスワードは、管理 CLI コマンドでプレーンテキストで指定できます。たとえば、("bindCredential"=>"secret1")
のようになります。セキュリティー上の理由から、パスワードは JBoss EAP vault のメカニズムを使用して暗号化する必要があります。- 外部コマンドを使用する。
- 外部コマンドの出力からパスワードを取得するには、
{EXT}...
の形式を使用します。ここで、...
は外部コマンドになります。コマンド出力の最初の行がパスワードとして使用されます。パフォーマンスを向上させるために、{EXTC[:expiration_in_millis]}
バリアントは指定された数のミリ秒のパスワードをキャッシュします。デフォルトでは、キャッシュされたパスワードは期限切れになりません。0
(ゼロ)の値を指定すると、キャッシュされた認証情報の有効期限はありません。EXTC
バリアントはLdapExtended
ログインモジュールでのみサポートされます。
例14.18 外部コマンドからパスワードを取得します。
{EXT}cat /mysecretpasswordfile
例14.19 外部ファイルからパスワードを取得し、500 ミリ秒キャッシュします。
{EXTC:500}cat /mysecretpasswordfile