4.2. Elytron クライアントによるクライアント認証の設定
EJB などの JBoss EAP に接続するクライアントは、Elytron クライアントを使用して認証できます。Elytron クライアントは、リモートクライアントが Elytron で認証可能にするクライアント側フレームワークです。Elytron クライアントには以下のコンポーネントがあります。
- authentication-configuration
-
認証設定には、ユーザー名、パスワード、承認済みの SASL メカニズムなどの認証情報と、ダイジェスト認証時に使用するセキュリティーレルムが含まれます。認証設定で指定した接続情報は、初期コンテキストの
PROVIDER_URL
で指定した値よりも優先されます。 - MatchRule
- 使用する認証設定の決定に使用されるルール。
- authentication-context
- 接続の確立にクライアントで使用するルールおよび認証設定のセット。
接続が確立されると、クライアントは認証コンテキストを使用します。この認証コンテキストには、各アウトバウンド接続に使用する認証設定を選択するルールが含まれます。たとえば、server1
への接続時に 1 つの認証設定を使用し、server2
との接続時に別の認証設定を使用するルールを指定できます。認証コンテキストには、接続の確立時の選択方法を定義するルールや認証設定が含まれます。認証コンテキストは ssl-context
も参照でき、ルールとの照合も可能です。
接続の確立時にセキュリティー情報を使用するクライアントを作成するには、以下を実行します。
- 1 つ以上の認証設定を作成します。
- ルールと認証設定のペアを作成して認証コンテキストを作成します。
- 接続を確立する runnable を作成します。
- 認証コンテキストを使用して runnable を実行します。
接続の確立時に、Elytron クライアントは認証コンテキストが提供するルールセットを使用して、認証時に使用する適切な認証設定を特定します。
クライアント接続の確立時に、以下のいずれかの方法でセキュリティー情報を使用できます。
Elytron クライアントを使用して EJB 呼び出しを行う場合には、javax.naming.InitialContext
の Context.SECURITY_PRINCIPAL
設定など、ハードコーディングされたプログラムによる認証情報が Elytron クライアント設定よりも優先されます。
4.2.1. 設定ファイルのアプローチ
設定ファイルのアプローチでは、認証設定、認証コンテキスト、および一致ルールを含めて XML ファイルを作成する必要があります。
例: custom-config.xml
<configuration> <authentication-client xmlns="urn:elytron:client:1.2"> <authentication-rules> <rule use-configuration="monitor"> <match-host name="127.0.0.1" /> </rule> <rule use-configuration="administrator"> <match-host name="localhost" /> </rule> </authentication-rules> <authentication-configurations> <configuration name="monitor"> <sasl-mechanism-selector selector="DIGEST-MD5" /> <providers> <use-service-loader /> </providers> <set-user-name name="monitor" /> <credentials> <clear-password password="password1!" /> </credentials> <set-mechanism-realm name="ManagementRealm" /> </configuration> <configuration name="administrator"> <sasl-mechanism-selector selector="DIGEST-MD5" /> <providers> <use-service-loader /> </providers> <set-user-name name="administrator" /> <credentials> <clear-password password="password1!" /> </credentials> <set-mechanism-realm name="ManagementRealm" /> </configuration> </authentication-configurations> </authentication-client> </configuration>
次に、クライアントの実行時にシステムプロパティーを設定すると、クライアントのコードでそのファイルを参照できます。
$ java -Dwildfly.config.url=/path/to/custom-config.xml ...
プログラムによるアプローチ を使用する場合には、wildfly.config.url
システムプロパティーが設定されていても、指定した設定ファイルを上書きします。
ルールの作成時に hostname
、port
、protocol
または user-name
などのさまざまなパラメーターと合致するものを検索できます。MatchRule
のオプションの完全リストは、Java ドキュメントにあります。ルールは、設定順に評価されます。
ルールに一致設定が含まれていない場合は、ルール全体が一致し、認証設定が選択されます。複数の一致設定をルールに追加する場合は、そのルールすべてが合致しない限り、認証設定は選択されません。
表4.1 共通ルール
属性 | 説明 |
---|---|
match-local-security-domain |
照合するローカルのセキュリティードメインを指定する |
match-host |
照合するホスト名を指定する |
match-no-user | ユーザーのない URI に対して照合します。 |
match-path |
照合するパスを指定する |
match-port |
照合するポートを指定する |
match-protocol |
照合するプロトコルを指定する |
match-urn |
照合する URN を指定する |
match-user |
照合する |
wildfly-config.xml
ファイルの例は、Example wildfly-config.xml
を参照してください。wildfly-config.xml
ファイルの設定方法に関する詳細は、JBoss EAP開発ガイドの wildfly-config.xml
ファイルを使用したクライアント設定 を参照してください。
4.2.2. プログラムによるアプローチ
プログラムによるアプローチでは、クライアントのコード内の全 Elytron クライアント設定を行います。
//create your authentication configuration AuthenticationConfiguration adminConfig = AuthenticationConfiguration.empty() .useProviders(() -> new Provider[] { new WildFlyElytronProvider() }) .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5")) .useRealm("ManagementRealm") .useName("administrator") .usePassword("password1!"); //create your authentication context AuthenticationContext context = AuthenticationContext.empty(); context = context.with(MatchRule.ALL.matchHost("127.0.0.1"), adminConfig); //create your runnable for establishing a connection Runnable runnable = new Runnable() { public void run() { try { //Establish your connection and do some work } catch (Exception e) { e.printStackTrace(); } } }; //use your authentication context to run your client context.run(runnable);
設定の詳細を AuthenticationConfiguration
および AuthenticationContext
に追加すると、各メソッド呼び出しはそのオブジェクトの新規インスタンスを返します。たとえば、別のホスト名で接続する場合に別個の設定が必要な場合は、以下を行うことができます。
//create your authentication configuration AuthenticationConfiguration commonConfig = AuthenticationConfiguration.empty() .useProviders(() -> new Provider[] { new WildFlyElytronProvider() }) .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5")) .useRealm("ManagementRealm"); AuthenticationConfiguration administrator = commonConfig .useName("administrator") .usePassword("password1!"); AuthenticationConfiguration monitor = commonConfig .useName("monitor") .usePassword("password1!"); //create your authentication context AuthenticationContext context = AuthenticationContext.empty(); context = context.with(MatchRule.ALL.matchHost("127.0.0.1"), administrator); context = context.with(MatchRule.ALL.matchHost("localhost"), monitor);
表4.2 共通ルール
ルール | 説明 |
---|---|
matchLocalSecurityDomain(String name) |
これは、設定ファイルのアプローチの |
matchNoUser() |
これは、設定ファイルのアプローチの |
matchPath(String pathSpec) |
これは、設定ファイルのアプローチの |
matchPort(int port) |
これは、設定ファイルのアプローチの |
matchProtocol(String protoName) |
これは、設定ファイルのアプローチの |
matchPurpose(String purpose) | このルールと同じ新しいルールを作成しますが、指定の目的名も合わせて照合します。 |
matchUrnName(String name) |
これは、設定ファイルのアプローチの |
matchUser(String userSpec) |
これは、設定ファイルのアプローチの |
また、空白の認証設定で開始せずに、captureCurrent()
を使用して現在設定済みの認証設定で開始できます。
//create your authentication configuration AuthenticationConfiguration commonConfig = AuthenticationConfiguration.captureCurrent();
captureCurrent()
を使用すると、以前に設定した認証コンテキストを取得し、そのコンテキストを新しい基本設定として使用します。認証コンテキストは、run()
を呼び出してコンテキストをアクティブにすると確立されます。captureCurrent()
を呼び出し、アクティブなコンテキストがない場合に、デフォルトの認証があれば、それを使用します。詳細は、以下のセクションを参照してください。
AuthenticationConfiguration.empty()
は、設定を構築するためのベースとしてだけ使用し、単独で使用すべきではありません。これは、JVM 全体で登録されたプロバイダーを使用し、匿名認証を有効にする設定を提供します。
AuthenticationConfiguration.empty()
設定でプロバイダーを指定する場合、カスタム一覧を指定できますが、ほとんどのユーザーは WildFlyElytronProvider()
プロバイダーを使用する必要があります。
認証コンテキストを作成する場合は context.with(…)
を使用することで、現在のコンテキストのルールと認証設定を、指定のルールと認証設定とマージさせる新しいコンテキストが作成されます。指定されるルールおよび認証設定は、現在のコンテキストのルールおよび認証設定の後に表示されます。
4.2.3. デフォルト設定アプローチ
デフォルト設定アプローチは、Elytron クライアントが指定する設定に完全に依存します。
//create your runnable for establishing a connection Runnable runnable = new Runnable() { public void run() { try { //Establish your connection and do some work } catch (Exception e) { e.printStackTrace(); } } }; // run runnable directly runnable.run();
Elytron クライアントはファイルシステムの wildfly-config.xml
ファイルを自動検出して、デフォルト設定を使用します。以下の場所を探します。
-
クライアントコード外に設定された
wildfly.config.url
システムプロパティーが指定する場所。 - クラスパスのルートディレクトリー。
-
クラスパスの
META-INF
ディレクトリー。 - 現在のユーザーのホームディレクトリー。
- 現在の作業ディレクトリー。
以下の例は、クライアントの wildfly-config.xml
ファイルの基本設定として使用できます。
基本的な wildfly-config.xml
<configuration> <authentication-client xmlns="urn:elytron:client:1.2"> <authentication-rules> <rule use-configuration="default" /> </authentication-rules> <authentication-configurations> <configuration name="default"> <sasl-mechanism-selector selector="#ALL" /> <set-mechanism-properties> <property key="wildfly.sasl.local-user.quiet-auth" value="true" /> </set-mechanism-properties> <providers> <use-service-loader/> </providers> </configuration> </authentication-configurations> </authentication-client> </configuration>
ANONYMOUS
メカニズムでは、匿名ユーザー以外
のユーザーとしての認証はサポートしていません。つまり、set-authorization-name
は、Elytron クライアントの設定ファイルの set-anonymous
と合わせて使用できません。代わりに、set-authorization-name
を設定する場合には、承認されたアイデンティティーに set-user-name
も指定する必要があります。
4.2.4. JBoss EAP にデプロイされたクライアントでの Elytron クライアントの使用
JBoss EAP にデプロイされたクライアントは Elytron クライアントを使用することもできます。AuthenticationContext
は解析され、JBoss EAP 設定の default-authentication-context
設定をもとに自動的に作成されます。default-authentication-context
が設定されていないものの、デプロイメントに wildfly-config.xml
ファイルが含まれる場合や、wildfly.config.url
システムプロパティーを使用して設定している場合には、AuthenticationContext
は自動的に解析され、このファイルをもとに作成されます。
例: デフォルトの認証コンテキストの設定
/subsystem=elytron/authentication-context=AUTH_CONTEXT:add /subsystem=elytron:write-attribute(name=default-authentication-context,value=AUTH_CONTEXT)
デプロイメント外で設定ファイルを読み込むには、parseAuthenticationClientConfiguration (URI)
メソッド を使用します。このメソッドは AuthenticationContext
を返すので、programmatic approach を使用してクライアントのコードで使用できます。
さらに、クライアントは elytron
サブシステムが指定するクライアント設定をもとに AuthenticationContext
を自動的に解析し、作成します。elytron
サブシステムのクライアント設定は、認証ストアなど、elytron
サブシステムで定義されている他のコンポーネントも活用できます。デプロイメントと elytron
サブシステムの両方でクライアントの設定が指定されている場合には、elytron
サブシステムの設定が使用されます。
authentication-context
が elytron
サブシステムのデフォルトとして設定されている場合のみ、elytron
サブシステムの AuthenticationContext
を使用できます。
4.2.5. wildfly-config.xml ファイルを使用した JMX クライアントの設定
JBoss EAP 7.1 以降で、JConsole などの JMX クライアントは、wildfly-config.xml
ファイルを使用して設定できます。JMX クライアントの起動時に -Dwildfly.config.url
システムプロパティーを使用して、設定ファイルへのファイルパスを指定します。
-Dwildfly.config.url=path/to/wildfly-config.xml
JConsole を使用する場合には、-Dwildfly.config.url
システムプロパティーの前に -J
を付ける必要があります。以下に例を示します。
-J-Dwildfly.config.url=path/to/wildfly-config.xml
詳細は、JBoss EAP開発ガイドの wildfly-config.xml
ファイルを使用したクライアント設定 を参照してください。
4.2.6. ElytronAuthenticator を使用したアイデンティティーの伝播
Java 8 では認証情報で既知の制限があるため、JBoss EAP での ElytronAuthenticator
の使用はサポートされておらず、推奨していません。このクラスを使用してアイデンティティーを伝播する場合は、以下の制限に注意してください。
- Java 8 設計の制限により、保護されたサーブレットへの呼び出しではセキュリティーアイデンティティーは伝播されません。
-
EJB などのサーバーで
ElytronAuthenticator
を使用しないでください。 - 認証情報のキャッシュは、スタンドアロンクライアントの JVM で使用する場合に影響を与える可能性があります。
JBoss EAP 7.1 では、現在のセキュリティーコンテキストを使用して認証を実行する ElytronAuthenticator
クラスが導入されました。org.wildfly.security.auth.util.ElytronAuthenticator クラスは java.net.Authenticator の実装です。
-
このクラスには、新規インスタンスを構築するコンストラクター (
ElytronAuthenticator()
) が 1 つ含まれています。 -
また、
PasswordAuthentication
を返すメソッド (getPasswordAuthentication()
) が 1 つ含まれています。
以下の例は、ElytronAuthenticator
クラスを作成して使用し、アイデンティティーをサーバーに伝播するクライアントコードです。
例: ElytronAuthenticator を使用したコード
// Create the authentication configuration
AuthenticationConfiguration httpConfig = AuthenticationConfiguration.empty().useName("bob");
// Create the authentication context
AuthenticationContext context = AuthenticationContext.captureCurrent().with(MatchRule.ALL, httpConfig.usePassword(createPassword(httpConfig, "secret")));
String response = context.run((PrivilegedExceptionAction<String>) () -> {
Authenticator.setDefault(new ElytronAuthenticator());
HttpURLConnection connection = HttpURLConnection.class.cast(new URL("http://localhost:" + SERVER_PORT).openConnection());
try (InputStream inputStream = connection.getInputStream()) {
return new BufferedReader(new InputStreamReader(inputStream)).lines().findFirst().orElse(null);
}
});