3.5. OpenID Connect を使用して OpenShift 上の JBoss EAP アプリケーションを保護する
JBoss EAP ネイティブ OpenID Connect (OIDC) クライアントを使用して、外部 OpenID プロバイダーを使用して認証を委任します。OIDC は、JBoss EAP などのクライアントが OpenID プロバイダーによって実行される認証に基づいてユーザーのアイデンティティーを検証できるようにするアイデンティティーレイヤーです。
elytron-oidc-client
サブシステムと elytron-oidc-client
Galleon レイヤーは、OpenID プロバイダーに接続するために JBoss EAP でネイティブ OIDC クライアントを提供します。JBoss EAP は、OpenID プロバイダーの設定に基づいて、アプリケーションの仮想セキュリティードメインを自動的に作成します。
elytron-oidc-client
サブシステムは、3 つの異なる方法で設定できます。
-
oidc.json
をデプロイメントに追加します。 -
CLI スクリプトを実行して
elytron-oidc-client
サブシステムを設定します。 -
OpenShift での JBoss EAP サーバーの起動時に
elytron-oidc-client
サブシステムを設定するための環境変数の定義。
この手順では、環境変数を使用して elytron-oidc-client
サブシステムを設定し、OIDC でアプリケーションを保護する方法について説明します。
3.5.1. JBoss EAP での OpenID Connect 設定
OpenID プロバイダーを使用してアプリケーションを保護する場合、セキュリティードメインリソースをローカルで設定する必要はありません。elytron-oidc-client
サブシステムは、OpenID プロバイダーと接続するための JBoss EAP のネイティブ OpenID Connect (OIDC) クライアントを提供します。JBoss EAP は、OpenID プロバイダーの設定に基づいて、アプリケーションの仮想セキュリティードメインを自動的に作成します。
OIDC クライアントは Red Hat build of Keycloak で使用してください。JSON Web トークン (JWT) であるアクセストークンを使用するように設定でき、RS256、RS384、RS512、ES256、ES384、または ES512 署名アルゴリズムを使用するように設定できる場合は、他の OpenID プロバイダーを使用できます。
OIDC の使用を有効にするには、elytron-oidc-client
サブシステムまたはアプリケーション自体を設定できます。JBoss EAP は、次のように OIDC 認証をアクティブにします。
-
アプリケーションを JBoss EAP にデプロイすると、
elytron-oidc-client
サブシステムがデプロイメントをスキャンして、OIDC 認証メカニズムが必要かどうかを検出します。 -
サブシステムが
elytron-oidc-client
サブシステムまたはアプリケーションデプロイメント記述子のいずれかでデプロイメントの OIDC 設定を検出した場合、JBoss EAP はアプリケーションの OIDC 認証メカニズムを有効にします。 -
サブシステムが両方の場所で OIDC 設定を検出した場合、
elytron-oidc-client
サブシステムsecure-deployment
属性の設定が、アプリケーションデプロイメント記述子の設定よりも優先されます。
3.5.2. OpenID Connect で保護されたアプリケーションの作成
web-application を作成するには、必要な依存関係とディレクトリー構造で Maven プロジェクトを作成します。ログインユーザーのプリンシパルおよび属性から取得したユーザー名を返すサーブレットを含む Web アプリケーションを作成します。ログインしているユーザーがないと、サーブレットは「NO AUTHENTICATED USER」のテキストを返します。
前提条件
- Maven がインストールされている。詳細は、Downloading Apache Maven を参照してください。
手順
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-webapp \ -DinteractiveMode=false
例:
$ mvn archetype:generate \ -DgroupId=com.example.app \ -DartifactId=simple-webapp-example \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false
アプリケーションのルートディレクトリーに移動します。
構文
$ cd <name-of-your-application>
例:
$ cd simple-webapp-example
生成された
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>com.example.app</groupId> <artifactId>simple-webapp-example</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>simple-webapp-example Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <version.maven.war.plugin>3.3.2</version.maven.war.plugin> <version.eap.plugin>1.0.0.Final-redhat-00014</version.eap.plugin> <version.server>8.0.0.GA-redhat-00009</version.server> <version.bom.ee>${version.server}</version.bom.ee> </properties> <repositories> <repository> <id>jboss</id> <url>https://maven.repository.redhat.com/ga/</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>jboss</id> <url>https://maven.repository.redhat.com/ga/</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> <dependencyManagement> <dependencies> <dependency> <groupId>org.jboss.bom</groupId> <artifactId>jboss-eap-ee-with-tools</artifactId> <version>${version.bom.ee}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.wildfly.security</groupId> <artifactId>wildfly-elytron-auth-server</artifactId> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>${version.maven.war.plugin}</version> </plugin> <plugin> <groupId>org.jboss.eap.plugins</groupId> <artifactId>eap-maven-plugin</artifactId> <version>${version.eap.plugin}</version> <configuration> <channels> <channel> <manifest> <groupId>org.jboss.eap.channels</groupId> <artifactId>eap-8.0</artifactId> </manifest> </channel> </channels> <feature-packs> <feature-pack> <location>org.jboss.eap:wildfly-ee-galleon-pack</location> </feature-pack> <feature-pack> <location>org.jboss.eap.cloud:eap-cloud-galleon-pack</location> </feature-pack> </feature-packs> <layers> <layer>cloud-server</layer> <layer>elytron-oidc-client</layer> </layers> <galleon-options> <jboss-fork-embedded>true</jboss-fork-embedded> </galleon-options> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
注記-
<version.eap.plugin>1.0.0.Final-redhat-00014</version.eap.plugin>
は、JBoss EAP Maven プラグインのバージョンの例です。JBoss EAP Maven プラグインのリリースの詳細は、Red Hat Maven リポジトリー (https://maven.repository.redhat.com/earlyaccess/all/org/jboss/eap/plugins/eap-maven-plugin/) を参照してください。
-
Java ファイルを保存するディレクトリーを作成します。
構文
$ mkdir -p src/main/java/<path_based_on_artifactID>
例:
$ mkdir -p src/main/java/com/example/app
新しいディレクトリーに移動します。
構文
$ cd src/main/java/<path_based_on_artifactID>
例:
$ cd src/main/java/com/example/app
以下の内容で
SecuredServlet.java
ファイルを作成します。package com.example.app; import java.io.IOException; import java.io.PrintWriter; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.authz.Attributes; import org.wildfly.security.authz.Attributes.Entry; /** * A simple secured HTTP servlet. It returns the user name and * attributes obtained from the logged-in user's Principal. If * there is no logged-in user, it returns the text * "NO AUTHENTICATED USER". */ @WebServlet("/secured") public class SecuredServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (PrintWriter writer = resp.getWriter()) { Principal user = req.getUserPrincipal(); SecurityIdentity identity = SecurityDomain.getCurrent().getCurrentSecurityIdentity(); Attributes identityAttributes = identity.getAttributes(); Set <String> keys = identityAttributes.keySet(); String attributes = "<ul>"; for (String attr : keys) { attributes += "<li> " + attr + " : " + identityAttributes.get(attr).toString() + "</li>"; } attributes+="</ul>"; writer.println("<html>"); writer.println(" <head><title>Secured Servlet</title></head>"); writer.println(" <body>"); writer.println(" <h1>Secured Servlet</h1>"); writer.println(" <p>"); writer.print(" Current Principal '"); writer.print(user != null ? user.getName() : "NO AUTHENTICATED USER"); writer.print("'"); writer.print(user != null ? "\n" + attributes : ""); writer.println(" </p>"); writer.println(" </body>"); writer.println("</html>"); } } }
アプリケーションの
web.xml
を設定して、アプリケーションリソースを保護します。例:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd" metadata-complete="false"> <security-constraint> <web-resource-collection> <web-resource-name>secured</web-resource-name> <url-pattern>/secured</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Users</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>OIDC</auth-method> </login-config> <security-role> <role-name>*</role-name> </security-role> </web-app>
この例では、
Users
ロールを持つユーザーのみがアプリケーションにアクセスできます。
3.5.3. アプリケーションを OpenShift にデプロイする
JBoss EAP アプリケーション開発者は、OpenID Connect サブシステムを使用する OpenShift にアプリケーションをデプロイし、そのアプリケーションを Red Hat build of Keycloak サーバーと統合できます。以下の手順に従って、アプリケーションをデプロイします。
前提条件
以下の設定で、OpenShift で Red Hat build of Keycloak サーバーを設定している。詳細は、Red Hat build of Keycloak Operator を参照してください。
- JBossEAP というレルムを作成します。
- demo というユーザーを作成します。
- demo というユーザーのパスワードを設定します。Temporary を OFF に切り替えて、Set Password をクリックします。確認プロンプトで、Set password をクリックします。
- Users というロールを作成します。
- ロール Users をユーザー demo に割り当てます。
- Client Roles フィールドで、JBoss EAP 用に設定した realm-management を選択します。
- ロール create-client をクライアント realm-management に割り当てます。
手順
- アプリケーションコードを Git リポジトリーにデプロイします。
OIDC 設定を含むシークレットを作成します。
次の内容を使用して、
oidc-secret.yaml
という名前のファイルを作成します。apiVersion: v1 kind: Secret metadata: name: oidc-secret type: Opaque stringData: OIDC_PROVIDER_NAME: rh-sso OIDC_USER_NAME: demo OIDC_USER_PASSWORD: demo OIDC_SECURE_DEPLOYMENT_SECRET: mysecret
以下のコマンドを実行してシークレットを作成します。
$ oc apply -f oidc-secret.yaml
次の内容を使用して、
helm.yaml
という名前のファイルを作成します。build: uri: [URL TO YOUR GIT REPOSITORY] deploy: envFrom: - secretRef: name: oidc-secret
JBoss EAP Helm チャートを使用してサンプルアプリケーションをデプロイします。
$ helm install eap-oidc-test-app -f helm.yaml jboss-eap/eap8
環境変数を
oidc-secret.yaml
ファイルに追加して、OIDC プロバイダーの URL とアプリケーションのホスト名を設定します。yaml stringData: ... OIDC_HOSTNAME_HTTPS: <host of the application> OIDC_PROVIDER_URL: https://<host of the SSO provider>/realms/JBossEAP
OIDC_HOSTNAME_HTTPS
の値は、次の出力に対応します。echo $(oc get route eap-oidc-test-app --template='{{ .spec.host }}')
OIDC_PROVIDER_URL
の値は、次の出力に対応します。echo https://$(oc get route sso --template='{{ .spec.host }}')/realms/JBossEAP
OIDC_HOSTNAME_HTTP(S)
が設定されていない場合は、ルート検出が試行されます。ルート検出を有効にするには、OpenShift ユーザーがroute
リソースを一覧表示できる必要があります。たとえば、routeview
ロールを作成してview
ユーザーに関連付けるには、次のoc
コマンドを使用します。$ oc create role <role-name> --verb=list --resource=route $ oc adm policy add-role-to-user <role-name> <user-name> --role-namespace=<your namespace>
-
oc apply -f oidc-secret.yaml
でシークレットを更新します。 アプリケーションを再度デプロイして、OpenShift が新しい環境変数を使用するようにします。
$ oc rollout restart deploy eap-oidc-test-app
検証
ブラウザーで
https://<eap-oidc-test-app route>/
に移動します。Red Hat build of Keycloak のログインページにリダイレクトされます。
- 保護されたサーブレットにアクセスします。
次の認証情報でログインします。
username: demo password: demo
Principal ID を含むページが表示されます。
3.5.4. 環境変数ベースの設定
これらの環境変数を使用して、OpenShift イメージで JBoss EAP OIDC サポートを設定します。
環境変数 | 従来の SSO 環境変数 | 説明 | 必須 | デフォルト値 |
---|---|---|---|---|
OIDC_PROVIDER_NAME |
なし。 |
OIDC_PROVIDER_NAME 変数を使用する場合は、 | はい | |
OIDC_PROVIDER_URL |
| プロバイダーの URL。 | はい | |
OIDC_USER_NAME | SSO_USERNAME | 動的クライアント登録では、トークンを受け取るためにユーザー名が必要です。 | はい | |
OIDC_USER_PASSWORD | SSO_PASSWORD | 動的クライアント登録では、トークンを受け取るためにユーザーパスワードが必要です。 | はい | |
OIDC_SECURE_DEPLOYMENT_SECRET | SSO_SECRET | これは、secure-deployment サブシステムと認証サーバークライアントの両方に認識されます。 | いいえ | |
OIDC_SECURE_DEPLOYMENT_PRINCIPAL_ATTRIBUTE | SSO_PRINCIPAL_ATTRIBUTE | プリンシパル名の値を設定します。 | いいえ |
典型的な値: preferred_username。 |
OIDC_SECURE_DEPLOYMENT_ENABLE_CORS | SSO_ENABLE_CORS | Single Sign-On アプリケーションの CORS を有効にします。 | いいえ |
デフォルトは |
OIDC_SECURE_DEPLOYMENT_BEARER_ONLY | SSO_BEARER_ONLY | ベアラートークンのみを受け入れ、ログ記録をサポートしないデプロイ。 | いいえ |
デフォルトは |
OIDC_PROVIDER_SSL_REQUIRED | NONE | デフォルトはプライベートアドレスやローカルアドレスなどの外部ですが、https はサポートしていません。 | いいえ | 外部 |
OIDC_PROVIDER_TRUSTSTORE | SSO_TRUSTSTORE |
レルム | いいえ | |
OIDC_PROVIDER_TRUSTSTORE_DIR | SSO_TRUSTSTORE_DIR |
レルム | いいえ | |
OIDC_PROVIDER_TRUSTSTORE_PASSWORD | SSO_TRUSTSTORE_PASSWORD |
レルム | いいえ | |
OIDC_PROVIDER_TRUSTSTORE_CERTIFICATE_ALIAS | SSO_TRUSTSTORE_CERTIFICATE_ALIAS |
レルム | いいえ | |
OIDC_DISABLE_SSL_CERTIFICATE_VALIDATION | SSO_DISABLE_SSL_CERTIFICATE_VALIDATION | 認証サーバーとやり取りしてクライアントを登録するときは、証明書の検証を無効にします。 | いいえ | |
OIDC_HOSTNAME_HTTP | HOSTNAME_HTTP | 安全でないルートに使用されるホスト名。 | いいえ | ルートが検出されます。 |
OIDC_HOSTNAME_HTTPS | HOSTNAME_HTTPS | 保護されたルートに使用されるホスト名。 | いいえ | 保護されたルートが検出されます。 |
NONE | SSO_PUBLIC_KEY | シングルサインオンレルムの公開鍵。このオプションは使用されません。公開鍵は OIDC サブシステムによって自動的に取得されます。 | いいえ | 設定すると、このオプションが無視されているという警告が表示されます。 |