1.5. JAAS レルムの作成
1.5.1. Elytron の JAAS レルム リンクのコピーリンクがクリップボードにコピーされました!
Java Authentication and Authorization Service (JAAS) レルム jaas-realm は、ユーザーの認証情報の検証とユーザーのロールの割り当てのために elytron サブシステムでカスタムログインモジュールを設定するために使用できるセキュリティーレルムです。
jaas-realm を使用して、JBoss EAP 管理インターフェイスとデプロイされたアプリケーションの両方を保護できます。
JAAS レルムは、JAAS 設定ファイルで指定されたログインモジュールを使用する javax.security.auth.login.LoginContext を初期化することにより、ユーザーの認証情報を検証します。
ログインモジュールは、javax.security.auth.login.LoginContext.LoginModule インターフェイスの実装です。これらの実装を JBoss EAP モジュールとしてサーバーに追加し、JAAS 設定ファイルで指定します。
JAAS 設定ファイルの例
test {
loginmodules.CustomLoginModule1 optional;
loginmodules.CustomLoginModule2 optional myOption1=true myOption2=exampleOption;
};
- 1
jaas-realmを設定するときに使用するエントリーの名前。- 2
- 任意のフラグを持つログインモジュール。JAAS で定義されているすべてのフラグを使用できます。詳細は、Oracle Java SE ドキュメントの JAAS ログイン設定ファイル を参照してください。
- 3
- 任意のフラグおよびオプションを含むログインモジュール。
ログインモジュールの属性マッピングおよびロールの関連付けへのサブジェクトのプリンシパル
サブジェクト のプリンシパルを利用して、ログインモジュールから取得した ID に属性を追加できます。サブジェクト は認証されるユーザーであり、プリンシパルはサブジェクト内に含まれるユーザー名などの識別子です。
Elytron は、次のように ID を取得してマッピングします。
-
ログインモジュールは、
javax.security.auth.Subjectを使用して、認証されるユーザー、サブジェクト を表します。 -
サブジェクト には、
java.security.Principal、principal の複数のインスタンスを関連付けることができます。 -
Elytron は、
org.wildfly.security.auth.server.SecurityIdentityを使用して認証されたユーザーを表します。SecurityIdentityの 対象となる Elytron マップ。
サブジェクトの プリンシパル は、以下のルールでセキュリティーアイデンティティーの属性にマッピングされます。
-
属性の
keyは、principal.getClass().getSimpleName()呼び出しによって取得された principal の単純なクラス名です。 -
valueは、principal.getName()呼び出しによって取得された プリンシパル の名前です。 - 同じタイプの プリンシパル の場合、値は属性キーの下のコレクションに追加されます。
1.5.2. カスタム JAAS ログインモジュールの開発 リンクのコピーリンクがクリップボードにコピーされました!
カスタム Java Authentication and Authorization Service (JAAS) ログインモジュールを作成して、カスタム認証および認可機能を実装できます。
Elytron サブシステムの jaas-realm を介してカスタム JAAS ログインモジュールを使用して、JBoss EAP 管理インターフェイスおよびデプロイされたアプリケーションをセキュア化できます。ログインモジュールはデプロイメントの一部ではなく、JBoss EAP モジュールとして含まれます。
以下の手順は例としてのみ提供されています。保護する必要があるアプリケーションがすでにある場合は、以下の手順をスキップして、アプリケーションへの認証と認可の追加 に直接進むことができます。
1.5.2.1. JAAS ログインモジュール開発の Maven プロジェクトの作成 リンクのコピーリンクがクリップボードにコピーされました!
カスタム Java Authentication and Authorization Service (JAAS) ログインモジュールを作成するには、必要な依存関係とディレクトリー構造を使用して Maven プロジェクトを作成します。
前提条件
- Maven がインストールされている。詳細は、Downloading Apache Maven を参照してください。
手順
CLI で
mvnコマンドを使用して Maven プロジェクトを設定します。このコマンドは、プロジェクトのディレクトリー構造とpom.xml設定ファイルを作成します。構文
$ mvn archetype:generate \ -DgroupId=<group-to-which-your-application-belongs> \ -DartifactId=<name-of-your-application> \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-simple \ -DinteractiveMode=false例
$ mvn archetype:generate \ -DgroupId=com.example.loginmodule \ -DartifactId=example-custom-login-module \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-simple \ -DinteractiveMode=falseアプリケーションのルートディレクトリーに移動します。
構文
$ cd <name-of-your-application>例
$ cd example-custom-login-module生成された
pom.xmlファイルの内容を、以下のテキストに置き換えます。<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>custom.loginmodules</groupId> <artifactId>custom-login-modules</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.wildfly.security</groupId> <artifactId>wildfly-elytron</artifactId> <version>1.17.2.Final</version> </dependency> <dependency> <groupId>jakarta.security.enterprise</groupId> <artifactId>jakarta.security.enterprise-api</artifactId> <version>3.0.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </project>この例ではディレクトリーは必要ないため、ディレクトリー
siteを削除してtestします。$ rm -rf src/site/ $ rm -rf src/test/
検証
アプリケーションのルートディレクトリーで、次のコマンドを入力します。
$ mvn install次のような出力が得られます。
... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.404 s [INFO] Finished at: 2022-04-28T13:55:18+05:30 [INFO] ------------------------------------------------------------------------
カスタム JAAS ログインモジュールを作成できるようになりました。
1.5.2.2. カスタム JAAS ログインモジュールの作成 リンクのコピーリンクがクリップボードにコピーされました!
javax.security.auth.spi.LoginModule インターフェイスを実装するクラスを作成して、カスタム Java Authentication and Authorization Service (JAAS) ログインモジュールを作成します。さらに、カスタムログインモジュールのフラグとオプションを含む JAAS 設定ファイルを作成します。
この手順では、<application_home> は、アプリケーションの pom.xml 設定ファイルが含まれるディレクトリーを参照します。
前提条件
Maven プロジェクトを作成している。
詳細は、JAAS ログインモジュール開発用の Maven プロジェクトの作成 を参照してください。
手順
Java ファイルを保存するディレクトリーを作成します。
構文
$ mkdir -p src/main/java/<path_based_on_artifactID>例
$ mkdir -p src/main/java/com/example/loginmoduleソースファイルを含むディレクトリーに移動します。
構文
$ cd src/main/java/<path_based_on_groupID>例
$ cd src/main/java/com/example/loginmodule生成されたファイル
App.javaを削除します。$ rm App.javaカスタムログインモジュールソースの
ExampleCustomLoginModule.javaファイルを作成します。package com.example.loginmodule; import org.wildfly.security.auth.principal.NamePrincipal; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import java.io.IOException; import java.security.Principal; import java.util.Arrays; import java.util.HashMap; import java.util.Map; public class ExampleCustomLoginModule implements LoginModule { private final Map<String, char[]> usersMap = new HashMap<String, char[]>(); private Principal principal; private Subject subject; private CallbackHandler handler; /** * In this example, identities are created as fixed Strings. * * The identities are: * user1 has the password passwordUser1 * user2 has the password passwordUser2 * * Use these credentials when you secure management interfaces * or applications with this login module. * * In a production login module, you would get the identities * from a data source. * */ @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { this.subject = subject; this.handler = callbackHandler; this.usersMap.put("user1", "passwordUser1".toCharArray()); this.usersMap.put("user2", "passwordUser2".toCharArray()); } @Override public boolean login() throws LoginException { // obtain the incoming username and password from the callback handler NameCallback nameCallback = new NameCallback("Username"); PasswordCallback passwordCallback = new PasswordCallback("Password", false); Callback[] callbacks = new Callback[]{nameCallback, passwordCallback}; try { this.handler.handle(callbacks); } catch (UnsupportedCallbackException | IOException e) { throw new LoginException("Error handling callback: " + e.getMessage()); } final String username = nameCallback.getName(); this.principal = new NamePrincipal(username); final char[] password = passwordCallback.getPassword(); char[] storedPassword = this.usersMap.get(username); if (!Arrays.equals(storedPassword, password)) { throw new LoginException("Invalid password"); } else { return true; } } /** * user1 is assigned the roles Admin, User and Guest. * In a production login module, you would get the identities * from a data source. * */ @Override public boolean commit() throws LoginException { if (this.principal.getName().equals("user1")) { this.subject.getPrincipals().add(new Roles("Admin")); this.subject.getPrincipals().add(new Roles("User")); this.subject.getPrincipals().add(new Roles("Guest")); } return true; } @Override public boolean abort() throws LoginException { return true; } @Override public boolean logout() throws LoginException { this.subject.getPrincipals().clear(); return true; } /** * Principal with simple classname 'Roles' will be mapped to the identity's attribute with name 'Roles'. */ private static class Roles implements Principal { private final String name; Roles(final String name) { this.name = name; } /** * @return name of the principal. This will be added as a value to the identity's attribute which has a name equal to the simple name of this class. In this example, this value will be added to the attribute with a name 'Roles'. */ public String getName() { return this.name; } } }<application_home> ディレクトリーに、JAAS 設定ファイル
JAAS-login-modules.confを作成します。exampleConfiguration { com.example.loginmodule.ExampleCustomLoginModule optional; };-
exampleConfigurationはエントリー名です。 -
com.example.loginmodule.ExampleCustomLoginModuleはログインモジュールです。 -
optionalはフラグです。
-
ログインモジュールをコンパイルします。
$ mvn package ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.321 s [INFO] Finished at: 2022-04-28T14:16:03+05:30 [INFO] ------------------------------------------------------------------------
これで、ログインモジュールを使用して JBoss EAP 管理インターフェイスとデプロイされたアプリケーションを保護できます。
1.5.3. Elytron での jaas-realm の作成 リンクのコピーリンクがクリップボードにコピーされました!
Java Authentication and Authorization Service (JAAS) 互換のカスタムログインモジュールに基づく Elytron セキュリティーレルムを作成して、JBoss EAP サーバーインターフェイスまたはデプロイされたアプリケーションを保護します。セキュリティーレルムを使用して、セキュリティードメインを作成します。
前提条件
カスタムログインモジュールを JAR としてパッケージ化しました。
ログインモジュールの例は、カスタム JAAS ログインモジュールの開発 を参照してください。
- JBoss EAP が実行されている。
手順
管理 CLI を使用してログインモジュール JAR をモジュールとして JBoss EAP に追加します。
構文
module add --name=<name_of_the_login_moudle> --resources=<path_to_the_login_module_jar> --dependencies=org.wildfly.security.elytron例
module add --name=exampleLoginModule --resources=<path_to_login_module>/custom-login-modules-1.0.jar --dependencies=org.wildfly.security.elytronログインモジュールと JAAS ログイン設定ファイルから
jaas-realmを作成します。構文
/subsystem=elytron/jaas-realm=<jaas_realm_name>:add(entry=<entry-name>,path=<path_to_module_config_file>,module=<name_of_the_login_module>,callback-handler=<name_of_the_optional_callback_handler>)例
/subsystem=elytron/jaas-realm=exampleSecurityRealm:add(entry=exampleConfiguration,path=<path_to_login_module>/JAAS-login-modules.conf,module=exampleLoginModule)jaas-realmを参照するセキュリティードメインを作成します。構文
/subsystem=elytron/security-domain=<security_domain_name>:add(default-realm=<jaas_realm_name>,realms=[{realm=<jaas_realm_name>}],permission-mapper=default-permission-mapper)例
/subsystem=elytron/security-domain=exampleSecurityDomain:add(default-realm=exampleSecurityRealm,realms=[{realm=exampleSecurityRealm}],permission-mapper=default-permission-mapper) {"outcome" => "success"}
これで、作成したセキュリティードメインを使用して、管理インターフェイスとアプリケーションに認証と認可を追加できるようになりました。詳細は、管理インターフェイスとアプリケーションの保護 を参照してください。