3.6. SAML を使用したアプリケーションの保護
Security Assertion Markup Language (SAML) は、2 者間での認証および認可情報の交換を可能にするデータ形式およびプロトコルです。通常、この 2 者には、アイデンティティプロバイダーとサービスプロバイダーが含まれます。この情報は、アサーションを含む SAML トークンの形式をとります。アイデンティティープロバイダーは、この SAML トークンをサブジェクトに発行して、サブジェクトがサービスプロバイダーで認証できるようにします。サブジェクトは複数のサービスプロバイダーで SAML トークンを再利用できるため、SAML v2 によるブラウザーベースのシングルサインオンが可能になります。
Keycloak SAML アダプター機能パックが提供する Galleon レイヤーを使用すると、Web アプリケーションを保護できます。
Keycloak SAML アダプター機能パックについては、SAML を使用してアプリケーションを保護するための Keycloak SAML アダプター機能パック を参照してください。
3.6.1. SAML を使用してアプリケーションを保護するための Keycloak SAML アダプター機能パック
Keycloak SAML アダプター Galleon パックは、keycloak-saml
レイヤーを含む Galleon 機能パックです。この機能パックの keycloak-saml
レイヤーを使用して、必要なモジュールと設定を JBoss EAP にインストールします。これらのモジュールと設定は、SAML の使用時にシングルサインオン (SSO) のアイデンティティプロバイダーとして Red Hat build of Keycloak を使用する場合に必要です。source-to-image (S2I) に keycloak-saml
SAML アダプター Galleon レイヤーを使用する場合は、必要に応じて、Red Hat build of Keycloak などのアイデンティティーサービスプロバイダー (IDP) への自動登録を可能にする SAML クライアント機能を使用できます。
3.6.2. Red Hat build of Keycloak を OpenShift の SAML プロバイダーとして設定する
Red Hat build of Keycloak は、シングルサインオン (SSO) を使用して Web アプリケーションを保護するためのアイデンティティーおよびアクセス管理プロバイダーです。OAuth 2.0 の拡張機能である OpenID Connect と、SAML をサポートします。
次の手順は、SAML を使用してアプリケーションを保護するために必要な重要な手順を示しています。詳細は、Red Hat build of Keycloak のドキュメント を参照してください。
前提条件
- Red Hat build of Keycloak への管理者アクセス権を持っている。
- Red Hat build of Keycloak が実行中である。詳細は、Red Hat build of Keycloak Operator を参照してください。
-
oc login
コマンドを使用して OpenShift にログインしている。
手順
- シングルサインオンレルム、ユーザー、およびロールを作成します。
Java
keytool
コマンドを使用してキーと証明書を生成します。keytool -genkeypair -alias saml-app -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -storepass password -dname "CN=saml-basic-auth,OU=EAP SAML Client,O=Red Hat EAP QE,L=MB,S=Milan,C=IT" -ext ku:c=dig,keyEncipherment -validity 365
キーストアを Java KeyStore (JKS) 形式でインポートします。
keytool -importkeystore -deststorepass password -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass password
OpenShift でキーストアのシークレットを作成します。
$ oc create secret generic saml-app-secret --from-file=keystore.jks=./keystore.jks --type=opaque
この手順は、自動 SAML クライアント登録機能を使用する場合にのみ必要です。JBoss EAP が新しい SAML クライアントを client-admin
ユーザーとして Red Hat build of Keycloak に登録する場合、JBoss EAP は新しい SAML クライアントの証明書を Red Hat build of Keycloak のクライアント設定に保存する必要があります。これにより、JBoss EAP は秘密鍵を保持しながら、公開証明書のみを Red Hat build of Keycloak に保存できるようになり、Red Hat build of Keycloak との通信用の認証済みクライアントが確立されます。
3.6.3. SAML で保護されたアプリケーションの作成
Security Assertion Markup Language (SAML) を使用すると、Web アプリケーションのセキュリティーを強化できます。SAML は、シングルサインオン (SSO) 機能とともに効果的なユーザー認証および認可を提供するため、Web アプリケーションを強化するときには頼りになる選択肢となります。
前提条件
- 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-pack> <location>org.keycloak:keycloak-saml-adapter-galleon-pack</location> </feature-pack> </feature-packs> <layers> <layer>cloud-server</layer> <layer>keycloak-saml</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.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; /** * 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
ファイルのディレクトリー構造を作成します。mkdir -p src/main/webapp/WEB-INF cd src/main/webapp/WEB-INF
アプリケーションの
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>user</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>KEYCLOAK-SAML</auth-method> </login-config> <security-role> <role-name>user</role-name> </security-role> </web-app>
この例では、
user
ロールを持つユーザーのみがアプリケーションにアクセスできます。
検証
アプリケーションを作成したら、リモート Git リポジトリーにコミットします。
-
Git リポジトリーを作成します (
https://github.com/your-username/simple-webapp-example
など)。リモートリポジトリーと Git の詳細は、Getting started with Git - About remote repositories を参照してください。 アプリケーションのルートフォルダーから、次の Git コマンドを実行します。
git init -b main git add pom.xml src git commit -m "First commit" git remote add origin git@github.com:your-username/simple-webapp-example.git git remote -v git push -u origin main
この手順により、アプリケーションがリモートリポジトリーにコミットされ、オンラインでアクセスできるようになります。
3.6.4. OpenShift 上での SAML で保護されたアプリケーションのビルドとデプロイ
JBoss EAP および Single Sign-On (SSO) Galleon レイヤーを使用して、SAML で保護されたアプリケーションを OpenShift 上でビルドおよびデプロイできます。
前提条件
- Helm がインストールされている。詳細は、Installing Helm を参照してください。
- SAML アプリケーションプロジェクトを作成し、Git リポジトリーでアクセスできるようにしている。
管理 CLI で次のコマンドを入力して、JBoss EAP Helm チャートのリポジトリーをインストールしている。
$ helm repo add jboss-eap https://jbossas.github.io/eap-charts/
手順
- アプリケーションコードを Git リポジトリーにデプロイします。
必要な環境変数を含む OpenShift シークレットを作成します。
apiVersion: v1 kind: Secret metadata: name: saml-secret type: Opaque stringData: SSO_REALM: "saml-basic-auth" SSO_USERNAME: "client-admin" SSO_PASSWORD: "client-admin" SSO_SAML_CERTIFICATE_NAME: "saml-app" SSO_SAML_KEYSTORE: "keystore.jks" SSO_SAML_KEYSTORE_PASSWORD: "password" SSO_SAML_KEYSTORE_DIR: "/etc/sso-saml-secret-volume" SSO_SAML_LOGOUT_PAGE: "/simple-webapp-example" SSO_DISABLE_SSL_CERTIFICATE_VALIDATION: "true"
-
指定の YAML コンテンツを
saml-secret.yaml
などのファイルに保存します。 次のコマンドを使用して、保存した YAML ファイルを適用します。
oc apply -f saml-secret.yaml
次の設定を含む
helm.yaml
という名前のファイルを作成します。build: uri: [WEB ADDRESS TO YOUR GIT REPOSITORY] deploy: volumes: - name: saml-keystore-volume secret: secretName: saml-app-secret volumeMounts: - name: saml-keystore-volume mountPath: /etc/sso-saml-secret-volume readOnly: true envFrom: - secretRef: name: saml-secret
注記Web アドレスは HTTP 形式で指定してください (
http://www.redhat.com
など)。Maven ミラーを使用している場合は、次のように Web アドレスを指定します。build: uri: [WEB ADDRESS TO YOUR GIT REPOSITORY] env: - name: "MAVEN_MIRROR_URL" value: "http://..."
JBoss EAP Helm チャートを使用してサンプルアプリケーションをデプロイします。
$ helm install saml-app -f helm.yaml jboss-eap/eap8
環境変数を
saml-secret.yaml
ファイルに追加して、Keycloak サーバー URL とアプリケーションルートを設定します。stringData: ... HOSTNAME_HTTPS: <saml-app application route> SSO_URL: https://<host of the Keycloak server>
<saml-app application root>
と<host of the Keycloak server>
は、適切な値に置き換えます。HOSTNAME_HTTPS
の値は、次の出力に対応します。echo $(oc get route saml-app --template='{{ .spec.host }}')
SSO_URL
の値は、次の出力に置き換えます。echo https://$(oc get route sso --template='{{ .spec.host }}')
注記このコマンドを使用できない場合は、
oc get routes
を使用して利用可能なルートをリストし、Red Hat build of Keycloak インスタンスへのルートを選択してください。-
oc apply -f saml-secret.yaml
を使用してシークレットを更新します。
検証
OpenShift で新しい環境変数が使用されるように、アプリケーションを再度デプロイします。
$ oc rollout restart deploy saml-app
ブラウザーで、アプリケーションの URL に移動します。たとえば、
https://<saml-app route>/simple-webapp-example
です。Red Hat build of Keycloak のログインページにリダイレクトされます。
Web アドレスを取得するために、次のコマンドを使用して保護されたサーブレットにアクセスします。
echo https://$(oc get route saml-app --template='{{ .spec.host }}')/simple-webapp-example/secured
次の認証情報でログインします。
username: demo password: demo
プリンシパル ID を含むページが表示されます。
これで、アプリケーションが SAML を使用して保護されました。
3.6.5. SSO レルム、ユーザー、およびロールの作成
Red Hat build of Keycloak 環境では、シングルサインオン (SSO) レルムの設定、ユーザーロールの定義、アクセス制御の管理を実行できます。これらの操作により、セキュリティーの強化、ユーザーアクセス管理の簡略化、認証エクスペリエンスの効率化を実現できます。これは、SSO 設定を最適化し、ユーザー認証プロセスを改善するために不可欠です。
前提条件
- Red Hat build of Keycloak への管理者アクセス権を持っている。
- Red Hat build of Keycloak が実行中である。
手順
-
URL
https://<SSO route>/
を使用して Red Hat build of Keycloak 管理コンソールにログインします。 Red Hat build of Keycloak でレルムを作成します (
saml-basic-auth
など)。その後、このレルムを使用して、必要なユーザー、ロール、およびクライアントを作成できます。詳細は、レルムの作成 を参照してください。
saml-basic-auth
レルム内にロールを作成します。たとえば、user
などです。詳細は、レルムロールの作成 を参照してください。
ユーザーを作成します。たとえば、
demo
などです。詳細は、ユーザーの作成 を参照してください。
ユーザーのパスワードを作成します。たとえば、
demo
などです。パスワードが一時的なものでないことを確認してください。詳細は、ユーザーのパスワードの設定 を参照してください。
ログインアクセス用の
user
ロールをdemo
ユーザーに割り当てます。詳細は、ロールマッピングの割り当て を参照してください。
ユーザーを作成します。たとえば、
client-admin
などです。JBoss EAP サーバーの起動時に Keycloak サーバーに SAML クライアントを作成するには、
client-admin
ユーザーを使用できます。このユーザーには追加の権限が必要です。詳細は、ユーザーの作成 を参照してください。ユーザーのパスワードを作成します。たとえば、
client-admin
などです。パスワードが一時的なものでないことを確認してください。詳細は、ユーザーのパスワードの設定 を参照してください。
-
Client Roles
ドロップダウンリストからrealm-management
を選択します。 create-client
、manage-clients
、およびmanage-realm
ロールをclient-admin
ユーザーに割り当てます。詳細は、ロールマッピングの割り当て を参照してください。
3.6.6. SAML サブシステムを設定するための環境変数
次の変数を理解して使用することで、環境内での Keycloak サーバーの統合を最適化できます。これにより、アプリケーション用にシームレスでセキュアな Keycloak セットアップを実現できます。
環境変数 | 説明 | 必須 |
---|---|---|
| デプロイメント名から導出されるクライアント名の接頭辞として使用されます。 | オプション |
|
HTTP OpenShift ルートのカスタムの | オプション |
|
HTTPS OpenShift ルートのカスタムの | オプション |
|
| オプション |
|
Keycloak レルムと対話し、クライアントを作成および登録する権限を持つユーザーのパスワード。たとえば、 | True |
|
アプリケーションクライアントを関連付けるための SSO レルム。たとえば、 | オプション |
|
SAML クライアントキーストア内の秘密鍵と証明書のエイリアス。たとえば、 | True |
|
キーストアファイルの名前。たとえば、 | True |
|
クライアントキーストアを含むディレクトリー。たとえば、 | True |
|
キーストアパスワードたとえば、 | True |
|
ログアウトページ。たとえば、 | True |
|
署名を検証する場合は | オプション |
|
undertow および | オプション |
| サーバー証明書を含むトラストストアのファイル名。 | オプション |
| トラストストア内の証明書のエイリアス。 | オプション |
| トラストストアを含むディレクトリー。 | オプション |
|
トラストストアと証明書のパスワード。たとえば、 | オプション |
|
SSO サーバーの URL。たとえば、 | True |
|
Keycloak レルムと対話し、クライアントを作成および登録する権限を持つユーザーのユーザー名。たとえば、 | True |
3.6.7. JBoss EAP サーバーのルート検出
JBoss EAP サーバーのルート検出機能を使用すると、サーバーのパフォーマンスを最適化し、指定した namespace でのルート設定を簡略化できます。この機能は、特に HOSTNAME_HTTPS
変数が指定されていない場合に、サーバーの効率を向上させ、よりスムーズな運用エクスペリエンスを実現する上で重要です。
HOSTNAME_HTTPS
変数が設定されていない場合、JBoss EAP サーバーは自動的にルート検出を試みます。ルート検出を有効にするには、必要な権限を作成する必要があります。
oc create role routeview --verb=list --resource=route -n YOUR_NAME_SPACE oc policy add-role-to-user routeview system:serviceaccount:YOUR_NAME_SPACE:default --role-namespace=YOUR_NAME_SPACE -n YOUR_NAME_SPACE