検索

3.6. SAML を使用したアプリケーションの保護

download PDF

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 にログインしている。

手順

  1. シングルサインオンレルム、ユーザー、およびロールを作成します
  2. 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
  3. キーストアを Java KeyStore (JKS) 形式でインポートします。

    keytool -importkeystore -deststorepass password -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass password
  4. 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 アプリケーションを強化するときには頼りになる選択肢となります。

前提条件

手順

  1. 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

  2. アプリケーションのルートディレクトリーに移動します。

    構文

    $ cd <name-of-your-application>

    例:

    $ cd simple-webapp-example

  3. 生成された 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>
    注記
  4. Java ファイルを保存するディレクトリーを作成します。

    構文

    $ mkdir -p src/main/java/<path_based_on_artifactID>

    例:

    $ mkdir -p src/main/java/com/example/app

  5. 新しいディレクトリーに移動します。

    構文

    $ cd src/main/java/<path_based_on_artifactID>

    例:

    $ cd src/main/java/com/example/app

  6. 次の設定を含む 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>");
            }
        }
    
    }
  7. web.xml ファイルのディレクトリー構造を作成します。

    mkdir -p src/main/webapp/WEB-INF
    cd src/main/webapp/WEB-INF
  8. アプリケーションの 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 リポジトリーにコミットします。

  1. Git リポジトリーを作成します (https://github.com/your-username/simple-webapp-example など)。リモートリポジトリーと Git の詳細は、Getting started with Git - About remote repositories を参照してください。
  2. アプリケーションのルートフォルダーから、次の 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/

手順

  1. アプリケーションコードを Git リポジトリーにデプロイします。
  2. 必要な環境変数を含む 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"
  3. 指定の YAML コンテンツを saml-secret.yaml などのファイルに保存します。
  4. 次のコマンドを使用して、保存した YAML ファイルを適用します。

    oc apply -f saml-secret.yaml
  5. 次の設定を含む 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://..."
  6. JBoss EAP Helm チャートを使用してサンプルアプリケーションをデプロイします。

    $ helm install saml-app -f helm.yaml jboss-eap/eap8
  7. 環境変数を 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 インスタンスへのルートを選択してください。

  8. oc apply -f saml-secret.yaml を使用してシークレットを更新します。

検証

  1. OpenShift で新しい環境変数が使用されるように、アプリケーションを再度デプロイします。

    $ oc rollout restart deploy saml-app
  2. ブラウザーで、アプリケーションの URL に移動します。たとえば、https://<saml-app route>/simple-webapp-example です。

    Red Hat build of Keycloak のログインページにリダイレクトされます。

  3. Web アドレスを取得するために、次のコマンドを使用して保護されたサーブレットにアクセスします。

    echo https://$(oc get route saml-app --template='{{ .spec.host }}')/simple-webapp-example/secured
  4. 次の認証情報でログインします。

    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 が実行中である。

手順

  1. URL https://<SSO route>/ を使用して Red Hat build of Keycloak 管理コンソールにログインします。
  2. Red Hat build of Keycloak でレルムを作成します (saml-basic-auth など)。その後、このレルムを使用して、必要なユーザー、ロール、およびクライアントを作成できます。

    詳細は、レルムの作成 を参照してください。

  3. saml-basic-auth レルム内にロールを作成します。たとえば、user などです。

    詳細は、レルムロールの作成 を参照してください。

  4. ユーザーを作成します。たとえば、demo などです。

    詳細は、ユーザーの作成 を参照してください。

  5. ユーザーのパスワードを作成します。たとえば、demo などです。

    パスワードが一時的なものでないことを確認してください。詳細は、ユーザーのパスワードの設定 を参照してください。

  6. ログインアクセス用の user ロールを demo ユーザーに割り当てます。

    詳細は、ロールマッピングの割り当て を参照してください。

  7. ユーザーを作成します。たとえば、client-admin などです。

    JBoss EAP サーバーの起動時に Keycloak サーバーに SAML クライアントを作成するには、client-admin ユーザーを使用できます。このユーザーには追加の権限が必要です。詳細は、ユーザーの作成 を参照してください。

  8. ユーザーのパスワードを作成します。たとえば、client-admin などです。

    パスワードが一時的なものでないことを確認してください。詳細は、ユーザーのパスワードの設定 を参照してください。

  9. Client Roles ドロップダウンリストから realm-management を選択します。
  10. create-clientmanage-clients、および manage-realm ロールを client-admin ユーザーに割り当てます。

    詳細は、ロールマッピングの割り当て を参照してください。

3.6.6. SAML サブシステムを設定するための環境変数

次の変数を理解して使用することで、環境内での Keycloak サーバーの統合を最適化できます。これにより、アプリケーション用にシームレスでセキュアな Keycloak セットアップを実現できます。

表3.2 環境変数
環境変数説明必須

APPLICATION_NAME

デプロイメント名から導出されるクライアント名の接頭辞として使用されます。

オプション

HOSTNAME_HTTP

HTTP OpenShift ルートのカスタムの hostname。設定されていない場合は、ルート検出が実行されます。

オプション

HOSTNAME_HTTPS

HTTPS OpenShift ルートのカスタムの hostname。設定されていない場合は、ルート検出が実行されます。

オプション

SSO_DISABLE_SSL_CERTIFICATE_VALIDATION

true または false を選択して、Keycloak サーバー証明書の検証を有効または無効にします。SSO サーバーが自己署名証明書を生成する場合は、これを true に設定することを検討してください。

オプション

SSO_PASSWORD

Keycloak レルムと対話し、クライアントを作成および登録する権限を持つユーザーのパスワード。たとえば、client-admin などです。

True

SSO_REALM

アプリケーションクライアントを関連付けるための SSO レルム。たとえば、saml-basic-auth です。

オプション

SSO_SAML_CERTIFICATE_NAME

SAML クライアントキーストア内の秘密鍵と証明書のエイリアス。たとえば、saml-app です。

True

SSO_SAML_KEYSTORE

キーストアファイルの名前。たとえば、keystore.jks です。

True

SSO_SAML_KEYSTORE_DIR

クライアントキーストアを含むディレクトリー。たとえば、/etc/sso-saml-secret-volume です。

True

SSO_SAML_KEYSTORE_PASSWORD

キーストアパスワードたとえば、password です。

True

SSO_SAML_LOGOUT_PAGE

ログアウトページ。たとえば、simple-webapp-example です。

True

SSO_SAML_VALIDATE_SIGNATURE

署名を検証する場合は true を、検証しない場合は false を指定します。デフォルトは true です。

オプション

SSO_SECURITY_DOMAIN

undertow および ejb サブシステムを保護するために使用するセキュリティードメインの名前。デフォルトは keycloak です。

オプション

SSO_TRUSTSTORE

サーバー証明書を含むトラストストアのファイル名。

オプション

SSO_TRUSTSTORE_CERTIFICATE_ALIAS

トラストストア内の証明書のエイリアス。

オプション

SSO_TRUSTSTORE_DIR

トラストストアを含むディレクトリー。

オプション

SSO_TRUSTSTORE_PASSWORD

トラストストアと証明書のパスワード。たとえば、mykeystorepass です。

オプション

SSO_URL

SSO サーバーの URL。たとえば、<SSO server accessible route> です。

True

SSO_USERNAME

Keycloak レルムと対話し、クライアントを作成および登録する権限を持つユーザーのユーザー名。たとえば、client-admin などです。

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

3.6.8. 関連情報

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.