Menu Close
Settings Close

Language and Page Formatting Options

アプリケーションおよびサービスのセキュリティー保護ガイド

Red Hat Single Sign-On 7.6

Red Hat Single Sign-On 7.6 向け

概要

本ガイドは、Red Hat Single Sign-On 7.6 を使用してアプリケーションとサービスのセキュリティーを保護する情報で構成されています。

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

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。これは大規模な取り組みであるため、これらの変更は今後の複数のリリースで段階的に実施されます。詳細は、Red Hat CTO である Chris Wright のメッセージ をご覧ください。

第1章 アプリケーションとサービスのセキュア化のプランニング

Red Hat Single Sign-On は、OpenID Connect (OAuth 2.0 への拡張) と SAML 2.0 の両方をサポートします。クライアントおよびサービスのセキュリティーを保護する場合は、最初に使用するものを決定する必要があります。OpenID Connect や他の SAML でセキュリティー保護するオプションを選択することもできます。

クライアントやサービスのセキュリティーを保護するには、選択したプロトコルにアダプターまたはライブラリーが必要になります。Red Hat Single Sign-On には、選択したプラットフォーム用の独自のアダプターが含まれていますが、汎用 OpenID Connect Relying Party ライブラリーおよび SAML Service Provider ライブラリーを使用することもできます。

1.1. クライアントアダプター

Red Hat Single Sign-On クライアントアダプターは、Red Hat Single Sign-On でアプリケーションおよびサービスのセキュリティーを簡単に保護するライブラリーです。基礎となるプラットフォームやフレームワークへの密接な統合を提供するため、ライブラリーではなくアダプターを呼び出します。これにより、アダプターは使いやすく、ライブラリーで通常必要とされるものよりも必要なボイラープレートコードよりも少なくなります。

1.2. サポート対象のプラットフォーム

Red Hat Single Sign-On により、OpenID Connect および SAML プロトコルを使用して、異なるプラットフォームで実行している異なるテクノロジースタックを使用するアプリケーションを保護できます。

1.2.1. OpenID Connect

1.2.1.1. Java

1.2.1.2. JavaScript (クライアント側)

1.2.1.3. Node.js (サーバー側)

1.2.2. SAML

1.2.2.1. Java

1.2.2.2. Apache HTTP サーバー

1.3. サポートされているプロトコル

Red Hat Single Sign-On は、OpenID Connect と SAML プロトコルの両方をサポートします。

1.3.1. OpenID Connect

OpenID Connect (OIDC) は、OAuth 2.0 の拡張機能である認証プロトコルです。OAuth 2.0 は承認プロトコルを構築するためのフレームワークでしかなく、主に不完全ですが、OIDC は完全な認証および承認プロトコルです。OIDC は、JWT (Json Web Token) 標準セットも多用しています。これらの標準は、アイデンティティープロバイダーの JSON 形式を定義し、そのデータをコンパクトで Web フレンドリーで暗号化する方法を定義しています。

OIDC を使用する場合は、本当に 2 つのタイプのユースケースがあります。1 つ目のアプリケーションは、Red Hat Single Sign-On サーバーがユーザーを認証するよう依頼するアプリケーションです。ログインに成功すると、アプリケーションは ID トークンアクセストークン を受け取ります。ID トークン には、ユーザー名、電子メール、その他のプロファイル情報など、ユーザーに関する情報が含まれています。アクセストークン はレルムによってデジタル署名され、アプリケーションでユーザーがアクセスできるリソースを判別するためにアプリケーションが使用できるアクセス情報 (ユーザーロールマッピングなど) が含まれます。

2 つ目のタイプのユースケースは、リモートサービスへのアクセスを取得するクライアントのものです。この場合、クライアントはユーザーの代わりに他のリモートサービスで起動するのに使用できる アクセストークン を取得するよう Red Hat Single Sign-On に要求します。Red Hat Single Sign-On はユーザーを認証し、ユーザーに要求したクライアントにアクセスを付与するよう依頼します。その後、クライアントは アクセストークン を受け取ります。この アクセストークン はレルムによってデジタル署名されます。クライアントはこの アクセストークン を使用してリモートサービスで REST 呼び出しを行うことができます。REST サービスは、アクセストークン を抽出し、トークンの署名を検証した後、トークン内のアクセス情報に基づいて、リクエストを処理するかどうかを決定します。

1.3.2. SAML 2.0

SAML 2.0 は OIDC と同様の仕様ですが、より古く、より成熟したものです。SOAP と plethora の WS-* 仕様にはルートがあるため、OIDC よりも詳細度が少しなる傾向があります。SAML 2.0 は主に、認証サーバーとアプリケーション間の XML ドキュメント変更によって機能する認証プロトコルです。XML 署名と暗号化は、要求と応答の検証に使用されます。

Red Hat Single Sign-On SAML では、ブラウザーアプリケーションと REST 呼び出しという 2 種類のユースケースを利用できます。

SAML を使用する場合は、主に 2 つのタイプのユースケースがあります。1 つ目のアプリケーションは、Red Hat Single Sign-On サーバーがユーザーを認証するよう依頼するアプリケーションです。ログインが成功すると、アプリケーションには、ユーザーのさまざまな属性を指定する SAML アサーションが含まれる XML ドキュメントを受け取ります。XML ドキュメントはレルムによってデジタル署名され、アプリケーションでユーザーがアクセスできるリソースを判別するためにアプリケーションが使用できるアクセス情報 (ユーザーロールマッピングなど) が含まれます。

2 つ目のタイプのユースケースは、リモートサービスへのアクセスを取得するクライアントのものです。この場合、クライアントはユーザーの代わりに他のリモートサービスで起動するのに使用できる SAML アサーションを取得するよう Red Hat Single Sign-On に要求します。

1.3.3. OpenID Connect 対SAML

OpenID Connect と SAML の選択は、古い成熟したプロトコル(SAML)の代わりに新しいプロトコル (OIDC) を使用する場合でも問題はありません。

多くの場合、Red Hat Single Sign-On では、OIDC の使用を推奨します。

SAML は OIDC よりも詳細な状態である傾向があります。

交換されたデータの詳細レベルを超えた場合、SAML は Web で機能するように OIDC が Web で機能するように設計されている仕様を比較すると、Web 上で動作するように調整されました。たとえば、OIDC は、SAML よりもクライアント側に簡単に実装できるため、HTML5/JavaScript アプリケーションにも適しています。トークンは JSON 形式であるため、JavaScript による使いやすさが簡単です。また、Web アプリケーションでセキュリティーを実装するためにより優れた機能もいくつかあります。たとえば、ユーザーがログインしたままかどうかを簡単に判断するために仕様で使用されている iframe における効果的な方法 を確認してください。

SAML がその使い方もあります。OIDC 仕様が進化したように、SAML で数年以上の機能を実装することがわかります。多くの場合は、成熟度が高いため、またそれらにはセキュリティーを確保した既存のアプリケーションがすでにあるため、SAML over OIDC を選択していることがよく見られます。

1.4. 用語

このガイドでは、以下の用語を使用しています。

  • クライアント は、Red Hat Single Sign-On と対話してユーザーを認証し、トークンを取得するエンティティーです。多くの場合、クライアントは、そのユーザーにシングルサインオンエクスペリエンスを提供し、サーバーが発行するトークンを使用して他のサービスにアクセスするユーザーの代わりに機能するアプリケーションおよびサービスです。クライアントは、トークンの取得のみに関心があり、他のサービスにアクセスするために機能するエンティティーである場合もあります。
  • アプリケーション には、それぞれのプロトコルについて特定のプラットフォームで動作する幅広いアプリケーションが含まれます。
  • クライアントアダプター は、Red Hat Single Sign-On でアプリケーションとサービスを簡単に保護できるようにするライブラリーです。基礎となるプラットフォームやフレームワークへの密接な統合を提供します。
  • クライアントの作成クライアントの登録 は、同じアクションです。クライアントの作成は、管理コンソールを使用してクライアントを作成するのに使用する用語です。クライアントの登録 は、Red Hat Single Sign-On Client Registration Serviceを使用してクライアントを登録するのに使用される用語です。
  • サービスアカウント は、自分自身のためにトークンを取得できるクライアントの一種です。

1.5. アプリケーションとサービスを保護する基本的な手順

以下は、Red Hat Single Sign-On でアプリケーションまたはサービスのセキュリティーを保護する基本的な手順です。

  1. 以下のオプションのいずれかを使用してクライアントを設定します。

    • Red Hat Single Sign-On アダプター
    • 汎用 OpenID 接続または SAML ライブラリー
  2. 以下のオプションのいずれかを使用してクライアントを登録します。

    • Red Hat Single Sign-On 管理コンソール
    • クライアント登録サービス
    • CLI

関連情報

  • 本ガイドでは、これらのステップを詳細に説明します。関連情報は『Server Administration Guide』にあります。本ガイドでは、管理コンソールを使用してクライアントを作成する方法を説明します。クライアントの作成は、Red Hat Single Sign-On Client Registration Serviceを使用してクライアントを登録するタスクと同じです。

第2章 OpenID Connect を使用したアプリケーションとサービスのセキュア化

本セクションでは、Red Hat Single Sign-On アダプターまたは汎用 OpenID Connect Relying Party ライブラリーを使用して、OpenID Connect でアプリケーションとサービスのセキュリティーを保護する方法を説明します。

2.1. Java アダプター

Red Hat Single Sign-On には、Java アプリケーションのさまざまなアダプターがあります。正しいアダプターの選択は、ターゲットプラットフォームによって異なります。

すべての Java アダプターは、「Java アダプター設定」の章で説明されている共通の設定オプションセットを共有します。

2.1.1. Java アダプターの設定

Red Hat Single Sign-On がサポートする各 Java アダプターは、単純な JSON ファイルで設定できます。これは次のようになります。

{
  "realm" : "demo",
  "resource" : "customer-portal",
  "realm-public-key" : "MIGfMA0GCSqGSIb3D...31LwIDAQAB",
  "auth-server-url" : "https://localhost:8443/auth",
  "ssl-required" : "external",
  "use-resource-role-mappings" : false,
  "enable-cors" : true,
  "cors-max-age" : 1000,
  "cors-allowed-methods" : "POST, PUT, DELETE, GET",
  "cors-exposed-headers" : "WWW-Authenticate, My-custom-exposed-Header",
  "bearer-only" : false,
  "enable-basic-auth" : false,
  "expose-token" : true,
  "verify-token-audience" : true,
  "credentials" : {
    "secret" : "234234-234234-234234"
  },

  "connection-pool-size" : 20,
  "socket-timeout-millis" : 5000,
  "connection-timeout-millis" : 6000,
  "connection-ttl-millis" : 500,
  "disable-trust-manager" : false,
  "allow-any-hostname" : false,
  "truststore" : "path/to/truststore.jks",
  "truststore-password" : "geheim",
  "client-keystore" : "path/to/client-keystore.jks",
  "client-keystore-password" : "geheim",
  "client-key-password" : "geheim",
  "token-minimum-time-to-live" : 10,
  "min-time-between-jwks-requests" : 10,
  "public-key-cache-ttl" : 86400,
  "redirect-rewrite-rules" : {
    "^/wsmaster/api/(.*)$" : "/api/$1"
  }
}

システムプロパティーの置き換えには ${…​} エンクロージャーを使用できます。たとえば、${jboss.server.config.dir}/path/to/Red Hat Single Sign-On に置き換えられます。環境変数の代替も、env 接頭辞 (例: ${env.MY_ENVIRONMENT_VARIABLE}) でサポートされます。

初期設定ファイルは管理コンソールから取得できます。これは、管理コンソールを開き、メニューから Clients を選択して、対応するクライアントをクリックします。クライアントのページが開いたら、インストール タブをクリックし、Keycloak OIDC JSON を選択します。

各設定オプションの説明は次のとおりです。

realm
レルムの名前これは 必須 です。
resource
アプリケーションの client-id各アプリケーションには、アプリケーションを識別するのに使用される client-id があります。これは 必須 です。
realm-public-key
レルム公開鍵の PEM 形式。これは管理コンソールから取得できます。これは 任意 ですが、設定することは推奨されません。設定しないと、アダプターは Red Hat Single Sign-On からダウンロードし、必要に応じて常に再ダウンロードを行います (例: Red Hat Single Sign-On はその鍵をローテーションします)。ただし、realm-public-key が設定されている場合、アダプターは Red Hat Single Sign-On から新しい鍵をダウンロードしません。そのため、Red Hat Single Sign-On が鍵をローテーションするとアダプターが中断されます。
auth-server-url
Red Hat Single Sign-On サーバーのベース URL。他のすべての Red Hat シングルサインオンページおよび REST サービスエンドポイントはこれから派生します。通常、形式は https://host:port/auth です。これは 必須 です。
ssl-required
Red Hat Single Sign-On サーバーとの間のすべての通信が HTTPS を介して行われるようにします。実稼働環境では、これを all に設定する必要があります。これは 任意 です。デフォルト値は external です。つまり、外部要求に HTTPS がデフォルトで必要になります。有効な値は、「all」、「external」、および「none」です。
confidential-port
SSL/TLS を介してセキュアな接続のために、Red Hat Single Sign-On サーバーによって使用される機密ポート。これは 任意 です。デフォルト値は 8443 です。
use-resource-role-mappings
true に設定すると、アダプターはユーザーのアプリケーションレベルのロールマッピングのトークンを検索します。false の場合は、ユーザーロールマッピングのレルムレベルを確認します。これは 任意 です。デフォルト値は false です。
public-client
true に設定すると、アダプターはクライアントの認証情報を Red Hat Single Sign-On に送信しません。これは 任意 です。デフォルト値は false です。
enable-cors
これにより、CORS サポートが有効になります。CORS プリフライトリクエストを処理します。また、アクセストークンを調べて、有効な発信元を判別します。これは 任意 です。デフォルト値は false です。
cors-max-age
CORS が有効な場合は、Access-Control-Max-Age ヘッダーの値が設定されます。これは 任意 です。設定されていない場合、このヘッダーは CORS 応答で返されません。
cors-allowed-methods
CORS が有効な場合は、Access-Control-Allow-Methods ヘッダーの値が設定されます。これはコンマ区切りの文字列である必要があります。これは 任意 です。設定されていない場合、このヘッダーは CORS 応答で返されません。
cors-allowed-headers
CORS が有効な場合は、Access-Control-Allow-Headers ヘッダーの値を設定します。これはコンマ区切りの文字列である必要があります。これは 任意 です。設定されていない場合、このヘッダーは CORS 応答で返されません。
cors-exposed-headers
CORS が有効な場合は、Access-Control-Expose-Headers ヘッダーの値を設定します。これはコンマ区切りの文字列である必要があります。これは 任意 です。設定されていない場合、このヘッダーは CORS 応答で返されません。
bearer-only
これは、サービスに true に設定する必要があります。有効な場合、アダプターはユーザーの認証を試行しませんが、ベアラートークンのみを検証します。これは 任意 です。デフォルト値は false です。
autodetect-bearer-only
アプリケーションが Web アプリケーションと Web サービス (例: SOAP または REST) の両方に対応する場合は、true に設定する必要があります。Web アプリケーションの認証されていないユーザーを Red Hat Single Sign-On ログインページにリダイレクトできますが、認証されていない SOAP または REST クライアントに HTTP 401 ステータスコードを送信することができます。ログインページへのリダイレクトは理解できません。Red Hat Single Sign-On は、X-Requested-WithSOAPAction、または Accept などの一般的なヘッダーに基づいて SOAP クライアントまたは REST クライアントを自動検出します。デフォルト値は false です。
enable-basic-auth
これは、Basic 認証もサポートするようにアダプターに指示します。このオプションが有効な場合には、シークレット も指定する必要があります。これは 任意 です。デフォルト値は false です。
expose-token
true の場合、(JavaScript HTTP 呼び出しを介して) 認証されたブラウザークライアントは、URL root/k_query_bearer_token を使用して署名されたアクセストークンを取得できます。これは 任意 です。デフォルト値は false です。
credentials
アプリケーションの認証情報を指定します。これは、鍵が認証情報タイプであり、値が認証情報タイプの値であるオブジェクト表記です。現在、パスワードおよび jwt がサポートされています。これは、アクセスタイプが「Confidential」を持つクライアントにのみ 必須 になります。
connection-pool-size
この設定オプションでは、Red Hat Single Sign-On サーバーへプールする接続の数を定義します。これは 任意 です。デフォルト値は 20 です。
socket-timeout-millis
接続の確立後にデータを待つソケットのタイムアウト (ミリ秒単位)。2 つのデータパケット間の最長の非アクティブ時間。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connection-timeout-millis
リモートホストとの接続を確立するためのタイムアウト (ミリ秒単位)。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connection-ttl-millis
クライアント向けの接続 Time to Live (TTL) (ミリ秒単位)。ゼロ以下の値は、無限の値として解釈されます。デフォルト値は -1 です。これは 任意 です。
disable-trust-manager
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合は、トラストストアを指定する必要はありません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を無効にするため、実稼働環境では 使用しないで ください。これは 任意 です。デフォルト値は false です。
allow-any-hostname
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合、Red Hat Single Sign-On サーバーの証明書はトラストストア経由で検証されますが、ホスト名の検証は行われません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を無効にするため、実稼働環境では 使用しないで ください。この設定は、テスト環境で役に立つ場合があります。これは 任意 です。デフォルト値は false です。
proxy-url
HTTP プロキシーが使用されている場合はその URL。
truststore
値は、トラストストアファイルへのファイルパスです。classpath: でパスを接頭辞にすると、代わりにデプロイメントのクラスパスからトラストストアが取得されます。Red Hat Single Sign-On サーバーへの送信 HTTPS 通信に使用されます。HTTPS 要求を実行するクライアントでは、通信先のサーバーのホストを確認する方法が必要です。これは、トラストストアが行なうことです。キーストアには、1 つ以上の信頼できるホスト証明書または認証局が含まれます。Red Hat Single Sign-On サーバーの SSL キーストアの公開証明書を抽出して、このトラストストアを作成できます。これは、ssl-requirednone、または disable-trust-managertrue でない限り、必須 になります。
truststore-password
トラストストアのパスワード。これは、トラストストア が設定され、トラストストアにパスワードが必要な場合は 必須 になります。
client-keystore
これはキーストアファイルに対するファイルパスです。このキーストアには、アダプターが Red Hat Single Sign-On サーバーに対して HTTPS を要求する際に双方向 SSL のクライアント証明書が含まれます。これは 任意 です。
client-keystore-password
クライアントキーストアのパスワード。これは、client-keystore が設定されている場合は 必須 になります。
client-key-password
クライアントのキーのパスワードこれは、client-keystore が設定されている場合は 必須 になります。
always-refresh-token
true の場合、アダプターはすべてのリクエストでトークンを更新します。警告: これを有効にすると、アプリケーションへのリクエストごとに Red Hat Single Sign-On へのリクエストが行われます。
register-node-at-startup
true の場合、アダプターは登録リクエストを Red Hat Single Sign-On に送信します。デフォルトは false で、アプリケーションがクラスター化されている場合にのみ便利です。詳細は、「アプリケーションクラスタリング」を参照してください。
register-node-period
Red Hat Single Sign-On に再登録アダプターを使用する期間。アプリケーションがクラスター化されている場合に役立ちます。詳細は、「アプリケーションクラスタリング」を参照してください。
token-store
使用できる値は session および cookie です。デフォルトは session で、アダプターはアカウント情報を HTTP セッションに保存します。代替 cookie とは、cookie への情報の格納を意味します。詳細は、「アプリケーションクラスタリング」を参照してください。
token-cookie-path
cookie ストアを使用する場合、このオプションはアカウント情報を保存するために使用される cookie のパスを設定します。相対パスの場合は、アプリケーションがコンテキストルートで実行されていることを前提とし、そのコンテキストルートへの相対的として解釈されます。絶対パスの場合は、クッキーパスの設定に絶対パスが使用されます。デフォルトは、コンテキストルートへの相対パスを使用します。
principal-attribute
UserPrincipal 名を入力する OpenID Connect ID Token 属性。トークン属性が null の場合、デフォルトは sub に設定されます。使用できる値は subpreferred_usernameemailnamenicknamegiven_namefamily_name です。
turn-off-change-session-id-on-login
一部のプラットフォームでログインに成功すると、セキュリティー攻撃ベクトルをプラグインするために、セッション ID がデフォルトで変更されます。これをオフにする場合は、これを true に変更します。これは 任意 です。デフォルト値は false です。
token-minimum-time-to-live
Red Hat Single Sign-On サーバーでアクティブなアクセストークンを事前更新してから失効する時間 (秒単位)。これは、アクセストークンが別の REST クライアントに送信され、評価前に期限切れになる可能性がある場合に特に便利です。この値は、レルムのアクセストークンの有効期間を超えてはいけないはずです。これは 任意 です。デフォルト値は 0 秒であるため、アダプターは期限切れの場合にのみアクセストークンを更新します。
min-time-between-jwks-requests
新しい公開鍵を取得するための Red Hat Single Sign-On への2つの要求間の最小間隔を指定する時間 (秒単位)。デフォルトは 10 秒です。アダプターは、不明な kid でトークンを認識すると、常に新しい公開鍵をダウンロードしようとします。ただし、10 秒に 1 回以上試行することはありません (デフォルト)。これは、攻撃者が不正な kid 強制アダプターを使用して多数のトークンを送信し、Red Hat Single Sign-On に多数のリクエストを送信するときに DoS を回避するためです。
public-key-cache-ttl
新しい公開鍵を取得する Red Hat Single Sign-On への 2 つのリクエストの最大間隔を指定する時間 (秒単位)。デフォルトは 86400 秒 (1 日) です。アダプターは、不明な kid でトークンを認識すると、常に新しい公開鍵をダウンロードしようとします。既知の kid でトークンを認識すると、以前ダウンロードした公開鍵のみを使用します。ただし、この設定した間隔 (デフォルトでは 1 日) につき少なくとも 1 回は新しい公開鍵がダウンロードされます。トークンの kid の規模が分かっている場合でも、常に新しい公開鍵がダウンロードされます。
ignore-oauth-query-parameter
デフォルトは false です。true に設定すると、ベアラートークン処理の access_token クエリーパラメーターの処理がオフになります。access_token を渡すだけでは、ユーザーを認証できません
redirect-rewrite-rules
必要な場合は、リダイレクト URI の書き換えルールを指定します。これは、キーが Redirect URI を照合する正規表現で、値は代替文字列になります。$ 文字は、代替 String の後方参照に使用できます。
verify-token-audience
true に設定すると、ベアラートークンを使用した認証中に、アダプターはトークンにこのクライアント名 (リソース) がオーディエンスとして含まれているかどうかを確認します。このオプションは特に、主にベアラートークンで認証された要求を提供するサービスに有用です。これは、デフォルトでは false に設定されますが、セキュリティーを強化する場合は、これを有効にすることが推奨されます。オーディエンスサポートの詳細は、「Audience Support」を参照してください。

2.1.2. JBoss EAP アダプター

このアダプターは、ZIP ファイルまたは RPM からインストールできます。

2.1.3. ZIP ファイルからの JBOSS EAP アダプターのインストール

JBoss EAP にデプロイされた WAR アプリケーションのセキュリティーを保護するには、Red Hat Single Sign-On アダプターサブシステムをインストールおよび設定する必要があります。次に、WAR のセキュリティーを保護する 2 つのオプションがあります。

  • WAR でアダプター設定ファイルを指定し、auth-method を web.xml 内の KEYCLOAK に変更できます。
  • または、WAR を修正する必要がなく、standalone.xml などの設定ファイルの Red Hat Single Sign-On アダプターサブシステム設定を介してセキュリティー保護できます。

本セクションでは、両方の方法を説明します。

アダプターは、使用しているサーバーのバージョンに応じて、別のアーカイブとして利用できます。

手順

  1. Sotware Downloads サイトからアプリケーションサーバーに適用されるアダプターをインストールします。

    • JBoss EAP 7 にインストールします。

      $ cd $EAP_HOME
      $ unzip rh-sso-7.6.0-eap7-adapter.zip

      この ZIP アーカイブには、Red Hat Single Sign-On アダプターに固有の JBoss モジュールが含まれています。また、アダプターサブシステムを設定するための JBoss CLI スクリプトも含まれています。

  2. アダプターサブシステムを設定するには、適切なコマンドを実行します。

    • サーバーが実行されて いない場合に、JBoss EAP 7.1 以上へのインストール

      $ ./bin/jboss-cli.sh --file=bin/adapter-elytron-install-offline.cli
      注記

      JBoss EAP 6.4 ではオフラインスクリプトは利用できません。

    • サーバーを実行している場合に、JBoss EAP 7.1 以上へのインストール

      $ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install.cli
      注記

      JBoss EAP 7.1 以上で従来の非 Elytron アダプターを使用することもできます。つまり、adapter-install-offline.cliを使用することができます。

    • JBoss EAP 6.4 へのインストール

      $ ./bin/jboss-cli.sh -c --file=bin/adapter-install.cli

2.1.3.1. JBoss SSO

JBoss EAP は、同じ JBoss EAP インスタンスにデプロイされた web アプリケーションに対するシングルサインオンのサポートが組み込まれています。これは、Red Hat Single Sign-On を使用する場合に有効にしないでください。

2.1.3.2. WAR のセキュリティー保護

本セクションでは、WAR パッケージ内の設定ファイルを追加および編集して、WAR を直接保護する方法を説明します。

手順

  1. WAR の WEB-INF ディレクトリーに keycloak.json アダプター設定ファイルを作成します。

    この設定ファイルの形式は、「Java アダプター設定」セクションで説明されています。

  2. web.xmlauth-methodKEYCLOAK に設定します。
  3. 標準のサーブレットセキュリティーを使用して URL に role-base 制約を指定します。

    以下に例を示します。

    <web-app 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_3_0.xsd"
          version="3.0">
    
        <module-name>application</module-name>
    
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>Admins</web-resource-name>
                <url-pattern>/admin/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>admin</role-name>
            </auth-constraint>
            <user-data-constraint>
                <transport-guarantee>CONFIDENTIAL</transport-guarantee>
            </user-data-constraint>
        </security-constraint>
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>Customers</web-resource-name>
                <url-pattern>/customers/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>user</role-name>
            </auth-constraint>
            <user-data-constraint>
                <transport-guarantee>CONFIDENTIAL</transport-guarantee>
            </user-data-constraint>
        </security-constraint>
    
        <login-config>
            <auth-method>KEYCLOAK</auth-method>
            <realm-name>this is ignored currently</realm-name>
        </login-config>
    
        <security-role>
            <role-name>admin</role-name>
        </security-role>
        <security-role>
            <role-name>user</role-name>
        </security-role>
    </web-app>

2.1.3.3. Adapter サブシステムによる WAR のセキュリティー保護

WAR を変更して Red Hat Single Sign-On で保護する必要はありません。代わりに、Red Hat Single Sign-On Adapter サブシステム経由で外部からセキュリティー保護することができます。Keycloak を auth-method として指定する必要はありませんが、web.xmlsecurity-constraints を定義する必要があります。ただし、WEB-INF/keycloak.json ファイルを作成する必要がありません。メタデータは、代わりに Red Hat Single Sign-On サブシステムのサーバー設定 (standalone.xml) で定義されます。

<extensions>
  <extension module="org.keycloak.keycloak-adapter-subsystem"/>
</extensions>

<profile>
  <subsystem xmlns="urn:jboss:domain:keycloak:1.1">
     <secure-deployment name="WAR MODULE NAME.war">
        <realm>demo</realm>
        <auth-server-url>http://localhost:8081/auth</auth-server-url>
        <ssl-required>external</ssl-required>
        <resource>customer-portal</resource>
        <credential name="secret">password</credential>
     </secure-deployment>
  </subsystem>
</profile>

secure-deployment name 属性は、セキュリティーを保護する WAR を識別します。この値は web.xml.war を追加した module-name です。残りの構成は、Javaアダプター構成 で定義された keycloak.json 構成オプションとほぼ 1 対 1 で対応しています。

例外は credential 要素です。

これを容易にするために、Red Hat Single Sign-On 管理コンソールに移動し、この WAR が連携しているアプリケーションのクライアント/インストールタブに移動します。ここでは、カットアンドペーストできる XML ファイルの例を提供します。

同じレルムでセキュア化された複数のデプロイメントがある場合は、レルム設定を個別の要素で共有できます。以下に例を示します。

<subsystem xmlns="urn:jboss:domain:keycloak:1.1">
    <realm name="demo">
        <auth-server-url>http://localhost:8080/auth</auth-server-url>
        <ssl-required>external</ssl-required>
    </realm>
    <secure-deployment name="customer-portal.war">
        <realm>demo</realm>
        <resource>customer-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="product-portal.war">
        <realm>demo</realm>
        <resource>product-portal</resource>
        <credential name="secret">password</credential>
    </secure-deployment>
    <secure-deployment name="database.war">
        <realm>demo</realm>
        <resource>database-service</resource>
        <bearer-only>true</bearer-only>
    </secure-deployment>
</subsystem>

2.1.3.4. セキュリティードメイン

セキュリティーコンテキストは EJB 階層に自動的に伝播されます。

2.1.4. RPM からの JBoss EAP 7 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

前提条件

RPM から JBoss EAP 7 アダプターをインストールする前に、JBoss EAP 7.4 リポジトリーにサブスクライブする必要があります。

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。

    Red Hat Enterprise Linux 6、7 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms

    Red Hat Enterprise Linux 8 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。

    $ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms

手順

  1. Red Hat Enterprise Linux のバージョンに応じて OIDC の JBoss EAP 7 アダプターをインストールします。

    • Red Hat Enterprise Linux 6、7 へのインストール

      $ sudo yum install eap7-keycloak-adapter-sso7_5
    • Red Hat Enterprise Linux 8 へのインストール

      $ sudo dnf install eap7-keycloak-adapter-sso7_5
      注記

      RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap7/root/usr/share/wildfly です。

  2. OIDC モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli

インストールが完了しました。

2.1.5. RPM からの JBoss EAP 6 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

RPM から EAP 6 アダプターをインストールする前に、JBoss EAP 6 リポジトリーにサブスクライブする必要があります。

前提条件

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。

    Red Hat Subscription Manager を使用して、以下のコマンドを使用して JBoss EAP 6 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms

手順

  1. 以下のコマンドを使用して、OIDC の EAP 6 アダプターをインストールします。

    $ sudo yum install keycloak-adapter-sso7_5-eap6
    注記

    RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap6/root/usr/share/wildfly です。

  2. OIDC モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install.cli

インストールが完了しました。

2.1.6. Spring Boot アダプター

注記

Spring Boot アダプターは非推奨となり、RH-SSO の 8.0 以降のバージョンには含まれません。このアダプターは、RH-SSO 7.x のライフサイクル期間、メンテナンスされます。ユーザーは Spring Security に移行して、Spring Boot アプリケーションを RH-SSO と統合する必要があります。

2.1.6.1. Spring Boot アダプターのインストール

Spring Boot アプリケーションのセキュリティーを保護するには、Keycloak Spring Boot アダプター JAR をアプリケーションに追加する必要があります。その後、通常の Spring Boot 設定 (application.properties) を使用して追加の設定を提供する必要があります。

Keycloak Spring Boot アダプターは Spring Boot の自動設定を活用するため、このアダプターKeycloak Spring Boot スターターをプロジェクトに追加する必要があります。

手順

  1. Maven を使用してスターターをプロジェクトに追加するには、以下を依存関係に追加します。

    <dependency>
        <groupId>org.keycloak</groupId>
        <artifactId>keycloak-spring-boot-starter</artifactId>
    </dependency>
  2. アダプター BOM 依存関係を追加します。

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.keycloak.bom</groupId>
          <artifactId>keycloak-adapter-bom</artifactId>
          <version>18.0.0.redhat-00001</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>

現在、以下の埋め込みコンテナーはサポートされており、Starter の使用時には追加の依存関係は必要ありません。

  • Tomcat
  • Undertow
  • Jetty

2.1.6.2. Spring Boot アダプターの設定

以下の手順を使用して、Red Hat Single Sign-On を使用するように Spring Boot アプリケーションを設定します。

手順

  1. keycloak.json ファイルの代わりに、通常の Spring Boot 設定を介して Spring Boot アダプターのレルムを設定します。以下に例を示します。

    keycloak.realm = demorealm
    keycloak.auth-server-url = http://127.0.0.1:8080/auth
    keycloak.ssl-required = external
    keycloak.resource = demoapp
    keycloak.credentials.secret = 11111111-1111-1111-1111-111111111111
    keycloak.use-resource-role-mappings = true

    keycloak.enabled = false を設定して、Keycloak Spring Boot Adapter (テストなど) を無効できます。

  2. Policy Enforcer を設定するには、keycloak.json とは異なり、policy-enforcer ではなく policy-enforcer-config を使用します。
  3. 通常 web.xml にある Java EE セキュリティー設定を指定します。

    Spring Boot Adapter は login-methodKEYCLOAK に設定し、起動時に security-constraints を設定します。以下は、設定例です。

    keycloak.securityConstraints[0].authRoles[0] = admin
    keycloak.securityConstraints[0].authRoles[1] = user
    keycloak.securityConstraints[0].securityCollections[0].name = insecure stuff
    keycloak.securityConstraints[0].securityCollections[0].patterns[0] = /insecure
    
    keycloak.securityConstraints[1].authRoles[0] = admin
    keycloak.securityConstraints[1].securityCollections[0].name = admin stuff
    keycloak.securityConstraints[1].securityCollections[0].patterns[0] = /admin
警告

Spring アプリケーションを WAR としてデプロイする予定の場合は、Spring Boot アダプターを使用せず、使用しているアプリケーションサーバーまたはサーブレットコンテナーの専用アダプターを使用してください。Spring Boot には web.xml ファイルも含まれている必要があります。

2.1.7. Java サーブレットフィルターアダプター

Java Servlet アプリケーションをプラットフォームにデプロイする場合は、Red Hat Single Sign-On アダプターがないため、サーブレットフィルターアダプターを使用できます。このアダプターは、他のアダプターとは異なります。web.xml ではセキュリティー制約を定義しません。代わりに、Red Hat Single Sign-On サーブレットフィルターアダプターを使用してフィルターマッピングを定義し、セキュリティーを保護する url パターンを保護します。

警告

Backchannel ログアウトの動作は、標準アダプターとは少々異なります。HTTP セッションを無効にする代わりに、セッション ID をログアウトとしてマークします。セッション ID に基づいて HTTP セッションを無効にする標準的な方法はありません。

<web-app 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_3_0.xsd"
      version="3.0">

	<module-name>application</module-name>

    <filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Keycloak Filter</filter-name>
        <url-pattern>/keycloak/*</url-pattern>
        <url-pattern>/protected/*</url-pattern>
    </filter-mapping>
</web-app>

上記のスニペットには、url-patterns が 2 つあります。/protected/* は保護する必要のあるファイルですが、/keycloak/* url-pattern は Red Hat Single Sign-On サーバーからコールバックを処理します。

構成された url-patternsの 下の一部のパスを除外する必要がある場合は、フィルターの init パラメーター keycloak.config.skipPatternを使用して、keycloak フィルターがフィルターチェーンにすぐに委譲するパスパターンを記述する正規表現を構成できます。デフォルトでは skipPattern が設定されていません。

パターンは、context-path なしで requestURI に対して一致します。コンテキストパス /myapp を指定すると、/myapp/index.html のリクエストはスキップパターンに対して /index.html と照合されます。

<init-param>
    <param-name>keycloak.config.skipPattern</param-name>
    <param-value>^/(path1|path2|path3).*</param-value>
</init-param>

フィルターの url-pattern で対応しているセキュアなセクションを参照する管理 URL を使用して、Red Hat Single Sign-On 管理コンソールでクライアントを設定する必要があります。

管理 URL は、バックチャネルログアウトなどを行うための管理 URL へのコールバックを作成します。この例の管理 URL は http[s]://hostname/{context-root}/keycloak となります。

セッション ID マッパーをカスタマイズする必要がある場合は、フィルター init-param keycloak.config.idMapper でクラスの完全修飾名を設定できます。セッション ID マッパーは、ユーザー ID とセッション ID のマップに使用されるマッパーです。デフォルトでは、org.keycloak.adapters.spi.InMemorySessionIdMapper が設定されています。

<init-param>
    <param-name>keycloak.config.idMapper</param-name>
    <param-value>org.keycloak.adapters.spi.InMemorySessionIdMapper</param-value>
</init-param>

Red Hat Single Sign-On フィルターには、他のアダプターと同じ設定パラメーターがあります。ただし、コンテキストパラメーターではなく、フィルター init パラメーターとして定義する必要があります。

このフィルターを使用するには、この maven アーティファクトを WAR pom に組み込みます。

<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-servlet-filter-adapter</artifactId>
    <version>18.0.0.redhat-00001</version>
</dependency>

2.1.8. セキュリティコンテキスト

KeycloakSecurityContext インターフェースは、トークンに直接アクセスする必要がある場合に利用できます。これは、トークン (ユーザープロファイル情報など) から追加情報を取得する場合や、Red Hat Single Sign-On が保護する RESTful サービスを呼び出す場合に便利です。

サーブレット環境では、HttpServletRequest の属性としてセキュアな呼び出しを利用できます。

httpServletRequest
    .getAttribute(KeycloakSecurityContext.class.getName());

または、HttpSession のセキュアでない要求で利用できます。

httpServletRequest.getSession()
    .getAttribute(KeycloakSecurityContext.class.getName());

2.1.9. エラー処理

Red Hat Single Sign-On には、サーブレットベースのクライアントアダプターに対するエラー処理機能があります。認証でエラーが発生した場合、Red Hat Single Sign-On は HttpServletResponse.sendError() を呼び出します。web.xml ファイル内にエラーページを設定して、必要なエラーを処理できます。Red Hat Single Sign-On は 400、401、403、および 500 のエラーをスローできます。

<error-page>
    <error-code>403</error-code>
    <location>/ErrorHandler</location>
</error-page>

Red Hat Single Sign-On は、取得可能な HttpServletRequest 属性も設定します。属性名は org.keycloak.adapters.spi.AuthenticationError で、org.keycloak.adapters.OIDCAuthenticationError にキャストする必要があります。

以下に例を示します。

import org.keycloak.adapters.OIDCAuthenticationError;
import org.keycloak.adapters.OIDCAuthenticationError.Reason;
...

OIDCAuthenticationError error = (OIDCAuthenticationError) httpServletRequest
    .getAttribute('org.keycloak.adapters.spi.AuthenticationError');

Reason reason = error.getReason();
System.out.println(reason.name());

2.1.10. ログアウト

Web アプリケーションからログアウトするには、複数の方法でログアウトできます。Jakarta EE サーブレットコンテナーでは、HttpServletRequest.logout() を呼び出すことができます。他のブラウザーアプリケーションの場合は、ブラウザーを http://auth-server/auth/realms/{realm-name}/protocol/openid-connect/logout にリダイレクトできます。これは、ユーザーのブラウザーに SSO セッションがある場合にユーザーをログアウトします。実際のログアウトは、ユーザーがログアウトを確認すると行われます。OpenID Connect RP-Initiated Logout に記載されているように、id_token_hintpost_logout_redirect_uri などのパラメーターを追加できます。その結果、ログアウトをユーザーが明示的に確認する必要はありません。

ログアウト処理の一部として外部 ID プロバイダからのログアウトを回避したい場合は、パラメータ initiating_idp を指定して、値を問題の ID プロバイダーの ID (エイリアス) にすることができます。このパラメーターは、ログアウトエンドポイントが外部アイデンティティープロバイダーによって開始される単一ログアウトの一部として呼び出される場合に便利です。パラメーター initiating_idp は、RP-Initiated Logout 仕様で説明されているパラメーターに加えて、Red Hat Single Sign-On ログアウトエンドポイントのサポートされるパラメーターです。

HttpServletRequest.logout() オプションを使用する場合、アダプターはリフレッシュトークンを渡す Red Hat Single Sign-On サーバーに対してバックチャンネル POST 呼び出しを実行します。保護されていないページ (有効なトークンを確認しないページ) からメソッドが実行されると、更新トークンは利用できません。その場合、アダプターは呼び出しをスキップします。このため、現在のトークンが常に考慮され、必要に応じて Red Hat Single Sign-On server サーバーとの対話が実行されるように、保護されたページを使用して HttpServletRequest.logout() を実行することが推奨されます。

2.1.11. パラメーター転送

Red Hat Single Sign-On の初期承認エンドポイントリクエストでは、さまざまなパラメーターがサポートされます。ほとんどのパラメーターは、OIDC 仕様 に記載されています。一部のパラメーターは、アダプター設定に基づいてアダプターによって自動的に追加されます。ただし、呼び出しごとに追加できるパラメーターはいくつかあります。セキュアなアプリケーション URI を開くと、特定のパラメーターは Red Hat Single Sign-On 承認エンドポイントに転送されます。

例えば、オフライントークンを要求する場合は、次のように scope パラメーターを指定してセキュアなアプリケーションの URI を開くことができます。

http://myappserver/mysecuredapp?scope=offline_access

およびパラメーター scope=offline_access を指定すると、Red Hat Single Sign-On 認証エンドポイントに自動的に転送されます。

サポートされるパラメーターは以下のとおりです。

  • scope - スコープのスペースで区切られたリストを使用します。スペースで区切られたリストは、通常、特定のクライアントで定義された クライアントスコープ を参照します。スコープの openid は、アダプターによって常にスコープのリストに追加されることに注意してください。例えば、スコープオプションの address phone を入力すると、Red Hat Single Sign-On へのリクエストにはスコープパラメーター scope=openid address phone が含まれます。
  • prompt - Red Hat Single Sign-On では、以下の設定がサポートされます。

    • login - SSO は無視され、ユーザーがすでに認証済みであっても Red Hat Single Sign-On ログインページが常に表示されます。
    • consent - 同意が必要な クライアントにのみ適用されます。これを使用すると、ユーザーが以前にこのクライアントに同意した場合でも、Consent ページが常に表示されます。
    • none - ログインページは表示されません。その代わりに、ユーザはアプリケーションにリダイレクトされ、ユーザーが認証されていない場合はエラーが表示されます。この設定により、アプリケーション側でフィルター/インターセプターを作成し、ユーザーにカスタムのエラーページを表示できます。詳細は、仕様を参照してください。
  • max_age - ユーザーがすでに認証されている場合にのみ使用します。認証が永続する最大時間を指定します。ユーザーの認証時から測定されます。ユーザーが maxAge より長く認証されると、SSO は無視され、再認証が必要となります。
  • login_hint - ログインフォームの username/email フィールドを事前に入力するのに使用されます。
  • kc_idp_hint - Red Hat Single Sign-On に対して、ログインページの表示をスキップし、指定のアイデンティティープロバイダーに自動的にリダイレクトするために使用されます。詳細は、Identity Provider のドキュメント を参照してください。

ほとんどのパラメーターは、OIDC 仕様 に記載されています。唯一の例外は kc_idp_hint パラメーターで、これは Red Hat Single Sign-On に固有のもので、自動的に使用する ID プロバイダーの名前が含まれています。詳細は、『Server Administration Guide』の「Identity Brokering」のセクションを参照してください。

警告

割り当てられたパラメーターを使用して URL を開くと、アダプターはアプリケーションで認証されている場合に Red Hat Single Sign-On にリダイレクトしません。たとえば、http://myappserver/mysecuredapp?prompt=login を開いても、アプリケーション mysecuredapp に対して認証済みの場合は、Red Hat Single Sign-On のログインページに自動的にリダイレクトされません。この動作は今後変更される可能性があります。

2.1.12. クライアント認証

機密 OIDC クライアントがバックチャネル要求を送信する必要がある場合 (トークンのコードを交換したり、トークンを更新する場合など)、Red Hat Single Sign-On サーバーに対して認証する必要があります。デフォルトでは、クライアント ID およびクライアントシークレット、署名済み JWT によるクライアント認証、またはクライアントシークレットを使用した署名済み JWT によるクライアント認証の 3 つの方法があります。

2.1.12.1. クライアント ID およびクライアントシークレット

これは、OAuth2 仕様で説明されている従来の方法です。クライアントには、アダプター (アプリケーション) サーバーと Red Hat Single Sign-On サーバーの両方を認識する必要があるシークレットがあります。Red Hat Single Sign-On 管理コンソールで特定のクライアントのシークレットを生成し、このシークレットをアプリケーション側の keycloak.json ファイルに貼り付けることができます。

"credentials": {
    "secret": "19666a4f-32dd-4049-b082-684c74115f28"
}

2.1.12.2. 署名済み JWT によるクライアント認証

これは RFC7523 の仕様に基づいています。これは、以下のように動作します。

  • クライアントには、秘密鍵と証明書が必要です。Red Hat シングルサインオンでは、クライアントアプリケーションのクラスパスかファイルシステムのどこかにある従来の keystore ファイルから利用できます。
  • クライアントアプリケーションを起動すると、がクライアントアプリケーションのベース URL であると仮定して、http://myhost.com/myapp/k_jwks のような URL を使用して JWKS 形式で公開鍵をダウンロードすることができます。この URL は Red Hat Single Sign-On で使用できます (下記参照)。
  • 認証中、クライアントは JWT トークンを生成し、その秘密鍵で署名し、client_assertion パラメーターの特定のバックチャンネル要求 (たとえば、code-to-token 要求) で Red Hat Single Sign-On に送信します。
  • Red Hat Single Sign-On には、JWT で署名を検証できるように、クライアントの公開鍵または証明書が必要です。Red Hat Single Sign-On では、クライアントの認証情報を設定する必要があります。まず、管理コンソールのCredentialsタブで、クライアントの認証方法として「Signed JWT」を選択する必要があります。次に、タブ Keys で、以下のいずれかを選択できます。

    • Red Hat Single Sign-On がクライアントの公開鍵をダウンロードできる JWKS URL を設定します。これは、http://myhost.com/myapp/k_jwks などの URL を指定できます (詳細は上記を参照してください)。クライアントはキーをいつでもローテーションできるため、このオプションは最も柔軟性の高いものであり、Red Hat Single Sign-On は設定を変更しなくても、必要に応じていつでも新しいキーをダウンロードします。より正確には、Red Hat Single Sign-On は、未知の kid (キー ID) 署名したトークンを見つけると、新しいキーをダウンロードします。
    • クライアントの公開鍵または証明書を、PEM 形式、JWK 形式、またはキーストアからアップロードします。このオプションを使用すると、公開鍵はハードコーディングされ、クライアントが新しいキーペアを生成する際に変更する必要があります。自分自身が利用可能でない場合は、Red Hat Single Sign-On の管理コンソールから独自のキーストアを生成することもできます。Red Hat Single Sign-On 管理コンソールの設定方法の詳細は、Server Administration Guide を参照してください。

アダプター側で設定するには、keycloak.json ファイルに以下のようなものを記述する必要があります。

"credentials": {
  "jwt": {
    "client-keystore-file": "classpath:keystore-client.jks",
    "client-keystore-type": "JKS",
    "client-keystore-password": "storepass",
    "client-key-password": "keypass",
    "client-key-alias": "clientkey",
    "algorithm": "RS256",
    "token-expiration": 10
  }
}

この設定では、WAR のクラスパスに keystore-client.jks というキーストアファイルがある必要があります。接頭辞 classpath: を使用しない場合は、クライアントアプリケーションが実行しているファイルシステム上の任意のファイルを指定できます。

algorithm フィールドは、署名済み JWT に使用されるアルゴリズムを指定し、デフォルトは RS256 です。このフィールドは、キーペアと同期する必要があります。たとえば、RS256 アルゴリズムには RSA 鍵ペアが必要で、ES256 アルゴリズムには EC キーペアが必要です。詳細は、Cryptographic Algorithms for Digital Signatures and MACs を参照してください。

2.1.13. マルチテナンシー

この場合、複数の Red Hat Single Sign-On レルムを使用して、1 つのターゲットアプリケーション (WAR) をセキュアにできることを意味します。レルムは、同じ Red Hat Single Sign-On インスタンスまたは別のインスタンスに配置できます。

実際には、これはアプリケーションが複数の keycloak.json アダプター設定ファイルを持つ必要があることを意味します。

異なるアダプター構成ファイルが異なるコンテキストパスにデプロイされた WAR の複数のインスタンスを持つことができます。しかし、これは不便である可能性があります。また、context-path 以外の項目に基づいてレルムを選択することもできます。

Red Hat Single Sign-On では、カスタム設定リゾルバーを設定して、リクエストごとに使用するアダプター設定を選択できるようになります。

これを実現するには、まず org.keycloak.adapterers.KeycloakConfigResolver の実装を作成する必要があります。以下に例を示します。

package example;

import org.keycloak.adapters.KeycloakConfigResolver;
import org.keycloak.adapters.KeycloakDeployment;
import org.keycloak.adapters.KeycloakDeploymentBuilder;

public class PathBasedKeycloakConfigResolver implements KeycloakConfigResolver {

    @Override
    public KeycloakDeployment resolve(OIDCHttpFacade.Request request) {
        if (path.startsWith("alternative")) {
            KeycloakDeployment deployment = cache.get(realm);
            if (null == deployment) {
                InputStream is = getClass().getResourceAsStream("/tenant1-keycloak.json");
                return KeycloakDeploymentBuilder.build(is);
            }
        } else {
            InputStream is = getClass().getResourceAsStream("/default-keycloak.json");
            return KeycloakDeploymentBuilder.build(is);
        }
    }

}

また、どの KeycloakConfigResolver 実装を web.xml のコンテキストパラメーター keycloak.config.resolver で使用するかを設定する必要があります。

<web-app>
    ...
    <context-param>
        <param-name>keycloak.config.resolver</param-name>
        <param-value>example.PathBasedKeycloakConfigResolver</param-value>
    </context-param>
</web-app>

2.1.14. アプリケーションクラスタリング

本章では、JBoss EAP にデプロイされたクラスター化されたアプリケーションのサポートに関連します。

アプリケーションが次のいずれであるかに応じて、いくつかのオプションを利用できます。

  • ステートレスまたはステートフル
  • 分散可能 (複製可能 http セッション) または非分散可能
  • ロードバランサーが提供するスティッキーセッションへの依存
  • Red Hat Single Sign-On と同じドメインでホストされる

クラスタリングの処理は、通常のアプリケーションほど単純ではありません。主に、ブラウザーとサーバー側のアプリケーションがリクエストを Red Hat Single Sign-On に送信するため、ロードバランサーでスティッキーセッションを有効にするのは単純ではありません。

2.1.14.1. ステートレストークンストア

デフォルトでは、Red Hat Single Sign-On によってセキュア化された web アプリケーションは HTTP セッションを使用してセキュリティーコンテキストを保存します。つまり、スティッキーセッションを有効にするか、HTTP セッションを複製する必要があります。

HTTP セッションにセキュリティーコンテキストを保存する代わりに、アダプターを設定して Cookie にこれを保存するように設定できます。これは、アプリケーションをステートレスにしたい場合、またはセキュリティコンテキストを HTTP セッションに保存したくない場合に役立ちます。

セキュリティコンテキストの保存に cookie ストアを使用するには、アプリケーションの WEB-INF/keycloak.json を編集して、以下を追加してください。

"token-store": "cookie"
注記

token-storeのデフォルト値は sessionで、HTTP セッションにセキュリティーコンテキストを保存します。

クッキーストアを使用する 1 つの制限は、すべての HTTP リクエストに対してセキュリティーコンテキスト全体がクッキーに渡されることです。これにより、パフォーマンスに影響する可能性があります。

別の小さな制限については、Single-Sign Out のサポートは限定されています。アダプターにより KEYCLOAK_ADAPTER_STATE cookie が削除されるため、アプリケーション自体からの init servlet logout (HttpServletRequest.logout) がアプリケーション自体からも問題なく機能します。ただし、別のアプリケーションから初期化されたバックチャネルログアウトは、cookie ストアを使用して Red Hat Single Sign-On によって伝播されません。そのため、アクセストークンのタイムアウトに short 値を使用することが推奨されます (例: 1 分)。

注記

一部のロードバランサーでは、Amazon ALB などのスティッキーセッション cookie 名またはコンテンツの設定は許可されません。これらの場合は、shouldAttachRoute オプションを false に設定することが推奨されます。

2.1.14.2. 相対 URI の最適化

Red Hat Single Sign-On およびアプリケーションが同じドメイン (リバースプロキシーまたはロードバランサー経由) でホストされるデプロイメントシナリオでは、クライアント設定で相対 URI オプションを使用すると便利です。

相対 URI を使用すると、URI は Red Hat Single Sign-On へのアクセスに使用する URL と相対的に解決されます。

例えば、アプリケーションの URL が https://acme.org/myapp で、Red Hat Single Sign-On の URL が https://acme.org/auth の場合は、https://acme.org/myapp 代わりに redirect-uri /myapp を使用できます。

2.1.14.3. 管理 URL の設定

特定のクライアントの管理者 URL は、Red Hat Single Sign-On の管理コンソールで設定できます。これは、Red Hat Single Sign-On サーバーが、ユーザーのログアウトや失効ポリシーのプッシュなどのさまざまなタスクのためにアプリケーションにバックエンドリクエストを送信するのに使用されます。

たとえば、バックチャネルログアウトの仕組みは以下のようになります。

  1. ユーザーが 1 つのアプリケーションからログアウトリクエストを送信します。
  2. アプリケーションはログアウトリクエストを Red Hat Single Sign-On に送信します。
  3. Red Hat Single Sign-On サーバーは、ユーザーセッションを無効にします。
  4. 次に、Red Hat Single Sign-On サーバーは、セッションに関連付けられた管理 URL を持つアプリケーションにバックチャネルリクエストを送信します。
  5. アプリケーションがログアウトリクエストを受け取ると、対応する HTTP セッションが無効になります。

管理の URL に ${application.session.host} が含まれている場合は、HTTP セッションに関連するノードの URL に置き換えられます。

2.1.14.4. アプリケーションノードの登録

前のセクションでは、Red Hat Single Sign-On が特定の HTTP セッションに関連付けられたノードにログアウトリクエストを送信する方法を説明します。ただし、場合によっては、管理者は、管理タスクを 1 つだけでなく、登録されているすべてのクラスターノードに伝達したいことがあります。たとえば、新しい not before ポリシーをアプリケーションにプッシュしたり、アプリケーションからすべてのユーザーをログアウトしたりするには、以下を実行します。

この場合、Red Hat Single Sign-On はすべてのアプリケーションクラスターノードを認識して、イベントをすべてのノードに送信できるようにします。これを行うには、自動検出メカニズムをサポートします。

  1. 新規アプリケーションノードがクラスターに参加すると、登録要求を Red Hat Single Sign-On サーバーに送信します。
  2. 要求は、定期的な間隔で Red Hat Single Sign-On に再送される場合があります。
  3. Red Hat Single Sign-On サーバーが、指定のタイムアウト内で再登録要求を受信しない場合は、自動的に特定のノードの登録を解除します。
  4. このノードは、登録されていないリクエストを送信する際に、Red Hat Single Sign-On でも登録が解除されます。これは通常、ノードのシャットダウンまたはアプリケーションのアンデプロイメント中に行われます。これは、アンデプロイメントリスナーが呼び出されていない場合に強制シャットダウンが適切に動作しないため、自動登録解除が必要になります。

一部のクラスターアプリケーションでのみ必要であるため、起動登録および定期的な再登録はデフォルトでは無効になっています。

この機能を有効にするには、アプリケーションの WEB-INF/keycloak.json ファイルを編集し、以下を追加します。

"register-node-at-startup": true,
"register-node-period": 600,

これは、アダプターが起動時に登録要求を送信し、10 分ごとに再登録します。

Red Hat Single Sign-On 管理コンソールでは、ノード再登録タイムアウトの最大数を指定できます (アダプター設定の register-node-period よりも大きくする必要があります)。管理コンソールを使用してクラスターノードを手動で追加および削除することもできます。これは、自動登録機能に依存したくない場合、または自動登録解除機能を使用せずに古いアプリケーションノードを削除する場合に便利です。

2.1.14.5. 各リクエストでトークンを更新する

デフォルトでは、アプリケーションアダプターは、有効期限が切れている場合にのみアクセストークンを更新します。ただし、すべてのリクエストでトークンを更新するようにアダプターを設定することもできます。アプリケーションが Red Hat Single Sign-On サーバーにより多くのリクエストを送信するため、パフォーマンスに影響する可能性があります。

この機能を有効にするには、アプリケーションの WEB-INF/keycloak.json ファイルを編集し、以下を追加します。

"always-refresh-token": true
注記

これは、パフォーマンスに大きく影響することがあります。ポリシーの前にログアウトを伝播するのにバックチャネルメッセージに依存しない場合にのみ、この機能を有効にします。考慮すべきもう 1 つの点は、デフォルトではアクセストークンの有効期限が短いため、ログアウトが伝播されなくても、トークンはログアウトから数分以内に有効期限が切れることです。

2.2. JavaScript アダプター

Red Hat Single Sign-On には、クライアント側 JavaScript ライブラリーが同梱されており、これを使用して HTML5/JavaScript アプリケーションをセキュアにすることができます。JavaScript アダプターは、Cordova アプリケーションに対して組み込みサポートがあります。

NPM や Yarn などのパッケージマネージャーを使用して、アプリケーションに JavaScript アダプターを含めることが推奨されます。keycloak-js パッケージは以下の場所で利用できます。

あるいは、ライブラリーは /auth/js/keycloak.js にある Red Hat Single Sign-On サーバーから直接取得でき、ZIP アーカイブとして配布されます。

クライアント側のアプリケーションの使用に関する重要なことは、クライアントの認証情報をクライアント側のアプリケーションに保存する安全な方法がないため、クライアントがパブリッククライアントである必要があることです。これにより、クライアント用に構成したリダイレクト URI が正しく、可能な限り具体的であることを確認することが非常に重要になります。

JavaScript アダプターを使用するには、まず Red Hat Single Sign-On 管理コンソールでアプリケーションのクライアントを作成する必要があります。Access Typepublic が選択されていることを確認してください。

また、Valid Redirect URIWeb Origins を設定する必要があります。そうしないと、セキュリティーの脆弱性が生じる可能性があるため、できるだけ具体的にしてください。

クライアントを作成したら、インストール タブをクリックして、Format OptionKeycloak OIDC JSON を選択し、Download をクリックします。ダウンロードした keycloak.json ファイルは、HTML ページと同じ場所にある Web サーバーでホストされている必要があります。

または、設定ファイルを省略し、アダプターを手動で設定することもできます。

以下の例は、JavaScript アダプターを初期化する方法を示しています。

<html>
<head>
    <script src="keycloak.js"></script>
    <script>
        function initKeycloak() {
            const keycloak = new Keycloak();
            keycloak.init().then(function(authenticated) {
                alert(authenticated ? 'authenticated' : 'not authenticated');
            }).catch(function() {
                alert('failed to initialize');
            });
        }
    </script>
</head>
<body onload="initKeycloak()">
    <!-- your page content goes here -->
</body>
</html>

keycloak.json ファイルが別の場所にある場合は、それを指定することができます。

const keycloak = new Keycloak('http://localhost:8080/myapp/keycloak.json');

代わりに、必要な設定で JavaScript オブジェクトを渡すことができます。

const keycloak = new Keycloak({
    url: 'http://keycloak-server$/auth',
    realm: 'myrealm',
    clientId: 'myapp'
});

デフォルトでは認証を行うには login 関数を呼び出す必要があります。ただし、アダプターが自動的に認証されるようにするオプションは 2 つあります。login-required または check-sso を init 関数に渡すことができます。ユーザーが Red Hat Single Sign-On にログインしている場合は、login-required がクライアントを認証します。そうでないと、ログインページが表示されます。check-sso は、ユーザーがログインしていない場合のみクライアントを認証します。ユーザーがログインしていない場合、ブラウザーはアプリケーションにリダイレクトされ、認証されていないままになります。

silent check-sso オプションを設定できます。この機能を有効にすると、ブラウザーは Red Hat Single Sign-On サーバーへのフルリダイレクトを行なさずにアプリケーションに戻りますが、このアクションは非表示の iframe で実行されるため、アプリケーションリソースを読み込むだけで済みます。アプリが初期化されたときにブラウザーによって 1 回解析され、Red Hat Single Sign-On からアプリにリダイレクトされた後に再度解析されることはありません。これは、SPA (Single Page Applications) の場合において特に便利です。

silent check-sso を有効にするには、init メソッドで silentCheckSsoRedirectUri 属性を指定する必要があります。この URI は、アプリケーションで有効なエンドポイントである必要があります (そして、Red Hat Single Sign-On 管理コンソールでクライアントの有効なリダイレクトとして設定する必要があります)。

keycloak.init({
    onLoad: 'check-sso',
    silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'
})

認証の状態が正常にチェックされ、Red Hat Single Sign-On サーバーからトークンを取得すると、サイレント check-sso リダイレクト URI のページが iframe に読み込まれます。受信したトークンをメインアプリケーションに送信する以外のタスクはなく、次のようになります。

<html>
<body>
    <script>
        parent.postMessage(location.href, location.origin)
    </script>
</body>
</html>

指定された場所にあるこのページは、アプリケーション自身が提供する必要があり、JavaScript アダプターの一部では ない ことに注意してください。

警告

静かな check-sso 機能は、一部の最新のブラウザーで制限さていれます。「Modern Browsers with Tracking Protection Section」のセクションを参照してください。

login-required を有効にするには、onLoadlogin-required に設定し、init メソッドに渡します。

keycloak.init({
    onLoad: 'login-required'
})

ユーザーが認証された後、アプリケーションは 認証 ヘッダーにベアラートークンを含めることで、Red Hat Single Sign-On で保護された RESTful サービスへのリクエストを行うことができます。以下に例を示します。

const loadData = function () {
    document.getElementById('username').innerText = keycloak.subject;

    const url = 'http://localhost:8080/restful-service';

    const req = new XMLHttpRequest();
    req.open('GET', url, true);
    req.setRequestHeader('Accept', 'application/json');
    req.setRequestHeader('Authorization', 'Bearer ' + keycloak.token);

    req.onreadystatechange = function () {
        if (req.readyState == 4) {
            if (req.status == 200) {
                alert('Success');
            } else if (req.status == 403) {
                alert('Forbidden');
            }
        }
    }

    req.send();
};

注意すべきことの 1 つは、アクセストークンの有効期限はデフォルトで短いため、リクエストを送信する前にアクセストークンの更新が必要になることが場合があることです。これは updateToken メソッドで行うことができます。updateToken メソッドは、トークンが正常に更新された場合にのみサービスを呼び出し、そうでない場合にはユーザーにエラーを表示することを容易にする Promise を返します。以下に例を示します。

keycloak.updateToken(30).then(function() {
    loadData();
}).catch(function() {
    alert('Failed to refresh token');
});

2.2.1. セッションステータスの iframe

デフォルトでは、JavaScript アダプターは、Single-Sign Out が発生したかどうかを検出するために使用される非表示の iframe を作成します。これにはネットワークトラフィックは必要ありません。代わりに、特別なステータスクッキーを確認してステータスを取得します。init メソッドに渡されるオプションで checkLoginIframe: false を設定することで、この機能を無効できます。

このクッキーを直接参照する必要はありません。この形式は変更でき、アプリケーションではなく、Red Hat Single Sign-On サーバーの URL に関連付けられている可能性があります。

警告

セッションステータスの iframe 機能は、一部の最新のブラウザーで制限されています。「Modern Browsers with Tracking Protection Section」のセクションを参照してください。

2.2.2. 暗黙的フローおよびハイブリッドフロー

デフォルトでは、JavaScript アダプターは Authorization Code フローを使用します。

このフローでは、Red Hat Single Sign-On サーバーは、認証トークンではなく、承認コードをアプリケーションに返します。JavaScript アダプターは、ブラウザーがアプリケーションにリダイレクトされた後に、アクセストークンとリフレッシュトークンの コード を交換します。

Red Hat Single Sign-On は、Red Hat Single Sign-On で認証に成功した直後にアクセストークンが送信される Implicit フローもサポートしています。これは、コードをトークンと交換する追加のリクエストがないため、標準フローよりもパフォーマンスが向上する可能性がありますが、アクセストークンの有効期限が切れると影響があります。

ただし、URL フラグメントでアクセストークンを送信すると、セキュリティー脆弱性が発生する可能性があります。たとえば、トークンは Web サーバーログやブラウザー履歴によってリークされる可能性があります。

暗黙のフローを有効にするには、Red Hat Single Sign-On 管理コンソールで、クライアントの Implicit Flow Enabled フラグを有効にする必要があります。また、initメソッドに implicit 値を持つパラメーター フロー を渡す必要があります。

keycloak.init({
    flow: 'implicit'
})

注記 1 つは、アクセストークンのみが提供され、更新トークンはありません。そのため、アクセストークンの期限が切れると、アプリケーションが Red Hat Single Sign-On に再度リダイレクトして新しいアクセストークンを取得する必要があります。

Red Hat Single Sign-On は、Hybrid フローにも対応しています。

これは、クライアントが管理コンソールで Standard Flow Enabled フラグおよび Implicit Flow Enabled フラグの両方を有効にしている必要があります。次に、Red Hat Single Sign-On サーバーは、コードとトークンの両方をアプリケーションに送信します。アクセストークンは、コードのアクセスと更新トークンを交換して、すぐに使用できます。暗黙的なフローと同様に、アクセストークンがすぐに利用できるため、ハイブリッドフローはパフォーマンスに適しています。ただし、トークンは URL で依然として送信され、前述のセキュリティーの脆弱性は引き続き適用されます。

Hybrid フローの利点の 1 つは、更新トークンがアプリケーションで利用できることです。

ハイブリッドフローの場合は、パラメーター flow の値 hybridinit メソッドに渡す必要があります。

keycloak.init({
    flow: 'hybrid'
})

2.2.3. Cordova でのハイブリッドアプリケーション

Keycloak は、Apache Cordova で開発されたハイブリッドモバイルアプリをサポートしています。JavaScript アダプターには、cordova および cordova-native の 2 つのモードがあります。

デフォルトは cordova で、アダプターのタイプが設定されておらず、window.cordova が存在する場合は自動的に選択されます。ログインすると、ユーザーが Red Hat Single Sign-On を操作できる InApp ブラウザー が開き、その後 http://localhost リダイレクトしてアプリに戻ります。このため、管理コンソールのクライアント設定セクションでこの URL を有効な redirect-uri としてホワイトリスト化する必要があります。

このモードの設定は簡単ですが、いくつかの欠点もあります。

  • InApp-Browser はアプリに組み込まれたブラウザーで、電話のデフォルトブラウザーではありません。したがって、設定が異なり、保存されている認証情報は利用できません。
  • 特に複雑な内容をレンダリングする場合は、InApp-Browser も遅くなる可能性があります。
  • このモードを使用する前に、アプリがログインページをレンダリングするブラウザーを完全に制御できるため、アプリがユーザーの資格情報にアクセスできる可能性があるなど、セキュリティ上の懸念事項を考慮する必要があります。そのため、信頼できないアプリの使用は許可しないでください。

この例のアプリ (https://github.com/keycloak/keycloak/tree/master/examples/cordova) で初めてみましょう。

代替モードの cordova-native は別のアプローチを取っています。システムのブラウザーを使用してログインページが開きます。ユーザーが認証されると、ブラウザーは特別な URL を使用してアプリにリダイレクトします。そこから、Red Hat Single Sign-On アダプターは、URL からコードまたはトークンを読み取り、ログインを終了できます。

init メソッドにアダプター型の cordova-native を渡すことで、ネイティブモードを有効できます。

keycloak.init({
    adapter: 'cordova-native'
})

このアダプターには、以下の 2 つのプラグインが必要です。

アプリへのリンクの技術情報は、各プラットフォームや特別な設定によって異なります。詳細は、deeplinks プラグインのドキュメント の Android と iOS のセクションを参照してください。

アプリを開くためのリンクにはさまざまな種類があります。カスタムスキーム (myapp://login または android-app://com.example.myapp/https/example.com/login) と ユニバーサルリンク (iOS)/Deep Links (Android) です。前者はセットアップが簡単で信頼性が高い傾向がありますが、後者は一意であり、ドメインの所有者のみが登録できるため、セキュリティーが強化されます。カスタム URL は iOS で非推奨になりました。最高の信頼性を得るには、ユニバーサルリンクをカスタム URL リンクのあるフォールバックサイトと組み合わせて使用することをお勧めします。

さらに、Keycloak アダプターとの互換性を改善するには、以下の手順が推奨されます。

  • iOS のユニバーサルリンクは、response-modequery に設定すると、より確実に動作するようです。
  • リダイレクト時に Android がアプリの新しいインスタンスを開かないようにするには、次のスニペットを config.xml に追加します。
<preference name="AndroidLaunchMode" value="singleTask" />

ネイティブモードの使い方を示すアプリの例 (https://github.com/keycloak/keycloak/tree/master/examples/cordova-native) があります。

2.2.4. カスタムアダプター

デフォルトでサポートされていない環境で JavaScript クライアントを実行する必要がある場合があります (Capacitor など)。このような不明な環境で JavasScript クライアントを使用できるようにするために、カスタムアダプターを渡すことができます。たとえば、サードパーティーのライブラリーは、このようなアダプターを提供して、問題なく JavaScript クライアントを実行できます。

import Keycloak from 'keycloak-js';
import KeycloakCapacitorAdapter from 'keycloak-capacitor-adapter';

const keycloak = new Keycloak();

keycloak.init({
    adapter: KeycloakCapacitorAdapter,
});

この特定のパッケージは存在しませんが、そのようなアダプターをクライアントに渡す方法に関する適切な例を示すことができます。

独自のアダプターを作成することもできます。そのためには、KeycloakAdapter インターフェースで説明されているメソッドを実装する必要があります。たとえば、以下の TypeScript コードは、すべてのメソッドが適切に実装されていることを確認します。

import Keycloak, { KeycloakAdapter } from 'keycloak-js';

// Implement the 'KeycloakAdapter' interface so that all required methods are guaranteed to be present.
const MyCustomAdapter: KeycloakAdapter = {
    login(options) {
        // Write your own implementation here.
    }

    // The other methods go here...
};

const keycloak = new Keycloak();

keycloak.init({
    adapter: MyCustomAdapter,
});

タイプ情報を省略することで TypeScript を使用せずにこれを実行することもできますが、インターフェースを確実に適切に実装することは、完全にユーザー次第となります。

2.2.5. 以前のブラウザー

JavaScript アダプターは、Base64 (window.btoa および window.atob)、HTML5 History API、およびオプションで Promise API に依存します。これらが利用できないブラウザーをサポートする必要がある場合 (例: IE9) は、polyfillers を追加する必要があります。

ポリフィルライブラリーの例:

2.2.6. 追跡保護機能を備えた最新のブラウザー

一部のブラウザーの最新版では、Chrome の SameSite や完全にブロックされたサードパーティーの cookie など、サードパーティーによるユーザーの追跡を防ぐためにさまざまな cookie ポリシーが適用されています。これらのポリシーは、時間の経過とともにさらに制限され、他のブラウザーによって採用され、最終的にはサードパーティーのコンテキストの cookie が完全にサポートされず、ブラウザーによってブロックされることが予想されます。これの影響を受けるアダプター機能は、今後非推奨となる可能性があります。

JavaScript アダプターは、セッションステータスの iframe、サイレント check-sso、および部分的に通常の (非サイレント) check-sso についても、サードパーティーの cookie に依存しています。これらの機能は、機能が制限されているか、またはブラウザーが cookie に関してどのように制限されているかに基づいて完全に無効になっています。アダプターはこの設定を検出しようとし、それに応じて反応します。

2.2.6.1. 「SameSite=Lax by Default」ポリシーを持つブラウザー

Red Hat Single Sign-On 側およびアプリケーション側で SSL / TLS 接続が設定されている場合、すべての機能がサポートされます。「configuring the SSL / TLS」を参照してください。影響を受けるのは、たとえば、バージョン 84 以降の Chrome などです。

2.2.6.2. サードパーティーの Cookie がブロックされているブラウザー

セッションステータス iframe はサポートされず、このようなブラウザーの動作が JS アダプターによって検出されると自動的に無効になります。これは、アダプターは Single Sign-Out 検出にセッション cookie を使用できず、純粋にトークンに依存する必要があることを意味します。これは、ユーザーが別のウィンドウでログアウトすると、JavaScript アダプターを使用しているアプリケーションは、アクセストークンを更新しようとするまでログアウトされないことを意味します。したがって、アクセストークンの有効期間を比較的短い時間に設定して、ログアウトが後でではなく、早くに検出されるようにすることをお勧めします。「Session and Token Timeouts」を参照してください。

サイレント check-sso はサポートされず、デフォルトで通常の (非サイレント) check-sso にフォールバックします。この動作は、init メソッドに渡されるオプションで silentCheckSsoFallback: false を設定することで変更できます。この場合、制限的なブラウザー動作が検出されると、check-sso は完全に無効になります。

通常の check-sso も影響を受けます。セッションステータス iframe がサポートされていないため、アダプターがユーザーのログインステータスをチェックするために初期化される際に、Red Hat Single Sign-On への追加のリダイレクトを行う必要があります。これは、ユーザーがログインしているかどうかを示すために iframe を使用する標準の動作とは異なり、リダイレクトはログアウト時にのみ実行されます。

影響を受けるブラウザーは、たとえば、バージョン 13.1 以降の Safari などです。

2.2.7. JavaScript アダプターリファレンス

2.2.7.1. コンストラクター

new Keycloak();
new Keycloak('http://localhost/keycloak.json');
new Keycloak({ url: 'http://localhost/auth', realm: 'myrealm', clientId: 'myApp' });

2.2.7.2. プロパティー

authenticated
ユーザが認証されている場合は true、そうでない場合は false です。
token
サービスへのリクエストで Authorization ヘッダーで送ることができる base64 エンコードされたトークン。
tokenParsed
解析されたトークンを JavaScript オブジェクトとして実行します。
subject
ユーザー id
idToken
base64 でエンコードされた ID トークン。
idTokenParsed
解析された id トークンを JavaScript オブジェクトとして実行します。
realmAccess
トークンに関連付けられたレルムロール。
resourceAccess
トークンに関連付けられたリソースロール。
refreshToken
新しいトークンの取得に使用できる base64 でエンコードされた更新トークン。
refreshTokenParsed
JavaScript オブジェクトとして解析された更新トークン。
timeSkew
ブラウザー時間と Red Hat Single Sign-On サーバー間の推定時間 (秒単位)。この値は見積りませんが、トークンの有効期限が切れているかどうかを判断します。
responseMode
init で渡される応答モード (デフォルト値は fragment)。
flow
init に渡されるフロー。
adapter

リダイレクトする方法と、その他のブラウザー関連の機能がライブラリーによって処理される方法を上書きできます。利用可能なオプション:

  • 「default」 - ライブラリーはリダイレクトにブラウザー api を使用します (これがデフォルトです)。
  • 「cordova」 - ライブラリーは InAppBrowser cordova プラグインを使用して keycloak login/registration ページを読み込もうとします (これは、ライブラリーが cordova エコシステムで作業しているときに自動的に使用されます)。
  • 「cordova-native」 - ライブラリーは、BrowserTabs cordova プラグインを使用して、電話のシステムブラウザーを使用してログインおよび登録ページを開くことを試みます。これには、アプリにリダイレクトするための特別な設定が必要です (「Cordova でのハイブリッドアプリケーション」 を参照)。
  • custom - カスタムアダプターを実装することができます (高度なユースケースのみ)。
responseType
ログイン要求で Red Hat Single Sign-On に送信された応答タイプ。これは初期化時に使用されるフロー値に基づいて決定されますが、この値を設定すると上書きできます。

2.2.7.3. メソッド

2.2.7.3.1. init(options)

アダプターを初期化するために呼び出されます。

オプションはオブジェクトです。ここでは、以下のようになります。

  • useNonce - 暗号化ナンスを追加して、認証応答がリクエストと一致することを確認します (デフォルトは true)。
  • onLoad - 読み込み時に実行するアクションを指定します。サポートされている値は、login-required または check-sso です。
  • silentCheckSsoRedirectUri - onLoad が「check-sso」に設定されたかどうかをサイレント認証チェックにリダイレクト URI を設定します。
  • silentCheckSsoFallback: サイレント check-sso がブラウザーでサポートされない場合に、通常の check-sso へのフォールバックを有効にします (デフォルトは true)。
  • token - トークンに初期値を設定します。
  • refreshToken - 更新トークンの初期値を設定します。
  • idToken - id トークンに初期値を設定します (トークンまたは refreshToken とともにのみ)。
  • timeSkew - ローカルタイムと Red Hat Single Sign-On サーバー間のスキュー用に初期値を設定します (トークンと refreshToken の場合のみ)。
  • checkLoginIframe - ログイン状態の監視を有効にするかどうかを設定します (既定値は true)。
  • checkLoginIframeInterval - ログイン状態を確認する間隔を設定します (デフォルトは 5 秒です)。
  • responseMode - ログイン要求時に OpenID Connect 応答モードを Red Hat Single Sign-On サーバーに送信します。有効な値は query または fragment です。デフォルト値は fragment で、認証に成功した後、OpenID Connect パラメーターを URL フラグメントに追加した JavaScript アプリケーションに Red Hat Single Sign-On がリダイレクトすることを意味します。これは一般的には、より安全で、query を介して推奨されています。
  • flow - OpenID Connect フローを設定します。有効な値は、standardimplicit、または hybrid です。
  • enableLogging - Keycloak からコンソールへのログメッセージを有効にします (デフォルトは false です)。
  • pkceMethod - 使用する Proof Key Code Exchange (PKCE) のメソッド。この値を設定すると、PKCE メカニズムが有効になります。利用可能なオプション:

    • 「S256」 - SHA256 ベースの PKCE メソッド
  • messageReceiveTimeout: Keycloak サーバーからのメッセージ応答を待つタイムアウトをミリ秒単位で設定します。これは、たとえば、サードパーティーの Cookie チェック中に、メッセージを待機するときに使用されます。デフォルト値は 10000 です。

初期化の完了時に解決する promise を返します。

2.2.7.3.2. login(options)

ログインフォームにリダイレクトします。

options は任意のオブジェクトです。ここでは、以下のようになります。

  • redirecturi - ログイン後にリダイレクトする URI を指定します。
  • prompt - このパラメーターは、Red Hat Single Sign-On サーバー側でログインフローを若干カスタマイズできるようにします。たとえば、値の login の場合、ログイン画面の表示を強制します。prompt パラメーターの詳細および使用できるすべての値については、「パラメーター転送」セクションを参照してください。
  • maxAge - ユーザーがすでに認証されている場合にのみ使用します。ユーザーの認証が発生した時点の最大時間を指定します。ユーザーが maxAge よりも長い期間認証されている場合、SSO は無視されるため、再認証が必要になります。
  • loginHint - ログインフォームの username/email フィールドを事前に入力するのに使用されます。
  • スコープ - scope パラメーターを Red Hat Single Sign-On ログインエンドポイントに転送するのに使用します。スコープのスペースで区切られたリストを使用します。通常、これらは特定のクライアントで定義される 「クライアントスコープ」 を参照します。スコープの openid は、アダプターによって常にスコープのリストに追加されることに注意してください。例えば、スコープオプションの address phone を入力すると、Red Hat Single Sign-On へのリクエストにはスコープパラメーター scope=openid address phone が含まれます。
  • idpHint - Red Hat Single Sign-On に対して、ログインページの表示を省略し、代わりに指定されたアイデンティティープロバイダーに自動的にリダイレクトするように指示するために使用されます。詳細は、Identity Provider のドキュメント を参照してください。
  • acr: acr 要求についての情報が含まれます。これは、要求パラメーター内で Red Hat Single Sign-On サーバーに送信されます。一般的な用途は、段階的な認証です。使用例: { values: ["silver", "gold"], essential: true }詳細は、OpenID Connect の仕様および「Step-up authentication documentation」を参照してください。
  • action - 値が register の場合、ユーザーは登録ページにリダイレクトされます。値が UPDATE_PASSWORD の場合、ユーザーはリセットパスワードページにリダイレクトされます(認証がない場合、ユーザーは最初にログインページに送信され、認証後にリダイレクトされます)。それ以外の場合は、ログインページにリダイレクトされます。
  • locale - OIDC 1.0 仕様のセクション 3.1.2.1 に従って、「ui_localesクエリーパラメーターを設定します。
  • cordovaOptions - Cordova in-app-browser (該当する場合) に渡される引数を指定します。hidden オプションおよび location オプションは、これらの引数の影響を受けません。利用可能なすべてのオプションはhttps://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/ で定義されています。使用例: { zoom: "no", hardwareback: "yes" };
2.2.7.3.3. createLoginUrl(options)

ログインフォームへの URL を返します。

optionsは任意のオブジェクトで、関数 login と同じオプションをサポートします。

2.2.7.3.4. logout(options)

ログアウトにリダイレクトされます。

オプションはオブジェクトです。ここでは、以下のようになります。

  • redirectUri - ログアウト後にリダイレクトする URI を指定します。
2.2.7.3.5. createLogoutUrl(options)

ユーザーをログアウトするための URL を返します。

オプションはオブジェクトです。ここでは、以下のようになります。

  • redirectUri - ログアウト後にリダイレクトする URI を指定します。
2.2.7.3.6. register(options)

登録フォームにリダイレクトされます。オプション action = 'register' を使用したログインのショートカット

オプションはログイン方法と同じですが、「action」は「register」に設定されています

2.2.7.3.7. createRegisterUrl(options)

登録ページへの URL を返します。オプション action = 'register' を持つ createLoginUrl のショートカット

オプションは createLoginUrl メソッドと同じですが、「action」は「register」に設定されています

2.2.7.3.8. accountManagement()

アカウント管理コンソールにリダイレクトされます。

2.2.7.3.9. createAccountUrl(options)

アカウント管理コンソールに URL を返します。

オプションはオブジェクトです。ここでは、以下のようになります。

  • redirectUri: アプリケーションにリダイレクトする際にリダイレクトする URI を指定します。
2.2.7.3.10. hasRealmRole(role)

トークンに指定のレルムロールがある場合は true を返します。

2.2.7.3.11. hasResourceRole(role, resource)

トークンにリソースの指定されたロールがある場合に true を返します (指定の clientId が使用されていない場合、リソースは任意です)。

2.2.7.3.12. loadUserProfile()

ユーザープロファイルを読み込みます。

プロファイルで解決する promise を返します。

以下に例を示します。

keycloak.loadUserProfile()
    .then(function(profile) {
        alert(JSON.stringify(profile, null, "  "))
    }).catch(function() {
        alert('Failed to load user profile');
    });
2.2.7.3.13. isTokenExpired(minValidity)

トークンの有効期限が切れる前にトークンが minValidity 秒未満の場合は true を返します (minValidityは任意であり、指定されていない場合は 0 が使用されます)。

2.2.7.3.14. updateToken(minValidity)

トークンが minValidity 秒以内に期限切れになると (minValidity は任意で、指定されていない場合は 5 が使用されます)、トークンが更新されます。セッションステータスが iframe が有効になっている場合は、セッションステータスもチェックされます。

トークンが更新されているかどうかを示すブール値で解決する promise を返します。

以下に例を示します。

keycloak.updateToken(5)
    .then(function(refreshed) {
        if (refreshed) {
            alert('Token was successfully refreshed');
        } else {
            alert('Token is still valid');
        }
    }).catch(function() {
        alert('Failed to refresh the token, or the session has expired');
    });
2.2.7.3.15. clearToken()

トークンを含む認証状態を消去します。これは、トークンの更新が失敗した場合など、セッションの期限が切れたことをアプリケーションが検出する場合に役立ちます。

これを呼び出すと、AuthLogout コールバックリスナーが呼び出されます。

2.2.7.4. コールバックイベント

アダプターは、特定のイベントの callback リスナーの設定をサポートします。

以下に例を示します。

keycloak.onAuthSuccess = function() { alert('authenticated'); }

利用可能なイベントは以下のとおりです。

  • onReady(authenticated) - アダプターが初期化されると呼び出されます。
  • onAuthSuccess - ユーザーが正常に認証されると呼び出しされます。
  • onAuthError - 認証中にエラーが発生した場合に呼び出しされます。
  • onAuthRefreshSuccess - トークンの更新時に呼び出しされます。
  • onAuthRefreshError - トークンの更新中にエラーが発生した場合に呼び出します。
  • onAuthLogout - ユーザーがログアウトした場合に呼び出されます (セッションステータス iframe が有効になっている場合、または Cordova モードの場合にのみ呼び出されます)。
  • onTokenExpired - アクセストークンの期限が切れたときに呼び出しされます。更新トークンが利用可能な場合、トークンは updateToken で更新できます。利用できない場合 (つまり暗黙的なフローの場合) は、ログイン画面にリダイレクトして新しいアクセストークンを取得できます。

2.3. Node.js アダプター

Red Hat Single Sign-On は、サーバー側の JavaScript アプリケーションを保護するために Connect 上に構築された Node.js アダプターを提供します。この目的は、Express.js などのフレームワークと統合できる柔軟性があることでした。

Node.js アダプターを使用するには、まず Red Hat Single Sign-On 管理コンソールでアプリケーションのクライアントを作成する必要があります。アダプターは、パブリック、機密、およびベアラーのみのアクセスタイプをサポートします。どちらを選択しても、ユースケースのシナリオにより異なります。

クライアントが作成されたら、Installation タブをクリックして Format OptionRed Hat Single Sign-On OIDC JSON を選択してから Download をクリックします。ダウンロードした keycloak.json ファイルはプロジェクトの root ディレクトリーにあるはずです。

2.3.1. インストールシステム

Node.js がすでにインストールされている場合は、アプリケーションのディレクトリーを作成します。

mkdir myapp && cd myapp

npm init コマンドを使用して、アプリケーションの package.json を作成します。依存関係一覧に Red Hat Single Sign-On の接続アダプターを追加するようになりました。

    "dependencies": {
        "keycloak-connect": "file:keycloak-connect-18.0.0.redhat-00001.tgz"
    }

2.3.2. 用途

Keycloak クラスをインスタンス化します。
Keycloak クラスは、アプリケーションとの設定および統合の中心的な場所を提供します。最も単純な作成には引数は含まれません。

プロジェクトのルートディレクトリーに server.js という名前のファイルを作成し、以下のコードを追加します。

    const session = require('express-session');
    const Keycloak = require('keycloak-connect');

    const memoryStore = new session.MemoryStore();
    const keycloak = new Keycloak({ store: memoryStore });

express-session 依存関係をインストールします。

    npm install express-session

server.js スクリプトを起動するには、package.json の 'scripts' セクションに以下のコマンドを追加します。

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start" "node server.js"
    },

これで、以下のコマンドでサーバーを実行できるようになりました。

    npm run start

デフォルトでは、これはアプリケーションの主な実行ファイルとともに keycloak.json という名前のファイルを見つけ(ここではルートフォルダー)、keycloak 固有の設定を初期化します (公開鍵、レルム名、さまざまな URLなど)。

この場合、Keycloak 管理コンソールにアクセスするためにKeycloak デプロイメントが必要です。

使用して Keycloak 管理コンソールをデプロイする方法については、Podman または Dockerのリンクを参照してください。

これで、Red Hat Single Sign-On Admin Console → clients (左サイドバー) → choose your client → Installation → Format Option → Keycloak OIDC JSON → Download に移動して keycloak.json ファイルを取得できます。

ダウンロードしたファイルをプロジェクトのルートディレクトリーに貼り付けます。

この方法を使用したインスタンス化により、妥当なデフォルトがすべて使用されます。または、keycloak.json ファイルの代わりに、設定オブジェクトを指定することもできます。

    const kcConfig = {
        clientId: 'myclient',
        bearerOnly: true,
        serverUrl: 'http://localhost:8080/auth',
        realm: 'myrealm',
        realmPublicKey: 'MIIBIjANB...'
    };

    const keycloak = new Keycloak({ store: memoryStore }, kcConfig);

アプリケーションは、以下を使用して、ユーザーを優先しているアイデンティティープロバイダーにリダイレクトすることもできます。

    const keycloak = new Keycloak({ store: memoryStore, idpHint: myIdP }, kcConfig);
Web セッションストアの設定
Web セッションを使用して認証のサーバー側の状態を管理する場合は、少なくとも store パラメーターで Keycloak(…​) を初期化し、express-session が使用している実際のセッションストアを渡します。
    const session = require('express-session');
    const memoryStore = new session.MemoryStore();

    // Configure session
    app.use(
      session({
        secret: 'mySecret',
        resave: false,
        saveUninitialized: true,
        store: memoryStore,
      })
    );

    const keycloak = new Keycloak({ store: memoryStore });
カスタムスコープの値の指定
デフォルトでは、スコープ値の openid はクエリーパラメーターとして Red Hat Single Sign-On のログイン URL に渡されますが、さらにカスタム値を追加することができます。
    const keycloak = new Keycloak({ scope: 'offline_access' });

2.3.3. ミドルウェアのインストール

インスタンス化したら、ミドルウェアを接続対応のアプリケーションにインストールします。

これを行うには、まず Express をインストールする必要があります。

    npm install express

次に、以下で説明されているようにプロジェクトに Express が必要になります。

    const express = require('express');
    const app = express();

また、以下のコードを追加して Express で Keycloak ミドルウェアを設定します。

    app.use( keycloak.middleware() );

最後に、以下のコードを main.js に追加して、3000 ポートで HTTP 要求をリッスンするようにサーバーをセットアップしましょう。

    app.listen(3000, function () {
        console.log('App listening on port 3000');
    });

2.3.4. プロキシーの設定

SSL 接続を終了するプロキシーの背後でアプリケーション実行されている場合は、express behind proxies ガイドに従って、Express を設定する必要があります。誤ったプロキシー設定を使用すると、無効なリダイレクト URI が生成されることがあります。

設定例:

    const app = express();

    app.set( 'trust proxy', true );

    app.use( keycloak.middleware() );

2.3.5. 認証の確認

リソースにアクセスする前にユーザーが認証されていることを確認するには、keycloak.checkSso() を使用します。これは、ユーザーがすでにログインしている場合にのみ認証されます。ユーザーがログインしていない場合、ブラウザーは最初のリクエストされた URL にリダイレクトされ、認証されていないままになります。

    app.get( '/check-sso', keycloak.checkSso(), checkSsoHandler );

2.3.6. リソースの保護

簡易認証
リソースにアクセスする前にユーザーを認証する必要があるように強制するには、単に keycloak.protect() の非引数バージョンを使用します。
    app.get( '/complain', keycloak.protect(), complaintHandler );
ロールベースの承認
現在のアプリケーションのアプリケーションロールでリソースのセキュリティーを保護するには、以下を実行します。
    app.get( '/special', keycloak.protect('special'), specialHandler );

のアプリケーションのアプリケーションロールでリソースを保護するには、以下を行います。

    app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler );

レルムロールでリソースをセキュアにするには、以下を実行します。

    app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler );
リソースベースの承認
リソースベースの認証を使用すると、Keycloak で定義された一連のポリシーに基づいて、リソースとその特定のメソッド/アクション ** を保護できるため、アプリケーションからの認証を外部化できます。これは、リソースを保護するために使用できる keycloak.enforcer メソッドを公開することで実現されます。*
    app.get('/apis/me', keycloak.enforcer('user:profile'), userProfileHandler);

keycloak-enforcer メソッドは、response_mode 設定オプションの値に応じて 2 つのモードで動作します。

    app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), userProfileHandler);

response_modetoken に設定されている場合は、アプリケーションに送信されたベアラートークンで表されるサブジェクトの代わりにパーミッションがサーバーから取得されます。この場合、新しいアクセストークンは、サーバーによって付与されたアクセス許可を使用して、Keycloak により発行されます。サーバーが予想されるパーミッションを持つトークンに応答しなかった場合、要求は拒否されます。このモードを使用すると、以下のようにリクエストからトークンを取得できるはずです。

    app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'token'}), function (req, res) {
        const token = req.kauth.grant.access_token.content;
        const permissions = token.authorization ? token.authorization.permissions : undefined;

        // show user profile
    });

アプリケーションがセッションを使用していて、サーバーからの以前の決定をキャッシュし、更新トークンを自動的に処理する場合は、このモードが推奨されます。このモードは、クライアントとリソースサーバーとして動作するアプリケーションに特に便利です。

response_modepermissions (デフォルトモード) に設定されている場合、サーバーは新しいアクセストークンを発行せずに付与されたパーミッションの一覧のみを返します。このメソッドは、新しいトークンを発行しないだけでなく、以下のように リクエスト を介してサーバーに付与されたパーミッションを公開します。

    app.get('/apis/me', keycloak.enforcer('user:profile', {response_mode: 'permissions'}), function (req, res) {
        const permissions = req.permissions;

        // show user profile
    });

使用中の response_mode に関係なく、keycloak.enforcer メソッドは、アプリケーションに送信されたベアラートークン内のパーミッションを確認します。ベアラートークンで予想される権限がすでに引き継がれている場合は、サーバーと対話して意思決定を取得する必要はありません。これは、クライアントが、保護されたリソースにアクセスする前に予想されるパーミッションでサーバーからアクセストークンを取得できる場合に特に便利です。そのため、増分認証などの Keycloak Authorization Services が提供する機能を使用し、keycloak.enforcer がリソースへのアクセスを強制している場合に、サーバーへの追加のリクエストを回避できます。

デフォルトでは、ポリシーエンフォーサーはアプリケーション (例: keycloak.json) に定義された client_id を使用して、Keycloak Authorization Services をサポートする Keycloak のクライアントを参照します。この場合、クライアントは実際にはリソースサーバーであることをパブリックにすることはできません。

アプリケーションがパブリッククライアント (フロントエンド) とリソースサーバー (バックエンド) の両方として機能している場合は、次の構成を使用して、適用するポリシーで Keycloak 内の別のクライアントを参照できます。

      keycloak.enforcer('user:profile', {resource_server_id: 'my-apiserver'})

フロントエンドおよびバックエンドを表すために、Keycloak で個別のクライアントを使用することが推奨されます。

保護するアプリケーションが Keycloak 認証サービスで有効になり、keycloak.json でクライアント認証情報を定義している場合は、サーバーに追加の要求をプッシュして決定のためにポリシーで利用できるようにすることができます。そのため、プッシュする要求と共に JSON を返す 関数 を想定する claims 設定オプションを定義できます。

      app.get('/protected/resource', keycloak.enforcer(['resource:view', 'resource:write'], {
          claims: function(request) {
            return {
              "http.uri": ["/protected/resource"],
              "user.agent": // get user agent  from request
            }
          }
        }), function (req, res) {
          // access granted

Keycloak を設定してアプリケーションリソースを保護する方法の詳細については、Authorization Services Guide を参照してください。

高度な認証
URL 自体の一部に基づいてリソースを保護するには、各セクションにロールが存在することを前提としています。
    function protectBySection(token, request) {
      return token.hasRole( request.params.section );
    }

    app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler );

高度なログイン設定:

デフォルトでは、クライアントがベアラーのみでない限り、承認されていないすべてのリクエストは Red Hat Single Sign-On のログインページにリダイレクトされます。ただし、機密またはパブリッククライアントは、閲覧可能なエンドポイントと API エンドポイントの両方をホストする場合があります。認証されていない API 要求でのリダイレクトを防ぎ、代わりに HTTP 401 を返すようにするには、redirectToLogin 関数をオーバーライドします。

たとえば、このオーバーライドでは URL に /api/ が含まれているかどうかを確認し、ログインリダイレクトを無効にします。

    Keycloak.prototype.redirectToLogin = function(req) {
    const apiReqMatcher = /\/api\//i;
    return !apiReqMatcher.test(req.originalUrl || req.url);
    };

2.3.7. 追加の URL

明示的なユーザーがトリガーされたログアウト
デフォルトでは、ミドルウェアは /logout への呼び出しをキャッチし、Red Hat Single Sign-On 中心のログアウトワークフローを介してユーザーを送信します。これは、logout 設定パラメーターを middleware() 呼び出しに指定することで変更できます。
    app.use( keycloak.middleware( { logout: '/logoff' } ));

ユーザーがトリガーするログアウトが呼び出されると、クエリーパラメーター redirect_url を渡すことができます。

https://example.com/logoff?redirect_url=https%3A%2F%2Fexample.com%3A3000%2Flogged%2Fout

次に、このパラメーターは OIDC ログアウトエンドポイントのリダイレクト URL として使用され、ユーザーは https://example.com/logged/out にリダイレクトされます。

Red Hat Single Sign-On 管理者のコールバック
また、ミドルウェアは、Red Hat Single Sign-On コンソールのコールバックをサポートし、単一のセッションまたはすべてのセッションをログアウトします。デフォルトでは、これらの管理コールバックのタイプは / のルート URL に関連して行われますが、middleware() 呼び出しに admin パラメーターを指定して変更できます。
    app.use( keycloak.middleware( { admin: '/callbacks' } );

2.3.8. 完全な例

Node.js アダプターの完全な使用例は、Node.js のKeycloak クイックスタートにあります。

2.4. その他の OpenID Connect ライブラリー

Red Hat Single Sign-On は、通常、使用が簡単で、Red Hat Single Sign-On との統合を改善できるアダプターによって提供されます。ただし、プログラミング言語、フレームワーク、またはプラットフォームでアダプターが利用できない場合は、代わりに汎用 OpenID Connect Relying Party (RP) ライブラリーを使用することを選択できます。本章では、Red Hat Single Sign-On に固有の詳細を説明します。また、特定のプロトコルの詳細は含まれません。詳細は、「OpenID Connect 仕様」 および 「OAuth2 仕様」 を参照してください。

2.4.1. エンドポイント

理解すべき最も重要なエンドポイントは、よく知られている 設定エンドポイントです。Red Hat Single Sign-On の OpenID Connect 実装に関連するエンドポイントおよびその他の設定オプションを一覧表示します。エンドポイントは次のとおりです。

/realms/{realm-name}/.well-known/openid-configuration

完全な URL を取得するには、Red Hat Single Sign-On のベース URL を追加し、{realm-name} をレルムの名前に置き換えます。以下に例を示します。

http://localhost:8080/auth/realms/master/.well-known/openid-configuration

一部の RP ライブラリーは、このエンドポイントから必要なすべてのエンドポイントを取得しますが、その他のライブラリーでは、エンドポイントを個別に一覧表示しないといけない場合があります。

2.4.1.1. 承認エンドポイント

/realms/{realm-name}/protocol/openid-connect/auth

承認エンドポイントはエンドユーザーの認証を実行します。これは、ユーザーエージェントをこのエンドポイントにリダイレクトすることで行います。

詳細は、OpenID Connect 仕様の「認証エンドポイント」セクションを参照してください。

2.4.1.2. トークンエンドポイント

/realms/{realm-name}/protocol/openid-connect/token

トークンエンドポイントは、トークンの取得に使用されます。トークンは、承認コードを調べるか、使用するフローに応じて認証情報を直接指定して取得できます。トークンエンドポイントは、有効期限が切れたときに新しいアクセストークンの取得にも使用されます。

詳細は、OpenID Connect 仕様の トークンエンドポイント セクションを参照してください。

2.4.1.3. userInfo エンドポイント

/realms/{realm-name}/protocol/openid-connect/userinfo

userinfo エンドポイントは、認証されたユーザーについての標準要求を返し、ベアラートークンによって保護されます。

詳細は、OpenID Connect 仕様の userInfo エンドポイント セクションを参照してください。

2.4.1.4. ログアウトエンドポイント

/realms/{realm-name}/protocol/openid-connect/logout

ログアウトエンドポイントは、認証されたユーザーをログアウトします。

ユーザーエージェントはエンドポイントにリダイレクトできます。この場合は、アクティブなユーザーセッションがログアウトされます。その後、ユーザーエージェントはアプリケーションにリダイレクトされます。

エンドポイントはアプリケーションによって直接呼び出すこともできます。このエンドポイントを直接呼び出すには、更新トークンとクライアントの認証に必要な認証情報を追加する必要があります。

2.4.1.5. 証明書エンドポイント

/realms/{realm-name}/protocol/openid-connect/certs

証明書エンドポイントは、レルムが有効にした公開鍵を返し、JSON Web Key (JWK) としてエンコードされます。レルム設定によっては、トークンの検証に 1 つ以上のキーが有効になります。詳細は、Server Administration Guide および JSON Web Key 仕様 を参照してください。

2.4.1.6. イントロスペクションエンドポイント

/realms/{realm-name}/protocol/openid-connect/token/introspect

イントロスペクションエンドポイントは、トークンのアクティブな状態を取得するために使用されます。つまり、これを使用してアクセストークンを検証したり、更新したりできます。これは、機密クライアントでのみ呼び出すことができます。

このエンドポイントで呼び出す方法の詳細については、「OAuth 2.0 Token Introspection specification」 を参照してください。

2.4.1.7. 動的クライアント登録エンドポイント

/realms/{realm-name}/clients-registrations/openid-connect

動的クライアント登録エンドポイントは、クライアントを動的に登録するのに使用されます。

詳細は、「クライアント登録」および「OpenID 接続動的クライアント登録仕様」の章を参照してください。

2.4.1.8. トークン失効エンドポイント

/realms/{realm-name}/protocol/openid-connect/revoke

トークン失効エンドポイントは、トークンの取り消しに使用されます。このエンドポイントでは、更新トークンとアクセストークンの両方がサポートされます。

このエンドポイントで呼び出す方法の詳細については、「OAuth 2.0 Token Revocation specification」を参照してください。

2.4.1.9. デバイス承認エンドポイント

/realms/{realm-name}/protocol/openid-connect/auth/device

デバイス承認エンドポイントは、デバイスコードとユーザーコードを取得するために使用されます。これは、機密またはパブリッククライアントで呼び出すことができます。

このエンドポイントで呼び出す方法の詳細については、「OAuth 2.0 Device Authorization Grant specification」を参照してください。

2.4.1.10. backchannel 認証エンドポイント

/realms/{realm-name}/protocol/openid-connect/ext/ciba/auth

backchannel 認証エンドポイントは、クライアントによる認証要求を識別する auth_req_id を取得するために使用されます。これは、機密クライアントでのみ呼び出すことができます。

このエンドポイントで呼び出す方法の詳細は、「OpenID Connect Client Initiated Backchannel Authentication Flow specification」を参照してください。

また、本書の「Client Initiated Backchannel Authentication Grant」セクションおよび『Server Administration Guide』の「Client Initiated Backchannel Authentication Grant」セクションなど、Red Hat Single Sign-On ドキュメントの他の部分についても参照してください。

2.4.2. アクセストークンの検証

Red Hat Single Sign-On が発行するアクセストークンを手動で検証する必要がある場合には、イントロスペクションエンドポイント を呼び出すことができます。この方法のマイナス面は、Red Hat Single Sign-On サーバーへのネットワーク呼び出しを行う必要があることです。同時に実行される検証要求が多すぎると、これは遅くなり、サーバーが過負荷になる可能性があります。Red Hat Single Sign-On が発行するアクセストークンは、JSON Web Signature (JWS) を使用してデジタル署名およびエンコードされた JSON Web Tokens (JWT) です。この方法でエンコードされるため、発行したレルムの公開鍵を使用してアクセストークンをローカルで検証できます。レルムの公開鍵を検証コードでハードコードするか、JWS 内に埋め込まれたキー ID (KID) で 証明書エンドポイント を使用して公開鍵を検索してキャッシュします。コーディングする言語に応じて、JWS の検証に役立つサードパーティのライブラリーが多数あります。

2.4.3. フロー

2.4.3.1. 認可コード

Authorization Code フローは、ユーザーエージェントを Red Hat Single Sign-On にリダイレクトします。Red Hat Single Sign-On で正常に認証されたら、承認コードが作成され、ユーザーエージェントはアプリケーションにリダイレクトされます。その後、アプリケーションは認証情報と共に承認コードを使用して、Red Hat Single Sign-On からアクセストークン、更新トークン、および ID トークンを取得します。

フローは Web アプリケーションにターゲットとして設定されていますが、ユーザーエージェントを組み込むことができるモバイルアプリケーションなど、ネイティブアプリケーションに推奨されます。

詳細は、OpenID Connect 仕様の Authorization Code Flow を参照してください。

2.4.3.2. 暗黙的

暗黙的フローリダイレクトは承認コードフローと同じような機能ですが、アクセストークンおよび ID トークンが返される承認コードを返す代わりに、このフローが返されます。これにより、追加の呼び出しでアクセストークンの承認コードを交換する必要がなくなります。ただし、更新トークンは含まれません。その結果、有効期限の長いアクセストークンを許可する必要があります。これは、これらを無効にするのが非常に難しいため、問題があります。または、最初のアクセストークンの期限が切れたら、新しいアクセストークンを取得するために新しいリダイレクトが必要になります。暗黙的フローは、アプリケーションがユーザーを認証し、ログアウト自体を処理する場合に便利です。

また、アクセストークンと承認コードの両方が返されるハイブリッドフローもあります。

注意すべき点の 1 つは、アクセストークンが Web サーバーのログやブラウザーの履歴から漏洩する可能性があるため、暗黙的なフローとハイブリッドフローの両方に潜在的なセキュリティーリスクがあることです。これは、アクセストークンに短い有効期限を使用することでいくらか軽減されます。

詳細については、OpenID Connect 仕様の 「Implicit Flow」を参照してください。

2.4.3.3. リソースオーナーパスワード認証情報

Red Hat Single Sign-On の Direct Grant (Direct Grant) と呼ばれるリソースオーナーパスワード認証情報を使用すると、ユーザー認証情報をトークンと交換できます。絶対に必要な場合を除き、このフローの使用は推奨されません。これは、従来のアプリケーションおよびコマンドラインインターフェースなどで役に立ちます。

このフローの使用には、次のようないくつかの制限があります。

  • ユーザーの認証情報ががアプリケーションに公開される
  • アプリケーションにはログインページが必要です。
  • アプリケーションは認証スキームを認識する必要があります。
  • 認証フローへの変更にはアプリケーションへの変更が必要です。
  • アイデンティティーブローカーまたはソーシャルログインはサポートされません。
  • フロー (ユーザー自己登録、必要なアクションなど) はサポートされません。

クライアントで Resource Owner Password Credentials の使用を許可するには、クライアントに Direct Access Grants Enabled オプションを有効にする必要があります。

このフローは OpenID Connect に含まれず、OAuth 2.0 仕様の一部です。

詳細は、OAuth 2.0 仕様の「Resource Owner Password Credentials Grant」の章を参照してください。

2.4.3.3.1. CURL の使用例

以下の例は、ユーザー名user およびパスワード password を使用して、レルムの master ユーザーのアクセストークンを取得する方法を示しています。この例では、機密クライアント myclient を使用しています。

curl \
  -d "client_id=myclient" \
  -d "client_secret=40cc097b-2a57-4c17-b36a-8fdf3fc2d578" \
  -d "username=user" \
  -d "password=password" \
  -d "grant_type=password" \
  "http://localhost:8080/auth/realms/master/protocol/openid-connect/token"

2.4.3.4. クライアントクレデンシャル

クライアント認証情報は、クライアント (アプリケーションおよびサービス) がユーザーに代わってではなく、自身に代わってアクセスを取得する場合に使用されます。たとえば、特定のユーザーではなく、一般的なシステムに変更を適用するバックグラウンドサービスなどに役立ちます。

Red Hat Single Sign-On は、クライアントが秘密または公開鍵/秘密鍵のいずれかを使用して認証するためのサポートを提供します。

このフローは OpenID Connect に含まれず、OAuth 2.0 仕様の一部です。

詳細は、OAuth 2.0 仕様の「Client Credentials Grant」の章を参照してください。

2.4.3.5. デバイス承認の付与

Device Authorization Grant は、入力機能が制限されているか、または適切なブラウザーがないインターネット接続デバイスで実行されているクライアントによって使用されます。アプリケーションは Red Hat Single Sign-On にデバイスコードとユーザーコードを要求します。Red Hat Single Sign-On は、デバイスコードとユーザーコードを作成します。Red Hat Single Sign-On は、デバイスコードおよびユーザーコードなどの応答をアプリケーションに返します。次に、アプリケーションはユーザーにユーザーコードと検証 URI を提供します。ユーザーは検証 URI にアクセスし、別のブラウザーを使用して認証されます。アプリケーションは、Red Hat Single Sign-On がユーザー承認を完了するまで、Red Hat Single Sign-On を繰り返しポーリングします。ユーザー認証が完了すると、アプリケーションはデバイスコードを取得します。その後、アプリケーションは認証情報と共にデバイスコードを使用して、Red Hat Single Sign-On からアクセストークン、更新トークン、および ID トークンを取得します。

詳細は、OAuth 2.0 Device Authorization Grant specification を参照してください。

2.4.3.6. Client Initiated Backchannel Authentication Grant

Client Initiated Backchannel Authentication Grant は、OAuth 2.0 の認証コード付与のように、ユーザーのブラウザーを介してリダイレクトせずに、OpenID プロバイダーと直接通信することで認証フローを開始するクライアントによって使用されます。

クライアントは、クライアントによる認証要求を識別する auth_req_id を Red Hat Single Sign-On に要求します。Red Hat Single Sign-On は auth_req_id を作成します。

この auth_req_id を受信した後、このクライアントは、ユーザーが認証されるまで、auth_req_id と引き換えに、Red Hat Single Sign-On からアクセストークン、更新トークン、および ID トークンを取得するために Red Hat Single Sign-On を繰り返しポーリングする必要があります。

クライアントが ping モードを使用する場合は、トークンエンドポイントを繰り返しポーリングする必要はありませんが、Red Hat Single Sign-On から指定された Client Notification Endpoint に送信される通知を待つことができます。Client Notification Endpoint は、Red Hat Single Sign-On 管理コンソールで設定できます。Client Notification Endpoint のコントラクトの詳細は、CIBA 仕様を参照してください。

詳細は、OpenID Connect Client Initiated Backchannel Authentication Flow specification を参照してください。

また、本書の「backchannel 認証エンドポイント」および『サーバー管理ガイド』の「Client Initiated Backchannel Authentication Grant」セクションなど、Red Hat Single Sign-On ドキュメントの別の部分についても参照してください。FAPI CIBA コンプライアンスの詳細は、本書の FAPI セクションを参照してください。

2.4.4. リダイレクト URI

リダイレクトベースのフローを使用する場合は、クライアントに有効なリダイレクト URI を使用することが重要です。リダイレクト URI は可能な限り具体的にする必要があります。これは特に、クライアント側の (パブリッククライアント) アプリケーションに適用されます。これを行わないと、以下が発生する可能性があります。

  • オープンリダイレクト - これにより、攻撃者はドメインから来ているように見えるなりすましリンクを作成できます
  • 不正なエントリ - ユーザーがすでに Red Hat Single Sign-Onで認証されている場合、攻撃者は、ユーザーの知らないうちにユーザーをリダイレクトすることでアクセスを取得するようにリダイレクト URI が正しく構成されていないパブリッククライアントを使用できます。

Web アプリケーションで実稼働環境では常にすべてのリダイレクト URI に https を使用します。http へのリダイレクトを許可しないでください。

いくつかの特別なリダイレクト URI もあります。

http://localhost
このリダイレクト URI はネイティブアプリケーションに役立ち、ネイティブアプリケーションは認証コードの取得に使用できるランダムポートで Web サーバーを作成できます。このリダイレクト URI は任意のポートを許可します。
urn:ietf:wg:oauth:2.0:oob
クライアント (またはブラウザーが利用できない) で Web サーバーを起動できない場合は、特別な urn:ietf:wg:oauth:2.0:oob リダイレクト URI を使用できます。このリダイレクト URI を使用すると、Red Hat Single Sign-On は、タイトルとページ上のボックスにコードを含むページを表示します。アプリケーションは、ブラウザーののタイトルが変更されたことを検出するか、ユーザーがコードを手動でアプリケーションにコピーして貼り付けることができます。このリダイレクト URI を使用すると、ユーザーが別のデバイスを使用してアプリケーションに貼り付けるコードを取得することもできます。

2.5. Financial-grade API (FAPI) サポート

Red Hat Single Sign-On を使用すると、管理者はクライアントが以下の仕様に準拠していることを簡単に確認できます。

このコンプライアンスは、Red Hat Single Sign-On サーバーが、これらの仕様に記載されている承認サーバーの要件を検証することを意味します。Red Hat Single Sign-On アダプターには FAPI を特別にサポートしていないため、クライアント (アプリケーション) 側での必要な検証は、引き続き手動で行うか、その他のサードパーティーソリューションを介して実行する必要がある場合があります。

2.5.1. FAPI クライアントプロファイル

クライアントが FAPI に準拠することを確認するには、『Server Administration Guide』の説明に従って、レルムにクライアントポリシーを設定し、そのポリシーを各レルムで自動的に利用できる FAPI サポートのグローバルクライアントプロファイルにリンクします。クライアントが準拠する必要のある FAPI プロファイルに基づいて、fapi-1-baseline または fapi-1-advanced プロファイルのいずれかを使用できます。

Pushed Authorization Request (PAR) を使用する場合は、クライアントが fapi-1-baseline プロファイルおよび fapi-1-advanced の両方を PAR 要求に使用することが推奨されます。具体的には、fapi-1-baseline プロファイルには、pkce-enforcer エグゼキューターが含まれています。これにより、クライアントはセキュリティーで保護された S256 アルゴリズムで PKCE を確実に使用します。これは、PAR 要求を使用しない限り、FAPI Advanced クライアントには必須ではありません。

FAPI に準拠する方法で CIBA を使用する場合は、クライアントが fapi-1-advanced および fapi-ciba クライアントプロファイルの両方を使用していることを確認してください。fapi-ciba プロファイルには CIBA 固有のエクゼキューターのみが含まれるため、fapi-1-advanced プロファイル、または要求されたエクゼキューターを含む他のクライアントプロファイルを使用する必要があります。FAPI CIBA 仕様の要件を実施する場合は、機密クライアントまたは証明書をバインドしたアクセストークンの適用など、より多くの要件が必要になります。

2.5.2. Open Banking Brasil Financial-grade API Security Profile

Red Hat Single Sign-On は、Open Banking Brasil Financial-grade API Security Profile 1.0 Implementers Draft 2 に準拠しています。これは、一部の要件では FAPI 1 Advanced 仕様よりも厳格であるため、一部の要件を適用するには、より厳格な方法で Client Policies を設定する必要がある場合があります。以下の場合は、特にその必要があります。

  • クライアントが PAR を使用しない場合は、暗号化された OIDC 要求オブジェクトが使用されていることを確認してください。これは、Encryption Required を有効にして設定された secure-request-object エグゼキューターを持つクライアントプロファイルを使用して実現できます。
  • JWS の場合は、クライアントが PS256 アルゴリズムを使用していることを確認してください。JWE の場合、クライアントは A256GCMRSA-OAEP を使用する必要がある。これは、これらのアルゴリズムが適用可能なすべての Client Settings で設定する必要がある場合があります。

2.5.3. TLS に関する考慮事項

機密情報が交換されるため、すべての対話は TLS (HTTPS) で暗号化される必要があります。さらに、使用される暗号スイートおよび TLS プロトコルバージョンの FAPI 仕様にはいくつかの要件があります。これらの要件に合致するには、許可された暗号を設定することを検討してください。この設定は、Elytron サブシステムの KEYCLOAK_HOME/standalone/configuration/standalone-*.xml ファイルで実行できます。たとえば、この要素は tlsserver-ssl-contexts の下に追加できます。

<server-ssl-context name="kcSSLContext" want-client-auth="true" protocols="TLSv1.2" \
key-manager="kcKeyManager" trust-manager="kcTrustManager" \
cipher-suite-filter="TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" protocols="TLSv1.2" />

kcKeyManager および kcTrustManager への参照は、対応するキーストアおよびトラストストアを参照します。詳細については、Wildfly Elytron サブシステムのドキュメントを参照してください。また、「Network Setup Section」または「X.509 Authentication Section」などの Red Hat Single Sign-On ドキュメントの他の部分も参照してください。

第3章 SAML を使用したアプリケーションとサービスのセキュア化

本セクションでは、Red Hat Single Sign-On クライアントアダプターまたは汎用 SAML プロバイダーライブラリーを使用して SAML でアプリケーションおよびサービスのセキュリティーを保護する方法を説明します。

3.1. Java アダプター

Red Hat Single Sign-On には、Java アプリケーションのさまざまなアダプターがあります。正しいアダプターの選択は、ターゲットプラットフォームによって異なります。

3.1.1. 汎用アダプターの設定

Red Hat Single Sign-On がサポートする各 SAML クライアントアダプターは、単純な XML テキストファイルで設定できます。これは次のようになります。

<keycloak-saml-adapter xmlns="urn:keycloak:saml:adapter"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="urn:keycloak:saml:adapter https://www.keycloak.org/schema/keycloak_saml_adapter_1_10.xsd">
    <SP entityID="http://localhost:8081/sales-post-sig/"
        sslPolicy="EXTERNAL"
        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
        logoutPage="/logout.jsp"
        forceAuthentication="false"
        isPassive="false"
        turnOffChangeSessionIdOnLogin="false"
        autodetectBearerOnly="false">
        <Keys>
            <Key signing="true" >
                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                    <PrivateKey alias="http://localhost:8080/sales-post-sig/" password="test123"/>
                    <Certificate alias="http://localhost:8080/sales-post-sig/"/>
                </KeyStore>
            </Key>
        </Keys>
        <PrincipalNameMapping policy="FROM_NAME_ID"/>
        <RoleIdentifiers>
            <Attribute name="Role"/>
        </RoleIdentifiers>
        <RoleMappingsProvider id="properties-based-role-mapper">
            <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
        </RoleMappingsProvider>
        <IDP entityID="idp"
             signaturesRequired="true">
        <SingleSignOnService requestBinding="POST"
                             bindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    />

            <SingleLogoutService
                    requestBinding="POST"
                    responseBinding="POST"
                    postBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    redirectBindingUrl="http://localhost:8081/auth/realms/demo/protocol/saml"
                    />
            <Keys>
                <Key signing="true">
                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                        <Certificate alias="demo"/>
                    </KeyStore>
                </Key>
            </Keys>
        </IDP>
     </SP>
</keycloak-saml-adapter>

これらの設定スイッチの一部はアダプター固有で、一部の設定がすべてのアダプターで共通となる場合があります。Java アダプターでは、システムプロパティーの置き換えとして ${…​} エンクロージャーを使用できます。たとえば ${jboss.server.config.dir} になります。

3.1.1.1. SP 要素

SP 要素属性の説明は次のとおりです。

<SP entityID="sp"
    sslPolicy="ssl"
    nameIDPolicyFormat="format"
    forceAuthentication="true"
    isPassive="false"
    keepDOMAssertion="true"
    autodetectBearerOnly="false">
...
</SP>
entityID
これは、このクライアントの ID です。IdP では、クライアントが通信しているユーザーを判別するためにこの値が必要です。この設定は 必須 です。
sslPolicy
これは、アダプターが強制する SSL ポリシーです。有効な値は ALLEXTERNAL、および NONE です。ALL の場合、すべてのリクエストは HTTPS 経由で受信する必要があります。EXTERNAL の場合、非プライベート IP アドレスのみが HTTPS 経由で有線を通過する必要があります。NONE の場合、HTTPS 経由のリクエストはありません。この設定は 任意 です。デフォルト値は EXTERNAL です。
nameIDPolicyFormat
SAML クライアントは、特定の NameID Subject 形式を要求できます。特定の形式が必要な場合は、この値を入力します。標準の SAML 形式の識別子である urn:oasis:names:tc:SAML:2.0:nameid-format:transient ある必要があります。この設定は 任意 です。デフォルトでは、特別な形式は要求されません。
forceAuthentication
SAML クライアントは、ユーザーが IdP にすでにログインしていても、再認証することをリクエストできます。有効にするには、これを true に設定します。この設定は 任意 です。デフォルト値は false です。
isPassive
SAML クライアントは、IdP にログインしていない場合でも、ユーザーの認証が要求されないように要求できます。必要に応じてこれを true に設定します。forceAuthentication は逆の設定なので、一緒に使用しないでください。この設定は 任意 です。デフォルト値は false です。
turnOffChangeSessionIdOnLogin
セッション ID は、一部のプラットフォームで正常にログインしてセキュリティー攻撃ベクトルをプラグインするためにデフォルトで変更されます。これを無効にするには、これを true に変更します。オフにしないことが推奨されます。デフォルト値は false です。
autodetectBearerOnly
アプリケーションが Web アプリケーションと Web サービス (例: SOAP または REST) の両方に対応する場合は、true に設定する必要があります。Web アプリケーションの認証されていないユーザーを Red Hat Single Sign-On ログインページにリダイレクトできますが、認証されていない SOAP または REST クライアントに HTTP 401 ステータスコードを送信することができます。ログインページへのリダイレクトは理解できません。Red Hat Single Sign-On は、X-Requested-WithSOAPAction、または Accept などの一般的なヘッダーに基づいて SOAP クライアントまたは REST クライアントを自動検出します。デフォルト値は false です。
logoutPage
これにより、ログアウト後に表示するページが設定されます。ページが http://web.example.com/logout.html などの完全な URL の場合、ユーザーは HTTP 302 ステータスコードを使用してログアウト後にそのページにリダイレクトされます。スキーム部分のないリンク (例: /logout.jsp)が指定されると、web.xml の security-constraint 宣言に従って保護領域に存在するかどうかに関係なく、ログアウトの後にページが表示され、ページがデプロイメントコンテキストルートとの関連で解決されます。
keepDOMAssertion
この属性は true に設定して、要求に関連付けられた SamlPrincipal 内の元の形式でアダプターストアにアサーションの DOM 表現を設定します。アサーションドキュメントは、プリンシパル内の getAssertionDocument メソッドを使用して取得できます。これは、署名済みアサーションの再生時に特に便利です。返されるドキュメントは、Red Hat Single Sign-On サーバーが受信した SAML 応答を解析して生成されたドキュメントです。この設定は 任意 で、デフォルト値は false です (ドキュメントはプリンシパルに保存されません)。

3.1.1.2. サービスプロバイダーキーおよびキー要素

IdP で、クライアントアプリケーション (または SP) がすべての要求に署名するか、IdP がアサーションを暗号化する場合は、これを実行するために使用するキーを定義する必要があります。クライアント署名のドキュメントでは、ドキュメントの署名に使用される秘密鍵、および公開鍵または証明書の両方を定義する必要があります。暗号化の場合は、復号に使用する秘密鍵のみを定義する必要があります。

キーを記述する方法は 2 つあります。キーは Java KeyStore 内に格納することも、PEM 形式の keycloak-saml.xml にキーを直接コピー/貼り付けることもできます。

        <Keys>
            <Key signing="true" >
               ...
            </Key>
        </Keys>

Key 要素には、2 つの任意の属性の signing および encryption があります。true に設定すると、これらはアダプターにキーの使用目的を通知します。両方の属性が true に設定されていると、キーはドキュメントの署名と暗号化されたアサーションの復号の両方に使用されます。少なくとも 1 つの属性を true に設定する必要があります。

3.1.1.2.1. キーストア要素

Key 要素内で、Java Keystore から鍵と証明書を読み込みます。これは KeyStore 要素内で宣言されます。

        <Keys>
            <Key signing="true" >
                <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                    <PrivateKey alias="myPrivate" password="test123"/>
                    <Certificate alias="myCertAlias"/>
                </KeyStore>
            </Key>
        </Keys>

以下は、KeyStore 要素で定義されている XML 設定属性です。

file
キーストアへのファイルパス。このオプションは 任意 です。file または resource 属性を設定する必要があります。
resource
KeyStore への WAR リソースパス。これは、ServletContext.getResourceAsStream() へのメソッド呼び出しで使用されるパスです。このオプションは 任意 です。file または resource 属性を設定する必要があります。
password
KeyStore のパスワード。このオプションは 必須 です。

SP がドキュメントの署名に使用するキーを定義する場合は、Java KeyStore 内の秘密鍵および証明書への参照も指定する必要があります。上記の例の PrivateKey および Certificate 要素は、キーストア内のキーまたは証明書を参照する エイリアス を定義します。キーストアには、秘密鍵にアクセスするために追加のパスワードが必要です。PrivateKey 要素で、password 属性内にこのパスワードを定義する必要があります。

3.1.1.2.2. キーの PEMS

Key 要素内で、PrivateKeyPemPublicKeyPemおよび CertificatePem のサブ要素を使用して、キーと証明書を直接宣言します。これらの要素に含まれる値は PEM キー形式に準拠する必要があります。通常、openssl または同様のコマンドラインツールを使用してキーを生成する場合は、このオプションを使用します。

<Keys>
   <Key signing="true">
      <PrivateKeyPem>
         2341251234AB31234==231BB998311222423522334
      </PrivateKeyPem>
      <CertificatePem>
         211111341251234AB31234==231BB998311222423522334
      </CertificatePem>
   </Key>
</Keys>

3.1.1.3. SP PrincipalNameMapping 要素

この要素は任意です。HttpServletRequest.getUserPrincipal() などのメソッドから取得する Java Principal オブジェクトを作成する場合は、Principal.getName() メソッドによって返される名前を定義できます。

<SP ...>
  <PrincipalNameMapping policy="FROM_NAME_ID"/>
</SP>

<SP ...>
  <PrincipalNameMapping policy="FROM_ATTRIBUTE" attribute="email" />
</SP>

policy 属性は、この値に設定するために使用されるポリシーを定義します。この属性に使用できる値は次のとおりです。

FROM_NAME_ID
このポリシーは SAML サブジェクト値を使用するだけです。これはデフォルト設定です。
FROM_ATTRIBUTE
これにより、サーバーから受信した SAML アサーションで宣言された属性のいずれかから値をプルします。XML 属性 attribute 内で使用する SAML の assertion 属性の名前を指定する必要があります。

3.1.1.4. RoleIdentifiers 要素

RoleIdentifiers 要素は、ユーザーから受け取ったアサーション内の SAML 属性を、ユーザーの Jakarta EE Security Context 内のロール識別子として使用する必要があります。

<RoleIdentifiers>
     <Attribute name="Role"/>
     <Attribute name="member"/>
     <Attribute name="memberOf"/>
</RoleIdentifiers>

デフォルトでは、Role 属性値は Jakarta EE ロールに変換されます。一部の IdP は、member または memberOf 属性アサーションを使用してロールを送信します。1 つ以上の Attribute 要素を定義して、ロールに変換する必要のある SAML 属性を指定できます。

3.1.1.5. RoleMappingsProvider 要素

RoleMappingsProvider は、SAML アダプターによって使用される SPI 実装 org.keycloak.adapters.saml.RoleMappingsProvider の ID および設定を許可するオプションの要素です。

Red Hat Single Sign-On が IDP として使用されると、ビルドされたロールマッパーを使用して、ロールを SAML アサーションに追加する前にマッピングできます。ただし、SAML アダプターを使用して、SAML リクエストをサードパーティの IDP に送信するびに使用できます。この場合は、SP の必要に応じてアサーションから展開されたロールを異なるロールセットにマッピングすることが必要になる場合があります。RoleMappingsProvider SPI は、必要なマッピングを実行するのに使用できるプラグ可能なロールマッパーの設定を可能にします。

プロバイダーの設定は以下のようになります。

...
<RoleIdentifiers>
    ...
</RoleIdentifiers>
<RoleMappingsProvider id="properties-based-role-mapper">
    <Property name="properties.resource.location" value="/WEB-INF/role-mappings.properties"/>
</RoleMappingsProvider>
<IDP>
    ...
</IDP>

id 属性は、使用するインストール済みプロバイダーを特定します。Property サブ要素は複数回使用してプロバイダーの設定プロパティーを指定できます。

3.1.1.5.1. プロパティーベースのロールマッピングプロバイダー

Red Hat Single Sign-On には、properties ファイルを使用してロールマッピングを実行する RoleMappingsProvider 実装が含まれています。このプロバイダーは id properties-based-role-mapper によって識別され、org.keycloak.adapters.saml.PropertiesBasedRoleMapper クラスによって実装されます。

このプロバイダーは、使用される properties ファイルの場所を指定するために使用できる 2 つの設定プロパティーに依存します。最初に、設定値を使用して、ファイルシステムで properties ファイルを見つけることで、properties.file.location プロパティーが指定されているかどうかを確認します。設定したファイルが見つからない場合、プロバイダーは RuntimeException を出力します。以下のスニペットは、properties.file.configuration オプションを使用して、ファイルシステムの /opt/mappers/ ディレクトリーから roles.properties ファイルを読み込むプロバイダーの例を示しています。

    <RoleMappingsProvider id="properties-based-role-mapper">
        <Property name="properties.file.location" value="/opt/mappers/roles.properties"/>
    </RoleMappingsProvider>

properties.file.location 設定が設定されていない場合、プロバイダーは properties.resource.location プロパティーをチェックし、設定した値を使用して WAR リソースから properties ファイルを読み込みます。この設定プロパティーがない場合、プロバイダーはデフォルトで /WEB-INF/role-mappings.properties からファイルを読み込もうとします。リソースからファイルを読み込めない場合、プロバイダーは RuntimeException を出力します。以下のスニペットは、properties.resource.location を使用してアプリケーションの /WEB-INF/conf/ ディレクトリーから roles.properties ファイルを読み込むプロバイダーの例を示しています。

    <RoleMappingsProvider id="properties-based-role-mapper">
        <Property name="properties.resource.location" value="/WEB-INF/conf/roles.properties"/>
    </RoleMappingsProvider>

properties ファイルには、ロールとプリンシパルの両方をキーとして含めることができ、0 つ以上のロールを値としてコンマで区切ります。呼び出されると、実装はアサーションから抽出したロールのセットを繰り返し処理し、各ロールについて、マッピングが存在するかどうかを確認します。ロールが空ロールにマップする場合、これは破棄されます。1 つ以上の異なるロールのセットにマップすると、これらのロールは結果セットに設定されます。ロールのマッピングが見つからない場合は、結果セットに組み込まれます。

ロールの処理後、アサーションから抽出したプリンシパルにエントリーの properties ファイルが含まれるかどうかを確認します。プリンシパルのマッピングが存在する場合は、値として一覧表示されるすべてのロールが結果セットに追加されます。これにより、追加のロールをプリンシパルに割り当てることができます。

たとえば、プロバイダーが以下のプロパティーファイルで設定されていると仮定します。

roleA=roleX,roleY
roleB=

kc_user=roleZ

プリンシパル kc_user が、roleAroleB、および roleC があるアサーションから抽出されると、プリンシパルに割り当てられたロールの最終セットは roleCroleXroleY、および roleZ になります。なぜなら roleAroleX および roleY にマッピングされ、roleB が空のロールにマッピングされて破棄され、roleC がそのまま使用され、追加ロールが kc_user プリンシパル (roleZ) に追加されるためです。

注記: マッピングのロール名にスペースを使用するには、Unicode の空白文字を使用してください。たとえば、受信した「ロール A」は以下のように表示されます。

role\u0020A=roleX,roleY
3.1.1.5.2. 独自のロールマッピングプロバイダーの追加

カスタムロールマッピングプロバイダーを追加するには、単に org.keycloak.adapters.saml.RoleMappingsProvider SPI を実装する必要があります。詳細は、『Server Developer Guide』の「SAML Role Mappings SPI」セクションを参照してください。

3.1.1.6. IDP 要素

IDP 要素のすべては、SP が通信しているアイデンティティープロバイダー (認証トークン) の設定を記述します。

<IDP entityID="idp"
     signaturesRequired="true"
     signatureAlgorithm="RSA_SHA1"
     signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
...
</IDP>

以下は、IDP 要素宣言内で指定できる属性設定オプションです。

entityID
これは IDP の発行者 ID です。この設定は 必須 です。
signaturesRequired
true に設定すると、クライアントアダプターは IDP に送信するすべてのドキュメントに署名します。また、クライアントは IDP が送信されたドキュメントに署名されることを想定します。このスイッチは、すべての要求および応答タイプのデフォルトを設定しますが、後でこのタイプを詳細に制御できることがわかります。この設定は 任意 で、デフォルトは false に設定されます。
signatureAlgorithm
これは、IDP により署名されたドキュメントで使用することが必要な署名アルゴリズムです。使用できる値は、RSA_SHA1RSA_SHA256RSA_SHA512、および DSA_SHA1 です。この設定は 任意 で、デフォルト値は RSA_SHA256 です。
signatureCanonicalizationMethod
これは、IDP により署名されたドキュメントで使用することが必要な署名の正規化方法です。この設定は 任意 です。デフォルト値は http://www.w3.org/2001/10/xml-exc-c14n# で、大抵の IDP に適しています。
metadataUrl
IDP メタデータの取得に使用される URL。現在、これは署名キーと暗号化キーを定期的に取得するためにのみ使用され、SP 側で手動で変更することなく IDP でこれらのキーを循環させることができます。

3.1.1.7. IDP AllowedClockSkew サブ要素

AllowedClockSkew オプションの sub 要素は、IDP と SP の間で許可されるクロックの skew を定義します。デフォルト値は 0 です。

<AllowedClockSkew unit="MILLISECONDS">3500</AllowedClockSkew>
unit
この要素の値に割り当てられた時間単位を定義することができます。使用できる値は MICROSECONDS、MILLISECONDS、MINUTES、NANOSECONDS、および SECONDS です。これは 任意 です。デフォルト値は SECONDS です。

3.1.1.8. IDP SingleSignOnService サブ要素

サブ要素 SingleSignOnService は、IDP のログイン SAML エンドポイントを定義します。クライアントアダプターは、ログイン時にこの要素内の設定を介してフォーマットされた IDP に要求を送信します。

<SingleSignOnService signRequest="true"
                     validateResponseSignature="true"
                     requestBinding="post"
                     bindingUrl="url"/>

この要素で定義できる config 属性を以下に示します。

signRequest
クライアントは認証要求に署名する必要がありますか?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateResponseSignature
クライアントは、IDP が auhtn 要求から返送されたアサーション応答ドキュメントに署名することを期待する必要がありますか?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
requestBinding
これは IDP との通信に使用される SAML バインディングタイプです。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
responseBinding
SAML を使用すると、クライアントは、認証応答で使用するバインディングタイプを要求できます。値は POST または REDIRECT です。この設定は 任意 です。デフォルトでは、クライアントは応答用に特定のバインディングタイプを要求しません。
assertionConsumerServiceUrl
IDP ログインサービスが応答を送信する必要がある Assertion Consumer Service (ACS) のURL。この設定は 任意 です。デフォルトでは、IdP の設定に依存するため、これは未設定です。設定した場合は、/saml (例: http://sp.domain.com/my/endpoint/for/saml) で終了する必要があります。このプロパティーの値は SAML AuthnRequest メッセージの AssertionConsumerServiceURL 属性で送信されます。通常、このプロパティーには responseBinding 属性が伴います。
bindingUrl
これは、クライアントが要求を送信する IDP ログインサービスの URL です。この設定は 必須 です。

3.1.1.9. IDP SingleLogoutService サブ要素

サブ要素 SingleLogoutService は、IDP のログアウト SAML エンドポイントを定義します。クライアントアダプターは、ログアウト時にこの要素内の設定を介してフォーマットされた IDP に要求を送信します。

<SingleLogoutService validateRequestSignature="true"
                     validateResponseSignature="true"
                     signRequest="true"
                     signResponse="true"
                     requestBinding="redirect"
                     responseBinding="post"
                     postBindingUrl="posturl"
                     redirectBindingUrl="redirecturl">
signRequest
クライアントは、IDP に対して行うログアウト要求に署名する必要がありますか?この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
signResponse
クライアントが、IDP 要求に送信するログアウト応答に署名する必要があるかどうか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateRequestSignature
クライアントが、IDP からの署名済みログアウト要求ドキュメントを期待する必要があるかどうか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
validateResponseSignature
クライアントが、IDPからの署名済みログアウト応答ドキュメントを期待する必要があるか。この設定は 任意 です。デフォルトは、任意の IDP の signaturesRequired 要素の値に設定されます。
requestBinding
これは、IDP への SAML 要求の通信に使用される SAML バインディングタイプです。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
responseBinding
これは、IDP への SAML 応答の通信に使用される SAML バインディングタイプです。値は POST または REDIRECT です。この設定は 任意 です。デフォルト値は POST ですが、REDIRECT に設定することもできます。
postBindingUrl
これは、POST バインディングの使用時に IDP のログアウトサービスの URL です。この設定は、POST バインディングを使用する場合に 必須 になります。
redirectBindingUrl
これは、REDIRECT バインディングの使用時に IDP のログアウトサービスの URL です。この設定は、REDIRECT バインディングを使用する場合に 必須 になります。

3.1.1.10. IDP キーサブ要素

IDP のキーサブ要素は、IDP によって署名されたドキュメントの検証に使用する証明書またはパブリックキーの定義にのみ使用されます。これは、SP の Keys 要素 と同じ方法で定義されます。ただし、証明書または公開鍵参照を定義するだけで十分です。IDP と SP の両方が Red Hat Single Sign-On サーバーおよびアダプターによって実現される場合、署名の検証にキーを指定する必要はありません。以下を参照してください。

SP と IDP の両方が Red Hat Single Sign-On によって実装されている場合、公開された証明書から IDP 署名検証用の公開鍵を自動的に取得するように SP を設定することができます。これは、キーサブ要素の署名検証キーの宣言をすべて削除することによって行われます。キーサブ要素が空のままになる場合は、完全に省略できます。次に、キーは SP により SAML 記述子から自動的に取得されます。これは、「IDP SingleSignOnService サブ要素」 で指定された SAML エンドポイント URL から派生します。SAML 記述子取得に使用される HTTP クライアントの設定は、通常、追加設定は必要ありませんが、IDP HttpClient サブ要素 で設定することもできます。

署名の検証に複数のキーを指定することもできます。これは、signing 属性が true に設定されている Keys サブ要素内で複数の Key 要素を宣言することによって行われます。これは、IDP 署名鍵がローテートされる場合などに便利です。通常、新しい SAML プロトコルメッセージとアサーションが新しいキーで署名される際に移行期間がありますが、以前のキーで署名されたものは引き続き受け入れる必要があります。

署名検証用のキーの自動取得および追加の静的署名検証キーの定義の両方を行うように Red Hat Single Sign-On を設定することはできません。

       <IDP entityID="idp">
            ...
            <Keys>
                <Key signing="true">
                    <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
                        <Certificate alias="demo"/>
                    </KeyStore>
                </Key>
            </Keys>
        </IDP>

3.1.1.11. IDP HttpClient サブ要素

HttpClient オプションのサブ要素は、enabled の場合に、IDP の SAML 記述子で IDP 署名検証用の公開鍵を含む証明書を自動的に取得するために使用される HTTP クライアントのプロパティーを定義します。

<HttpClient connectionPoolSize="10"
            disableTrustManager="false"
            allowAnyHostname="false"
            clientKeystore="classpath:keystore.jks"
            clientKeystorePassword="pwd"
            truststore="classpath:truststore.jks"
            truststorePassword="pwd"
            proxyUrl="http://proxy/"
            socketTimeout="5000"
            connectionTimeout="6000"
            connectionTtl="500" />
connectionPoolSize
この設定オプションでは、Red Hat Single Sign-On サーバーへプールする接続の数を定義します。これは 任意 です。デフォルト値は 10 です。
disableTrustManager
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合は、トラストストアを指定する必要はありません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を無効にするため、実稼働環境では 使用しないで ください。これは 任意 です。デフォルト値は false です。
allowAnyHostname
Red Hat Single Sign-On サーバーに HTTPS が必要で、この設定オプションが true に設定されている場合、Red Hat Single Sign-On サーバーの証明書はトラストストア経由で検証されますが、ホスト名の検証は行われません。この設定は開発時のみ使用してください。これは SSL 証明書の検証を一部無効にするため、実稼働環境では 使用しないで ください。この設定は、テスト環境で役に立ちます。これは 任意 です。デフォルト値は false です。
truststore
値は、トラストストアファイルへのファイルパスです。classpath: でパスを接頭辞にすると、代わりにデプロイメントのクラスパスからトラストストアが取得されます。Red Hat Single Sign-On サーバーへの送信 HTTPS 通信に使用されます。HTTPS 要求を実行するクライアントでは、通信先のサーバーのホストを確認する方法が必要です。これは、トラストストアが行なうことです。キーストアには、1 つ以上の信頼できるホスト証明書または認証局が含まれます。Red Hat Single Sign-On サーバーの SSL キーストアの公開証明書を抽出して、このトラストストアを作成できます。これは、disableTrustManagertrue でない限り 必須 になります。
truststorePassword
トラストストアのパスワード。これは、トラストストア が設定され、トラストストアにパスワードが必要な場合は 必須 になります。
clientKeystore
これはキーストアファイルに対するファイルパスです。このキーストアには、アダプターが Red Hat Single Sign-On サーバーに対して HTTPS を要求する際に双方向 SSL のクライアント証明書が含まれます。これは 任意 です。
clientKeystorePassword
クライアントキーストアおよびクライアントの鍵のパスワード。これは、clientKeystore が設定されている場合は REQUIRED になります。
proxyUrl
HTTP 接続に使用する HTTP プロキシーの URL。これは 任意 です。
socketTimeout
接続の確立後にデータを待つソケットのタイムアウト (ミリ秒単位)。2 つのデータパケット間の最長の非アクティブ時間。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connectionTimeout
リモートホストとの接続を確立するためのタイムアウト (ミリ秒単位)。タイムアウト値 0 は無限のタイムアウトとして解釈されます。負の値は未定義として解釈されます (該当する場合はシステムのデフォルト)。デフォルト値は -1 です。これは 任意 です。
connectionTtl
クライアント向けの接続 Time to Live (TTL) (ミリ秒単位)。ゼロ以下の値は、無限の値として解釈されます。デフォルト値は -1 です。これは 任意 です。

3.1.2. JBoss EAP アダプター

JBoss EAP にデプロイされた WAR アプリケーションのセキュリティーを保護できるようにするには、Red Hat Single Sign-On アダプターサブシステムをインストールおよび設定する必要があります。

次に、WAR で keycloak 設定ファイル /WEB-INF/keycloak-saml.xml を指定し、auth-method を web.xml 内の Keycloak-SAML に変更します。

ZIP ファイルまたは RPM を使用してアダプターをインストールします。

3.1.3. ZIP ファイルからのアダプターのインストール

各アダプターは、Red Hat Single Sign-On のダウンロードサイトの個別ダウンロードです。

手順

  1. Downloads サイトからアプリケーションサーバーに適用されるアダプターをインストールします。

    • JBoss EAP 7.x にインストールします。

      $ cd $EAP_HOME
      $ unzip rh-sso-saml-eap7-adapter.zip
    • JBoss EAP 6.x にインストールします。

      $ cd $EAP_HOME
      $ unzip rh-sso-saml-eap6-adapter.zip

      これらの ZIP ファイルは、JBoss EAP ディストリビューション内に JBoss EAP SAML アダプターに固有の新しい JBoss モジュールを作成します。

  2. CLI スクリプトを使用して、アプリケーションサーバーのサーバー設定 (domain.xml または standalone.xml) 内で Red Hat Single Sign-On SAML サブシステムを有効にします。

    サーバーを起動し、アプリケーションサーバーに適用するスクリプトを実行します。

    • JBoss EAP 7.1 以降の場合は、このコマンドを使用します。

      $ cd $JBOSS_HOME
      $ ./bin/jboss-cli.sh -c --file=bin/adapter-elytron-install-saml.cli
    • JBoss EAP 7.0 および EAP 6.4の場合は、このコマンドを使用します。

      $ cd $JBOSS_HOME
      $ ./bin/jboss-cli.sh -c --file=bin/adapter-install-saml.cli
      注記

      JBoss EAP 7.1 以上でも従来の非 Elytron アダプターを使用できます。つまり、これらのバージョンでも adapter-install-saml.cli を使用できます。ただし、新しい Elytron アダプターを使用することが推奨されます。

      スクリプトは、以下に説明するように、拡張機能、サブシステム、およびオプションの security-domain を追加します。

<server xmlns="urn:jboss:domain:1.4">

    <extensions>
        <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
          ...
    </extensions>

    <profile>
        <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1"/>
         ...
    </profile>

セキュアな Web 層で作成されたセキュリティーコンテキストを、呼び出している EJB (他の EE コンポーネント) に伝播する必要がある場合には、keycloak セキュリティードメインを EJB およびその他のコンポーネントと併用する必要があります。それ以外の場合、この設定は任意です。

<server xmlns="urn:jboss:domain:1.4">
 <subsystem xmlns="urn:jboss:domain:security:1.2">
    <security-domains>
...
      <security-domain name="keycloak">
         <authentication>
           <login-module code="org.keycloak.adapters.jboss.KeycloakLoginModule"
                         flag="required"/>
          </authentication>
      </security-domain>
    </security-domains>

セキュリティーコンテキストは EJB 階層に自動的に伝播されます。

3.1.3.1. JBoss SSO

JBoss EAP は、同じ JBoss EAP インスタンスにデプロイされた web アプリケーションに対するシングルサインオンのサポートが組み込まれています。これは、Red Hat Single Sign-On を使用する場合に有効にしないでください。

3.1.3.2. JSESSIONID cookie の SameSite 値の設定

ブラウザーは、cookie の SameSite 属性の値を Lax に設定することを計画しています。この設定は、リクエストが同じドメインにある場合にのみ、cookie がアプリケーションに送信されることを意味します。この動作は SAML POST バインディングに影響を与える可能性があり、機能しなくなる可能性があります。SAML アダプターのすべての機能を保持するには、コンテナーによって作成された JSESSIONID クッキーの SameSite の値を None に設定することを推奨します。このように設定しないと、Red Hat Single Sign-On へのリクエストごとに、コンテナーのセッションがリセットされる可能性があります。

注記

SameSite 属性を None に設定しないようにするには、許容できる場合は REDIRECT バインディングに切り替えるか、この回避策が不要な場合は OIDC プロトコルに切り替えることを検討してください。

Wildfly/EAP の JSESSIONID cookie の SameSite 値を None に設定するには、以下の内容の undertow-handlers.conf ファイルをアプリケーションの WEB-INF ディレクトリーに追加します。

samesite-cookie(mode=None, cookie-pattern=JSESSIONID)

この設定のサポートは、バージョン 19.1.0 以降の Wildfly で利用可能です。

3.1.4. RPM からの JBoss EAP 7 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

前提条件

RPM から EAP 7 アダプターをインストールする前に、JBoss EAP 7 リポジトリーにサブスクライブする必要があります。

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。

    Red Hat Enterprise Linux 6、7 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-7-for-rhel-<RHEL_VERSION>-server-rpms

    Red Hat Enterprise Linux 8 の場合: Red Hat Subscription Manager を使用して、以下のコマンドで JBoss EAP 7.4 リポジトリーにサブスクライブします。

    $ sudo subscription-manager repos --enable=jb-eap-7.4-for-rhel-8-x86_64-rpms --enable=rhel-8-for-x86_64-baseos-rpms --enable=rhel-8-for-x86_64-appstream-rpms

手順

  1. Red Hat Enterprise Linux のバージョンに応じて SAML の EAP 7 アダプターをインストールします。

    • Red Hat Linux 7 へのインストール

      $ sudo yum install eap7-keycloak-saml-adapter-sso7_5
    • Red Hat Enterprise Linux 8 へのインストール

      $ sudo dnf install eap7-keycloak-adapter-sso7_5
      注記

      RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap7/root/usr/share/wildfly です。

  2. SAML モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli

インストールが完了しました。

3.1.5. RPM からの JBoss EAP 6 アダプターのインストール

注記

Red Hat Enterprise Linux 7 では、チャンネル という用語はリポジトリーという用語に置き換えられました。これらの手順では、リポジトリーという用語のみが使用されています。

前提条件

RPM から EAP 6 アダプターをインストールする前に、JBoss EAP 6 リポジトリーにサブスクライブする必要があります。

  • Red Hat Subscription Manager を使用して、Red Hat Enterprise Linux システムがお使いのアカウントに登録されている必要があります。詳細は、Red Hat Subscription Management のドキュメント を参照してください。
  • すでに別の JBoss EAP リポジトリーにサブスクライブしている場合は、最初にそのリポジトリーからサブスクライブを解除する必要があります。
  • Red Hat Subscription Manager を使用して、以下のコマンドを使用して JBoss EAP 6 リポジトリーにサブスクライブします。お使いの Red Hat Enterprise Linux のバージョンに応じて、<RHEL_VERSION> を 6 または 7 に置き換えてください。

    $ sudo subscription-manager repos --enable=jb-eap-6-for-rhel-<RHEL_VERSION>-server-rpms

手順

  1. 以下のコマンドを使用して、SAML 用の EAP 6 アダプターをインストールします。

    $ sudo yum install keycloak-saml-adapter-sso7_5-eap6
    注記

    RPM インストールのデフォルトの EAP_HOME パスは /opt/rh/eap6/root/usr/share/wildfly です。

  2. SAML モジュールのインストールスクリプトを実行します。

    $ $EAP_HOME/bin/jboss-cli.sh -c --file=$EAP_HOME/bin/adapter-install-saml.cli

インストールが完了しました。

3.1.5.1. WAR のセキュリティー保護

このセクションでは、WAR パッケージ内に設定ファイルを追加してファイルを編集することにより、WAR を直接保護する方法について説明します。

最初に、WAR の WEB-INF ディレクトリーに keycloak-saml.xml アダプター設定ファイルを作成する必要があります。この設定ファイルの形式は、「一般的なアダプター設定」セクションで説明されています。

次に、web.xmlauth-methodKEYCLOAK-SAML に設定する必要があります。また、標準のサーブレットセキュリティーを使用して URL に role-base 制約を指定する必要があります。以下は web.xml ファイルの例です。

<web-app 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_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admins</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customers</web-resource-name>
            <url-pattern>/customers/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>user</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>KEYCLOAK-SAML</auth-method>
        <realm-name>this is ignored currently</realm-name>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>
    <security-role>
        <role-name>user</role-name>
    </security-role>
</web-app>

auth-method 設定を除くすべての標準サーブレット設定。

3.1.5.2. Red Hat Single Sign-On SAML サブシステムを使用した WAR のセキュリティー保護

Red Hat Single Sign-On で WAR を保護するために、WAR をオープンする必要はありません。代わりに、Red Hat Single Sign-On SAML Adapter Subsystem 経由で外部からセキュリティーを確保することもできます。KEYCLOAK-SAML を auth-method として指定する必要はありませんが、web.xmlsecurity-constraints を定義する必要があります。ただし、WEB-INF/keycloak-saml.xml ファイルを作成する必要がありません。このメタデータは、サーバーの サブシステム設定 domain.xml または standalone.xml の XML 内で定義されます。

<extensions>
  <extension module="org.keycloak.keycloak-saml-adapter-subsystem"/>
</extensions>

<profile>
  <subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
    <secure-deployment name="WAR MODULE NAME.war">
      <SP entityID="APPLICATION URL">
        ...
      </SP>
    </secure-deployment>
  </subsystem>
</profile>

secure-deployment name 属性は、セキュリティーを保護する WAR を識別します。この値は web.xml.war を追加した module-name です。残りの設定は、一般的なアダプター設定 で定義される keycloak-saml.xml 設定と同じ XML 構文を使用します。

設定例:

<subsystem xmlns="urn:jboss:domain:keycloak-saml:1.1">
  <secure-deployment name="saml-post-encryption.war">
    <SP entityID="http://localhost:8080/sales-post-enc/"
        sslPolicy="EXTERNAL"
        nameIDPolicyFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
        logoutPage="/logout.jsp"
        forceAuthentication="false">
      <Keys>
        <Key signing="true" encryption="true">
          <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
            <PrivateKey alias="http://localhost:8080/sales-post-enc/" password="test123"/>
            <Certificate alias="http://localhost:8080/sales-post-enc/"/>
          </KeyStore>
        </Key>
      </Keys>
      <PrincipalNameMapping policy="FROM_NAME_ID"/>
      <RoleIdentifiers>
        <Attribute name="Role"/>
      </RoleIdentifiers>
      <IDP entityID="idp">
        <SingleSignOnService signRequest="true"
            validateResponseSignature="true"
            requestBinding="POST"
            bindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>

        <SingleLogoutService
            validateRequestSignature="true"
            validateResponseSignature="true"
            signRequest="true"
            signResponse="true"
            requestBinding="POST"
            responseBinding="POST"
            postBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"
            redirectBindingUrl="http://localhost:8080/auth/realms/saml-demo/protocol/saml"/>
        <Keys>
          <Key signing="true" >
            <KeyStore resource="/WEB-INF/keystore.jks" password="store123">
              <Certificate alias="saml-demo"/>
            </KeyStore>
          </Key>
        </Keys>
      </IDP>
    </SP>
   </secure-deployment>
</subsystem>

3.1.6. Java Servle フィルターアダプター

サーブレットプラットフォーム用のアダプターを持たない Java サーブレットアプリケーションで SAML を使用する場合は、Red Hat Single Sign-On が持つサーブレットフィルターアダプターを使用することを選択できます。このアダプターは、他のアダプターとは異なります。「一般的なアダプター設定」セクションに定義されているように /WEB-INF/keycloak-saml.xml ファイルを指定する必要がありますが、web.xml でセキュリティー制約を定義する必要はありません。代わりに、Red Hat Single Sign-On サーブレットフィルターアダプターを使用してフィルターマッピングを定義し、セキュリティーを保護する url パターンを保護します。

注記

Backchannel ログアウトの動作は、標準アダプターとは少々異なります。HTTP セッションを無効にする代わりに、セッション ID をログアウトとしてマークします。セッション ID に基づいて http セッションを任意に無効にする方法はありません。

警告

SAML フィルターを使用するクラスター化されたアプリケーションがある場合は、バックチャネルログアウトは現在機能しません。

<web-app 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_3_0.xsd"
      version="3.0">

	<module-name>customer-portal</module-name>

    <filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Keycloak Filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Red Hat Single Sign-On フィルターには、他のアダプターと同じ設定パラメーターがあります。ただし、これらはコンテキストパラメーターではなく、フィルター init パラメーターとして定義する必要があります。

さまざまな異なる安全な URL パターンと安全でない URL パターンがある場合は、複数のフィルターマッピングを定義できます。

警告

/saml に対応するフィルターマッピングがある。このマッピングは、すべてのサーバーコールバックに対応します。

IdP で SP を登録する場合は、http[s]://hostname/{context-root}/saml を Assert Consumer Service URL および Single Logout Service URL として登録する必要があります。

このフィルターを使用するには、この maven アーティファクトを WAR pom に組み込みます。

<dependency>
   <groupId>org.keycloak</groupId>
   <artifactId>keycloak-saml-servlet-filter-adapter</artifactId>
   <version>18.0.0.redhat-00001</version>
</dependency>

マルチテナント を使用するには、keycloak.config.resolver パラメーターをフィルターパラメーターとして渡す必要があります。

    <filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.saml.servlet.SamlFilter</filter-class>
        <init-param>
            <param-name>keycloak.config.resolver</param-name>
            <param-value>example.SamlMultiTenantResolver</param-value>
        </init-param>
    </filter>

3.1.7. ID プロバイダーを使用した登録

サーブレットベースのアダプタごとに、アサートコンシューマサービス URL およびシングルログアウトサービスに登録するエンドポイントは/saml が追加されたサーブレットアプリケーションのベース URL、つまり https://example.com/contextPath/saml である必要があります。

3.1.8. ログアウト

Web アプリケーションからログアウトする方法は複数あります。Jakarta EE サーブレットコンテナーでは、HttpServletRequest.logout() を呼び出すことができます。他のブラウザーアプリケーションでは、ブラウザーをセキュリティー制約のある Web アプリケーションの任意の URL に指定し、クエリーパラメーター GLO (つまり http://myapp?GLO=true) に渡すことができます。ブラウザーに SSO セッションがある場合は、ログアウトします。

3.1.8.1. クラスター化された環境でのログアウト

SAML アダプターは内部的には、SAML セッションインデックス、プリンシパル名 (既知の場合)、および HTTP セッション ID 間のマッピングを保存します。このマッピングは、分散可能なアプリケーションのクラスター全体で、JBoss アプリケーションサーバーファミリー (WildFly 10/11、EAP 6/7) で維持できます。前提条件として、HTTP セッションをクラスター全体に分散する必要があります (つまり、アプリケーションはアプリケーションの web.xml<distributable/> タグでマークされます)。

この機能を有効にするには、以下のセクションを /WEB_INF/web.xml ファイルに追加します。

EAP 7 (WildFly 10/11) の場合:

<context-param>
    <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
    <param-value>org.keycloak.adapters.saml.wildfly.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>

EAP 6 の場合:

<context-param>
    <param-name>keycloak.sessionIdMapperUpdater.classes</param-name>
    <param-value>org.keycloak.adapters.saml.jbossweb.infinispan.InfinispanSessionCacheIdMapperUpdater</param-value>
</context-param>

デプロイメントのセッションキャッシュの名前が deployment-cache の場合、SAML マッピングに使用されるキャッシュの名前が deployment-cache.ssoCache になります。キャッシュの名前は、コンテキストパラメーター keycloak.sessionIdMapperUpdater.infinispan.cacheName で上書きできます。キャッシュを含むキャッシュコンテナーはデプロイメントセッションキャッシュを含むものと同じですが、コンテキストパラメーター keycloak.sessionIdMapperUpdater.infinispan.containerName で上書きできます。

デフォルトでは、SAML マッピングキャッシュの設定はセッションキャッシュから派生します。この設定は、他のキャッシュと同じように、サーバーのキャッシュ設定セクションで手動でオーバーライドできます。

現在、信頼できるサービスを提供するには、SAML セッションキャッシュにレプリケートされたキャッシュを使用することが推奨されます。分散キャッシュを使用すると、SAML のログアウト要求が HTTP セッションマッピングへの SAML セッションインデックスにアクセスできないノードに到達する結果となり、ログアウトに失敗する可能性があります。

3.1.8.2. クロスサイトシナリオにおけるログアウト

サイトの間のシナリオは、WildFly 10 以降および EAP 7 以降にのみ適用されます。

複数のデータセンターにまたがるセッションを処理するには、特別な処理が必要です。以下のシナリオを見てみましょう。

  1. ログイン要求は、データセンター 1 のクラスター内で処理されます。
  2. 管理者は、特定の SAML セッションに対してログアウト要求を発行し、要求はデータセンター 2 に送信されます。

データセンター 2 は、データセンター 1 (および HTTP セッションを共有する他のすべてのデータセンター) にあるすべてのセッションをログアウトする必要があります。

この場合、上記 の SAML セッションキャッシュを個別のクラスター内だけでなく、スタンドアロン Infinispan/JDG サーバーを介して すべてのデータセンターにレプリケートする必要があります。

  1. スタンドアロン Infinispan/JDG サーバーにキャッシュを追加する必要があります。
  2. 各 SAML セッションキャッシュのリモートストアとして、以前のアイテムからのキャッシュを追加する必要があります。

デプロイメント中にリモートストアが SAML セッションキャッシュに存在することが検出されると、変更がないか監視され、それに応じてローカル SAML セッションキャッシュが更新されます。

3.1.9. assertion 属性の取得

正常な SAML ログインの後、アプリケーションコードが SAML アサーションで渡される属性値を取得することをお勧めします。HttpServletRequest.getUserPrincipal() は、org.keycloak.adapters.saml.SamlPrincipal と呼ばれる Red Hat Single Sign-On 固有のクラスに型変換できる Principal オブジェクトを返します。このオブジェクトを使用すると、raw アサーションを確認でき、属性値を検索するための便利な関数もあります。

package org.keycloak.adapters.saml;

public class SamlPrincipal implements Serializable, Principal {
    /**
     * Get full saml assertion
     *
     * @return
     */
    public AssertionType getAssertion() {
       ...
    }

    /**
     * Get SAML subject sent in assertion
     *
     * @return
     */
    public String getSamlSubject() {
        ...
    }

    /**
     * Subject nameID format
     *
     * @return
     */
    public String getNameIDFormat() {
        ...
    }

    @Override
    public String getName() {
        ...
    }

    /**
     * Convenience function that gets Attribute value by attribute name
     *
     * @param name
     * @return
     */
    public List<String> getAttributes(String name) {
        ...

    }

    /**
     * Convenience function that gets Attribute value by attribute friendly name
     *
     * @param friendlyName
     * @return
     */
    public List<String> getFriendlyAttributes(String friendlyName) {
        ...
    }

    /**
     * Convenience function that gets first  value of an attribute by attribute name
     *
     * @param name
     * @return
     */
    public String getAttribute(String name) {
        ...
    }

    /**
     * Convenience function that gets first  value of an attribute by attribute name
     *
     *
     * @param friendlyName
     * @return
     */
    public String getFriendlyAttribute(String friendlyName) {
        ...
    }

    /**
     * Get set of all assertion attribute names
     *
     * @return
     */
    public Set<String> getAttributeNames() {
        ...
    }

    /**
     * Get set of all assertion friendly attribute names
     *
     * @return
     */
    public Set<String> getFriendlyNames() {
        ...
    }
}

3.1.10. エラー処理

Red Hat Single Sign-On には、サーブレットベースのクライアントアダプターに対するエラー処理機能があります。認証でエラーが発生した場合、クライアントアダプターは HttpServletResponse.sendError() を呼び出します。web.xml ファイル内に error-page を設定して、必要なエラーを処理できます。クライアントアダプターは 400、401、403、および 500 のエラーを出力できます。

<error-page>
    <error-code>403</error-code>
    <location>/ErrorHandler</location>
</error-page>

クライアントアダプターは、取得可能なHttpServletRequest 属性も設定します。属性名は org.keycloak.adapters.spi.AuthenticationError です。このオブジェクトは、org.keycloak.adapters.saml.SamlAuthenticationError に型変換されます。このクラスは、何が起こったのかを正確に知ることができます。この属性が設定されていない場合、アダプターはエラーコードを担当しませんでした。

public class SamlAuthenticationError implements AuthenticationError {
    public static enum Reason {
        EXTRACTION_FAILURE,
        INVALID_SIGNATURE,
        ERROR_STATUS
    }

    public Reason getReason() {
        return reason;
    }
    public StatusResponseType getStatus() {
        return status;
    }
}

3.1.11. トラブルシューティング

問題のトラブルシューティングを行う最適な方法として、クライアントアダプターと Red Hat Single Sign-On サーバーの両方で SAML のデバッグをオンにすることができます。ロギングフレームワークを使用して、org.keycloak.saml パッケージのログレベルを DEBUG に設定します。これをオンにすると、サーバーとの間で送受信される SAML 要求および応答ドキュメントを確認できます。

3.1.12. マルチテナンシー

SAML は マルチテナント の OIDC と同じ機能を提供します。つまり、1 つのターゲットアプリケーション (WAR) は複数の Red Hat Single Sign-On レルムでセキュリティー保護されます。レルムは、同じ Red Hat Single Sign-On インスタンスまたは別のインスタンスに配置できます。

これを実行するには、複数の keycloak-saml.xml アダプター設定ファイルが必要です。

異なるアダプター設定ファイルを含む WAR の複数のインスタンスを異なるコンテキストパスにデプロイすることができますが、これは不便である可能性があるため、コンテキストパス以外のものに基づいてレルムを選択することをお勧めします。

Red Hat Single Sign-On では、カスタム設定リゾルバーの設定が可能で、これにより、リクエストごとに使用するアダプター設定を選択できるようになります。SAML では、設定はログイン処理のみに関連し、ユーザーがログインするとセッションが認証され、返された keycloak-saml.xml が異なるかどうかは問題ありません。そのため、同じセッションで同じ設定を返すことが、適切な方法になります。

そのためには、org.keycloak.adapters.saml.SamlConfigResolver の実装を作成します。以下の例では、Host ヘッダーを使用して適切な設定を検索し、アプリケーションの Java クラスパスから関連する要素を読み込みます。

package example;

import java.io.InputStream;
import org.keycloak.adapters.saml.SamlConfigResolver;
import org.keycloak.adapters.saml.SamlDeployment;
import org.keycloak.adapters.saml.config.parsers.DeploymentBuilder;
import org.keycloak.adapters.saml.config.parsers.ResourceLoader;
import org.keycloak.adapters.spi.HttpFacade;
import org.keycloak.saml.common.exceptions.ParsingException;

public class SamlMultiTenantResolver implements SamlConfigResolver {

    @Override
    public SamlDeployment resolve(HttpFacade.Request request) {
        String host = request.getHeader("Host");
        String realm = null;
        if (host.contains("tenant1")) {
            realm = "tenant1";
        } else if (host.contains("tenant2")) {
            realm = "tenant2";
        } else {
            throw new IllegalStateException("Not able to guess the keycloak-saml.xml to load");
        }

        InputStream is = getClass().getResourceAsStream("/" + realm + "-keycloak-saml.xml");
        if (is == null) {
            throw new IllegalStateException("Not able to find the file /" + realm + "-keycloak-saml.xml");
        }

        ResourceLoader loader = new ResourceLoader() {
            @Override
            public InputStream getResourceAsStream(String path) {
                return getClass().getResourceAsStream(path);
            }
        };

        try {
            return new DeploymentBuilder().build(is, loader);
        } catch (ParsingException e) {
            throw new IllegalStateException("Cannot load SAML deployment", e);
        }
    }
}

また、web.xml のコンテキストパラメーター keycloak.config.resolver で使用する SamlConfigResolver 実装を構成する必要があります。

<web-app>
    ...
    <context-param>
        <param-name>keycloak.config.resolver</param-name>
        <param-value>example.SamlMultiTenantResolver</param-value>
    </context-param>
</web-app>

3.2. Apache HTTPD モジュール mod_auth_mellon

mod_auth_mellon モジュールは、SAML の Apache HTTPD プラグインです。言語/環境が Apache HTTPD をプロキシーとして使用することをサポートしている場合は、mod_auth_mellon を使用して SAML で Web アプリケーションを保護できます。このモジュールの詳細は、GitHub リポジトリー mod_auth_mellon を参照してください。

mod_auth_mellon を設定するには、以下が必要になります。

  • アイデンティティープロバイダー (IdP) エンティティー記述子 XML ファイル。Red Hat Single Sign-On または他の SAML IdP への接続を記述します。
  • セキュリティー保護するアプリケーションの SAML 接続および設定を記述する SP エンティティー記述子 XML ファイル。
  • 秘密鍵 PEM ファイル。これは、アプリケーションがドキュメントの署名に使用するプライベートキーを定義する PEM 形式のテキストファイルです。
  • アプリケーションの証明書を定義するテキストファイルである証明書 PEM ファイル。
  • mod_auth_mellon 固有の Apache HTTPD モジュール設定。

3.2.1. Red Hat Single Sign-On での mod_auth_mellon の設定

以下の 2 つのホストがあります。

  • Red Hat Single Sign-On が実行されているホスト。Red Hat Single Sign-On は SAML アイデンティティープロバイダー (IdP) であるため、$idp_host と呼ばれます。
  • Web アプリケーションが実行されているホスト。これは $sp_host と呼ばれます。SAML では、IdP を使用するアプリケーションはサービスプロバイダー (SP) と呼ばれます。

以下のすべての手順は、root 権限で $sp_host で実行する必要があります。

3.2.1.1. パッケージのインストール

必要なパッケージをインストールするには、以下が必要です。

  • Apache Web Server (httpd)
  • Apache の Mellon SAML SP アドオンモジュール
  • X509 証明書を作成するツール

必要なパッケージをインストールするには、以下のコマンドを実行します。

yum install httpd mod_auth_mellon mod_ssl openssl

3.2.1.2. Apache SAML の設定ディレクトリーの作成

Apache の SAML の使用に関連する設定ファイルを 1 つの場所で維持することを推奨します。

Apache 設定の root /etc/httpd の下に、saml2 という名前の新規ディレクトリーを作成します。

mkdir /etc/httpd/saml2

3.2.1.3. Mellon サービスプロバイダーの設定

Apache アドオンモジュールの設定ファイルは /etc/httpd/conf.d ディレクトリーにあり、ファイル名の拡張子は .conf になります。/etc/httpd/conf.d/mellon.conf ファイルを作成し、Mellon の設定ディレクティブをこれに配置する必要があります。

Mellon の設定ディレクティブは、大まかに 2 つのクラスの情報に分類できます。

  • SAML 認証を保護する URL
  • 保護された URL が参照された場合に使用される SAML パラメーター。

Apache 設定ディレクティブは通常、場所と呼ばれる URL 領域内の階層ツリー構造に従います。Mellon が保護するには、URL の場所を 1 つ以上指定する必要があります。各場所に適用される設定パラメーターを追加する方法に柔軟性があります。必要なパラメーターをすべてロケーションブロックに追加するか、Mellon パラメーターを特定の保護された場所が継承する URL の場所階層にある共通の場所に追加するかのいずれかを実行できます (またはこの 2 つのなんらかの組み合わせを実行)。どの場所が SAML アクションをトリガーしても、SP は同じように動作するのが一般的であるため、ここで使用する設定例では、一般的な Mellon 設定ディレクティブを階層の root に配置してから、Mellon によって保護される特定の場所を最小限のディレクティブで定義できます。このストラテジーでは、保護されている場所ごとに同じパラメーターが重複しないようにします。

この例には保護された場所が 1 つ (https://$sp_host/private) しかありません。

Mellon サービスプロバイダーを設定するには、以下の手順を実行します。

手順

  1. 以下の内容で /etc/httpd/conf.d/mellon.conf ファイルを作成します。
 <Location / >
    MellonEnable info
    MellonEndpointPath /mellon/
    MellonSPMetadataFile /etc/httpd/saml2/mellon_metadata.xml
    MellonSPPrivateKeyFile /etc/httpd/saml2/mellon.key
    MellonSPCertFile /etc/httpd/saml2/mellon.crt
    MellonIdPMetadataFile /etc/httpd/saml2/idp_metadata.xml
 </Location>
 <Location /private >
    AuthType Mellon
    MellonEnable auth
    Require valid-user
 </Location>
注記

上記のコードで参照されるファイルの一部は、後の手順で作成されます。

第4章 Red Hat Single Sign-On を使用するように Docker レジストリーを設定する手順

注記

Docker 認証はデフォルトで無効になっています。有効にするには、「Profiles」を参照してください。

本セクションでは、Red Hat Single Sign-On を認証サーバーとして使用するように Docker レジストリーを設定する方法を説明します。

Docker レジストリーのセットアップおよび設定方法の詳細は、『Docker Registry Configuration Guide』を参照してください。

4.1. Docker レジストリー設定ファイルのインストール

高度な Docker レジストリー設定を使用しているユーザーの場合は、通常、独自のレジストリー設定ファイルを提供することをお勧めします。Red Hat Single Sign-On Docker プロバイダーは、Registry Config File フォーマットオプションを介してこのメカニズムをサポートします。このオプションを選択すると、以下のような出力が生成されます。

auth:
  token:
    realm: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth
    service: docker-test
    issuer: http://localhost:8080/auth/realms/master

この出力は、既存のレジストリー設定ファイルにコピーできます。ファイルの設定方法に関する詳細は、レジストリー設定ファイル仕様 を参照してください。または 基本的な例 から始めてください。

警告

rootcertbundle フィールドを Red Hat Single Sign-On レルムの公開鍵の場所に設定することを忘れないでください。認証設定は、この引数なしでは機能しません。

4.2. Docker レジストリー環境変数オーバーライドインストール

多くの場合、開発または POC Docker レジストリーに単純な環境変数オーバーライドを使用することが適しています。通常、このアプローチは実稼働環境での使用は推奨されませんが、急場しのぎの方法でレジストリーを起動する必要がある場合には役立ちます。クライアントのインストールタブから Variable Override フォーマットオプションを使用するだけで、出力は以下のようになります。

REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/auth/realms/master/protocol/docker-v2/auth
REGISTRY_AUTH_TOKEN_SERVICE: docker-test
REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/auth/realms/master
警告

REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE を、Red Hat Single Sign-On レルムの公開鍵の場所で上書きする設定を忘れないでください。認証設定は、この引数なしでは機能しません。

4.3. Docker Compose YAML ファイル

警告

このインストール方法は、Red Hat Single Sign-On サーバーに対して docker レジストリーを認証する簡単な方法になります。これは開発のみを目的としており、本番環境または本番環境のような環境で使用しないでください。

zip ファイルインストールメカニズムは、Red Hat Single Sign-On サーバーが Docker レジストリーとどのように対話するかを理解したい開発者向けのクイックスタートを提供します。設定するには、以下を実施します。

手順

  1. 必要なレルムから、クライアント設定を作成します。この時点で、Docker レジストリーはありません。クイックスタートがその部分を処理します。
  2. インストールタブから「Docker Compose YAML」オプションを選択し、.zip ファイルをダウンロードします。
  3. 目的の場所にアーカイブを展開して、ディレクトリーを開きます。
  4. docker-compose up で Docker レジストリーを起動します。
注記

HTTP Basic 認証フローはフォームを表示しないため、'master' 以外のレルムで Docker レジストリークライアントを設定することをお勧めします。

上記の設定が行われ、keycloak サーバーおよび Docker レジストリーが実行されると、Docker 認証が正常に行われるはずです。

[user ~]# docker login localhost:5000 -u $username
Password: *******
Login Succeeded

第5章 クライアント登録サービスの使用

アプリケーションまたはサービスが Red Hat Single Sign-On を使用するには、Red Hat Single Sign-On でクライアントを登録する必要があります。管理者は管理コンソール (または管理 REST エンドポイント) でこれを実行できますが、クライアントは Red Hat Single Sign-On クライアント登録サービスを介して登録することもできます。

クライアント登録サービスは、Red Hat Single Sign-On Client Representations、OpenID Connect Client Meta Data および SAML Entity Descriptors の組み込みサポートを提供します。クライアント登録サービスのエンドポイントは /auth/realms/<realm>/clients-registrations/<provider> です。

サポートされている組み込み プロバイダー は以下のとおりです。

  • デフォルト - Red Hat Single Sign-On Client Representation (JSON)
  • インストール - Red Hat Single Sign-On Adapter Configuration (JSON)
  • openid-connect - OpenID Connect Client Metadata Description (JSON)
  • saml2-entity-descriptor - SAML エンティティー記述子 (XML)

以下のセクションでは、異なるプロバイダーを使用する方法を説明します。

5.1. 認証

クライアント登録サービスを呼び出すには、通常トークンが必要です。トークンは、ベアラートークン、初期アクセストークン、または登録アクセストークンにすることができます。トークンなしで新しいクライアントを登録する別の方法もありますが、その場合はクライアント登録ポリシーを設定する必要があります (以下を参照)。

5.1.1. ベアラートークン

ベアラートークンは、ユーザーまたは Service Account の代わりに発行できます。エンドポイントを呼び出すには、以下のパーミッションが必要です (詳細は『Server Administration Guide』を参照)。

  • create-client または manage-client - クライアントを作成するため
  • view-client または manage-client - クライアントを表示するため
  • manage-client - クライアントを更新または削除する

ベアラートークンを使用してクライアントを作成する場合は、create-client ロールのみのサービスアカウントからトークンを使用することが推奨されます (詳細は Server Administration Guide を参照)。

5.1.2. 初期アクセストークン

新しいクライアントを登録するための推奨されるアプローチは、初期アクセストークンを使用することです。初期アクセストークンは、クライアントの作成にのみ使用でき、有効期限を設定できるほか、作成できるクライアントの数に制限を設定できます。

初期アクセストークンは管理コンソールを使用して作成できます。新しい初期アクセストークンを作成するには、最初に管理コンソールでレルムを選択し、左側のメニューで Realm Settings をクリックし、ページに表示されるタブの Client Registration をクリックします。最後に Initial Access Tokens サブタブをクリックします。

これで、既存の初期アクセストークンを確認できるようになります。アクセスがあれば、不要になったトークンを削除できます。トークンの作成時にのみ、トークンの値を取得できます。新規トークンを作成するには、Create をクリックします。オプションで、トークンの有効期間を追加できるようになりました。また、トークンを使用して作成できるクライアントの数も追加できます。Save をクリックすると、トークンの値が表示されます。

このトークンは後で取得できないため、今すぐこのトークンをコピーして貼り付けることが重要です。コピー/貼り付けを忘れた場合は、このトークンを削除して別のトークンを作成してください。

トークン値は、クライアント登録サービスを呼び出すときに、リクエストの Authorization ヘッダーに追加することにより、標準のベアラートークンとして使用されます。以下に例を示します。

Authorization: bearer eyJhbGciOiJSUz...

5.1.3. 登録アクセストークン

クライアント登録サービス経由でクライアントを作成する場合、応答には登録アクセストークンが含まれます。登録アクセストークンは、後でクライアント設定を取得するアクセスを提供しますが、クライアントを更新または削除するためのアクセスも提供します。登録アクセストークンは、ベアラートークンまたは初期アクセストークンと同じ方法でリクエストに含まれます。登録アクセストークンは 1 回だけ有効です。使用すると、応答に新しいトークンが含まれます。

クライアント登録サービスの外部でクライアントが作成された場合、それに関連付けられた登録アクセストークンはありません。管理コンソールから作成できます。これは、特定のクライアントのトークンを失った場合にも便利です。新しいトークンを作成するには、管理コンソールでクライアントを見つけ、Credentials をクリックします。次に、Generate registration access token をクリックします。

5.2. Red Hat Single Sign-On Representations

デフォルト のクライアント登録プロバイダーは、クライアントの作成、取得、更新、および削除に使用できます。Red Hat Single Sign-On Client Representation 形式を使用します。これは、たとえばプロトコルマッパーの設定など、管理コンソールから設定できるのとまったく同じように、クライアントを設定するためのサポートを提供します。

クライアントを作成するには、クライアント表現 (JSON)を作成し、/auth/realms/<realm>/clients-registrations/default への HTTP POST 要求を実行します。

登録アクセストークンも含まれる Client Representation を返します。後で設定を取得したり、クライアントを更新または削除したりする場合は、登録アクセストークンをどこかに保存する必要があります。

クライアント表現を取得するには、/auth/realms/<realm>/clients-registrations/default/<client id> に対して HTTP GET リクエストを実行します。

また、新しい登録アクセストークンも返します。

クライアント表示を更新するには、更新されたクライアント表示で HTTP PUT 要求を実行します。これは、/auth/realms/<realm>/clients-registrations/default/<client id> です。

また、新しい登録アクセストークンも返します。

クライアント表現を削除するには、/auth/realms/<realm>/clients-registrations/default/<client id> への HTTP DELETE 要求を実行します。

5.3. Red Hat Single Sign-On アダプターの設定

インストール クライアント登録プロバイダーを使用して、クライアントのアダプター設定を取得できます。トークン認証の他に、HTTP Basic 認証を使用してクライアント認証情報で認証することもできます。これには、リクエストに以下のヘッダーが含まれます。

Authorization: basic BASE64(client-id + ':' + client-secret)

アダプター設定を取得するには、HTTP GET 要求を /auth/realms/<realm>/clients-registrations/install/<client id> に実行します。

パブリッククライアントには認証は必要ありません。これは、JavaScript アダプターの場合、上記の URL を使用して、Red Hat Single Sign-On から直接クライアント設定をロードできることを意味します。

5.4. OpenID Connect 動的クライアント登録

Red Hat Single Sign-On は、OAuth 2.0 動的クライアント登録プロトコル および OAuth 2.0 動的クライアント登録管理プロトコル を拡張する OpenID Connect 動的クライアント登録 を実装します。

Red Hat Single Sign-On でクライアントを登録するために使用するエンドポイントは、/auth/realms/<realm>/clients-registrations/openid-connect[/<client id>] です。

このエンドポイントは、レルムの OpenID Connect Discovery エンドポイントである /auth/realms/<realm>/.well-known/openid-configuration にも含まれています。

5.5. SAML エンティティー記述子

SAML エンティティー記述子エンドポイントは、SAML v2 エンティティー記述子を使用したクライアントの作成のみをサポートします。クライアントの取得、更新、または削除はサポートされません。これらの操作では、Red Hat Single Sign-On 表現エンドポイントを使用する必要があります。クライアントを作成する場合、登録アクセストークンを含む作成されたクライアントに関する詳細が記載された Red Hat Single Sign-On Client Representation が返されます。

クライアントを作成するには、SAML エンティティー記述子を使用して HTTP POST 要求を /auth/realms/<realm>/clients-registrations/saml2-entity-descriptor に実行します。

5.6. CURL の使用例

以下の例では、CURL を使用して clientId myclient でクライアントを作成します。eyJhbGciOiJSUz…​ を、適切な初期アクセストークンまたはベアラートークンに置き換える必要があります。

curl -X POST \
    -d '{ "clientId": "myclient" }' \
    -H "Content-Type:application/json" \
    -H "Authorization: bearer eyJhbGciOiJSUz..." \
    http://localhost:8080/auth/realms/master/clients-registrations/default

5.7. Java クライアント登録 API の使用例

クライアント登録 Java API により、Java を使用したクライアント登録サービスが容易になります。使用するには、Maven からの org.keycloak:keycloak-client-registration-api:>VERSION< の依存関係を追加します。

クライアント登録の使用に関する詳細な手順は、JavaDocs を参照してください。以下は、クライアントを作成する例です。eyJhbGciOiJSUz…​ を、適切な初期アクセストークンまたはベアラートークンに置き換える必要があります。

String token = "eyJhbGciOiJSUz...";

ClientRepresentation client = new ClientRepresentation();
client.setClientId(CLIENT_ID);

ClientRegistration reg = ClientRegistration.create()
    .url("http://localhost:8080/auth", "myrealm")
    .build();

reg.auth(Auth.token(token));

client = reg.create(client);

String registrationAccessToken = client.getRegistrationAccessToken();

5.8. クライアント登録ポリシー

注記

現行では、『Server Administration Guide』で説明されているクライアントポリシーを優先して、クライアント登録ポリシーを削除する予定です。クライアントポリシーはより柔軟であり、より多くのユースケースに対応します。

現在、Red Hat Single Sign-On では、クライアント登録サービスを介して新しいクライアントを登録する 2 つの方法をサポートしています。

  • 認証された要求 - 新しいクライアントを登録する要求には、上記のように Initial Access Token または Bearer Token のいずれかが含まれている必要があります。
  • 特定の要求 - 新しいクライアントを登録する要求にトークンを含める必要はありません。

匿名のクライアント登録要求は非常に興味深く強力な機能ですが、誰もが制限なしに新しいクライアントを登録できることは、通常は望まれません。このため、クライアント登録ポリシー SPI があります。これは、新しいクライアントを登録できるユーザーとその条件を制限する方法を提供します。

Red Hat Single Sign-On 管理コンソールでは、Client Registration タブをクリックして、Client Registration Policies サブタブをクリックします。ここでは、匿名要求に対して、デフォルトで設定されているポリシーと、認証された要求に対して設定されているポリシーを確認できます。

注記

匿名要求 (トークンなしの要求) は、新しいクライアントの作成 (登録) のためだけに許可されます。したがって、匿名要求を介して新しいクライアントを登録すると、応答には登録アクセストークンが含まれます。これは、特定のクライアントの読み取り、更新、または削除要求に使用する必要があります。ただし、匿名登録からこの登録アクセストークンを使用する場合も、匿名ポリシーが適用されます。そのため、たとえば、Trusted Hosts ポリシーがある場合は、更新クライアントのリクエストも Trusted Host から取得する必要があります。たとえば、クライアントの更新時や、Consent Required が存在する場合には、Consent Required を無効にすることはできません。

現在、以下のポリシー実装があります。

  • Trusted Hosts Policy: 信頼されたホストおよび信頼済みドメインの一覧を設定できます。クライアント登録サービスへの要求は、それらのホストまたはドメインからのみ送信できます。信頼できない IP から送信されたリクエストは拒否されます。新たに登録したクライアントの URL も、信頼できるホストまたはドメインを使用する必要があります。たとえば、信頼されていないホストを参照するクライアントの Redirect URI を設定することはできません。デフォルトでは、ホワイトリストに登録されているホストがないため、匿名クライアントの登録は事実上無効になっています。
  • Consent Required Policy: 新しく登録されたクライアントでは、Consent Allowed スイッチが有効になります。したがって、認証が成功した後、ユーザーがパーミッション (クライアントスコープ) を承認する必要があるときに、常に同意画面が表示されます。これは、ユーザーが承認しない限り、クライアントが個人情報へのアクセスやユーザーのパーミッションを持たないことを意味します。
  • Protocol Mappers Policy: ホワイトリスト化されたプロトコルマッパー実装のリストを設定できます。新規クライアントに、ホワイトリストに記載されていないプロトコルマッパーが含まれている場合は、登録や更新を行うことができません。このポリシーは認証されたリクエストにも使用されるため、認証されたリクエストであっても、使用できるプロトコルマッパーに関していくつかの制限がある点に注意してください。
  • Client Scope Policy: 新しく登録または更新されたクライアントで使用できる Client Scopes をホワイトリスト化できます。デフォルトではホワイトリスト化されたスコープはありません。デフォルトでは、Realm Default Client Scopes として定義されるクライアントスコープのみがホワイトリスト化されます。
  • Full Scope Policy: 新しく登録されたクライアントでは、Full Scope Allowed が無効になります。つまり、指定されたレルムロールや、他のクライアントのクライアントロールはありません。
  • Max Clients Policy: レルム内の現在のクライアント数が指定の制限と同じかそれより多い場合、登録を拒否します。匿名登録では、デフォルトで 200 になります。
  • Client Disabled Policy: 新たに登録されたクライアントが無効になります。これは、管理者が新しく登録されたすべてのクライアントを手動で承認して有効にする必要があることを意味します。このポリシーは、匿名登録でもデフォルトで使用されません。

第6章 CLI を使用したクライアント登録の自動化

クライアント登録 CLI は、アプリケーション開発者が、Red Hat Single Sign-On と統合する際に、セルフサービス方式で新しいクライアントを設定するためのコマンドラインインターフェイス (CLI) ツールです。これは、Red Hat Single Sign-On クライアント登録 REST エンドポイントと対話する目的で設計されています。

Red Hat Single Sign-On を使用できるようにするには、すべてのアプリケーションでクライアント設定を作成または取得する必要があります。通常、一意のホスト名でホストされる新規アプリケーションごとに新規クライアントを設定します。アプリケーションが Red Hat Single Sign-On と対話する場合、アプリケーションはクライアント ID で自身を識別するため、Red Hat Single Sign-On はログインページ、シングルサインオン (SSO) セッション管理、およびその他のサービスを提供できます。

クライアント登録 CLI を使用してコマンドラインからアプリケーションクライアントを設定できます。また、これをシェルスクリプトで使用できます。

特定のユーザーが Client Registration CLI を使用できるようにするために、Red Hat Single Sign-On の管理者は通常、管理コンソールを使用して適切なロールで新規ユーザーを設定するか、新しいクライアントとクライアントシークレットを設定してクライアント登録 REST API へのアクセスを付与します。

6.1. クライアント登録 CLI で使用する新しい一般ユーザーの設定

手順

  1. 管理コンソール (例: http://localhost:8080/auth/admin) に admin としてログインします。
  2. 管理するレルムを選択します。
  3. 既存のユーザーを使用する場合は、そのユーザーを選択して編集します。それ以外の場合は、新しいユーザーを作成します。
  4. Role Mappings > Client Roles > realm-management を選択します。マスターレルムを使用している場合は、NAME-realm を選択します。NAME はターゲットレルムの名前に置き換えます。他のレルムへのアクセスをマスターレルムのユーザーに付与できます。
  5. Available Roles > manage-client を選択して、完全セットのクライアント管理パーミッションを付与します。別のオプションとして、読み取り専用 view-clients または create-client を選択して、新規クライアントを作成します。

    注記

    これらのパーミッションにより、初期アクセストークン または 登録アクセストークン を使用せずに操作を実行することができます。

realm-management ロールをユーザーに割り当てることはできません。この場合、ユーザーは引き続きクライアント登録 CLI でログインできますが、初期アクセストークンなしでは使用することはできません。トークンなしで操作を実行しようとすると、403 Forbidden エラーが発生します。

管理者は、Realm Settings > Client Registration > Initial Access Token メニューの Admin Console から、初期アクセストークンを実行できます。

6.2. クライアント登録 CLI で使用するクライアントの設定

デフォルトでは、サーバーはクライアント登録 CLI を admin-cli クライアントとして認識します。これは、新しいレルムごとに自動的に設定されます。ユーザー名を使用してログインする場合、追加のクライアント設定は必要ありません。

手順

  1. クライアント登録 CLI に別のクライアント設定を使用する場合は、クライアントを作成します (例: reg-cli)。
  2. Standard Flow Enabled の設定を Off に切り替えます。
  3. クライアントの Access TypeConfidential として設定し、Credentials > ClientId and Secret を選択してセキュリティーを強化します。

    注記

    Credentials タブで Client Id and Secret または Signed JWT のいずれかを設定できます。

  4. 管理コンソールClients セクションで編集するクライアントを選択して、クライアントに関連付けられたサービスアカウントを使用する場合は、サービスアカウントを有効にします。

    1. SettingsAccess TypeConfidential に変更し、Service Accounts Enabled 設定を On に切り替えて、Save をクリックします。
    2. Service Account Roles をクリックし、必要なロールを選択してサービスアカウントのアクセスを設定します。選択するロールの詳細は、「クライアント登録 CLI で使用する新しい一般ユーザーの設定」を参照してください。
  5. サービスアカウントの代わりに通常のユーザーアカウントを使用する場合は、Direct Access Grants Enabled の設定を On に切り替えます。
  6. クライアントが Confidential として設定されている場合は、--secret オプションを使用して kcreg config credentials を実行する際に設定されたシークレットを指定します。
  7. kcreg config credentials の実行時に使用する clientId (例: --client reg-cli)を指定します。
  8. サービスアカウントを有効にすると、kcreg config credentials の実行時にユーザーの指定を省略し、クライアントシークレットまたはキーストア情報のみを提供します。

6.3. クライアント登録 CLI のインストール

クライアント登録 CLI は Red Hat Single Sign-On Server ディストリビューション内にパッケージ化されています。bin ディレクトリー内に実行スクリプトを見つけることができます。Linux スクリプトは kcreg.sh と呼ばれ、Windows スクリプトは kcreg.bat と呼ばれます。

ファイルシステム上の任意の場所からクライアントを使用できるようにクライアントを設定する際に、Red Hat Single Sign-On サーバーディレクトリーを PATH に追加します。

たとえば、以下のようになります。

  • Linux:
$ export PATH=$PATH:$KEYCLOAK_HOME/bin
$ kcreg.sh
  • Windows:
c:\> set PATH=%PATH%;%KEYCLOAK_HOME%\bin
c:\> kcreg

KEYCLOAK_HOME は、Red Hat Single Sign-On Server ディストリビューションが展開されたディレクトリーを指定します。

6.4. クライアント登録 CLI の使用

手順

  1. 認証情報を使用してログインし、認証されたセッションを開始します。
  2. クライアント登録 REST エンドポイントでコマンドを実行します。

    たとえば、以下のようになります。

    • Linux:

      $ kcreg.sh config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli
      $ kcreg.sh create -s clientId=my_client -s 'redirectUris=["http://localhost:8980/myapp/*"]'
      $ kcreg.sh get my_client
    • Windows:

      c:\> kcreg config credentials --server http://localhost:8080/auth --realm demo --user user --client reg-cli
      c:\> kcreg create -s clientId=my_client -s "redirectUris=[\"http://localhost:8980/myapp/*\"]"
      c:\> kcreg get my_client
      注記

      実稼働環境では、https: で Red Hat Single Sign-On にアクセスする必要があります。これにより、トークンをネットワークスニファーに公開しないようにする必要があります。

  3. Java のデフォルト証明書トラストストアに含まれる信頼される認証局 (CA) のいずれかによってサーバーの証明書が発行されていない場合は、truststore.jks ファイルを準備し、クライアント登録 CLI にこれを使用するように指示します。

    たとえば、以下のようになります。

    • Linux:

      $ kcreg.sh config truststore --trustpass $PASSWORD ~/.keycloak/truststore.jks
    • Windows:

      c:\> kcreg config truststore --trustpass %PASSWORD% %HOMEPATH%\.keycloak\truststore.jks

6.4.1. ログイン

手順

  1. クライアント登録 CLI でログインするときに、サーバーエンドポイント URL およびレルムを指定します。
  2. ユーザー名またはクライアント ID を指定します。これにより、特別なサービスアカウントが使用されます。ユーザー名を使用する場合は、指定したユーザーのパスワードを使用する必要があります。クライアント ID を使用する場合は、パスワードの代わりにクライアントシークレットまたは 署名済み JWT を使用します。

ログイン方法に関係なく、ログインするアカウントには、クライアント登録操作を実行するための適切な権限が必要です。マスター以外のレルムのアカウントには、同じレルム内のクライアントを管理するためのパーミッションのみを持つことができる点に注意してください。異なるレルムを管理する必要がある場合は、異なるレルムで複数のユーザーを設定するか、master レルムで 1 つのユーザーを作成し、異なるレルムでクライアントを管理するロールを追加できます。

クライアント登録 CLI を使用してユーザーを設定することはできません。管理コンソールの Web インターフェースまたは Admin Client CLI を使用してユーザーを設定します。詳細は、Server Administration Guide を参照してください。

kcreg が 正常にログインすると、認証トークンを受け取り、プライベート設定ファイルに保存します。これにより、後続の呼び出しにトークンを使用できます。設定ファイルの詳細は、「代替設定の使用」を参照してください。

クライアント登録 CLI の使用方法についての詳細は、組み込みヘルプを参照してください。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh help
  • Windows:
c:\> kcreg help

認証セッションの開始に関する詳細は、kcreg config credentials --help を参照してください。

6.4.2. 代替設定の使用

デフォルトでは、クライアント登録 CLI は、ユーザーのホームディレクトリーにあるデフォルトの場所 (./.keycloak/kcreg.config) で設定ファイルを自動的に維持します。--config オプションを使用して異なるファイルまたは場所を指定し、複数の認証セッションを並行して管理することができます。単一のスレッドから、単一の設定ファイルに関連付けられる操作を実行するための最も安全な方法です。

重要

システム上の他のユーザーには、設定ファイルを表示しないでください。設定ファイルには、非公開にしておく必要のあるアクセストークンとシークレットが含まれています。

すべてのコマンドで --no-config オプションを使用すると、シークレットを設定ファイル内に格納しないようにすることができます。各 kcreg 呼び出しですべての認証情報を指定します。

6.4.3. 初期アクセスおよび登録アクセストークン

使用したい Red Hat Single Sign-On サーバーでアカウントを設定していない開発者は、クライアント登録 CLI を使用できます。これは、レルム管理者が開発者に初期アクセストークンを発行した場合にのみ可能です。これらのトークンを発行および配布する方法と時期を決定するのは、レルム管理者の責任になります。レルム管理者は、初期アクセストークンの最大有効期間と、それを使用して作成できるクライアントの総数を制限できます。

開発者に初期アクセストークンがある場合、開発者は kcreg config credentials で認証せずにこれを使用して新規クライアントを作成することができます。初期アクセストークンは、設定ファイルに保存するか、kcreg create コマンドの一部として指定できます。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh config initial-token $TOKEN
$ kcreg.sh create -s clientId=myclient

または

$ kcreg.sh create -s clientId=myclient -t $TOKEN
  • Windows:
c:\> kcreg config initial-token %TOKEN%
c:\> kcreg create -s clientId=myclient

または

c:\> kcreg create -s clientId=myclient -t %TOKEN%

初期アクセストークンを使用する場合、サーバーの応答には、新しく発行された登録アクセストークンが含まれます。そのクライアントの後続の操作は、そのトークンで認証することで実行する必要があります。これは、そのクライアントに対してのみ有効です。

クライアント登録 CLI は、プライベート設定ファイルを自動的に使用して、このトークンを保存し、関連付けられたクライアントで使用します。同じ設定ファイルがすべてのクライアント操作に使用される限り、開発者はこの方法で作成されたクライアントの読み取り、更新、または削除を行うために認証する必要はありません。

初期アクセスおよび登録アクセストークンの詳細は、「クライアント登録」を参照してください。

クライアント登録 CLI でトークンを設定する方法についての詳細は、kcreg config initial-token --help コマンドおよび kcreg config registration-token --help コマンドを実行してください。

6.4.4. クライアント設定の作成

通常、認証情報を使用して認証するか、初期アクセストークンを設定した後の最初のタスクは、新しいクライアントを作成することです。多くの場合、準備した JSON ファイルをテンプレートとして使用し、一部の属性を設定したり、上書きすることをお勧めします。

以下の例は、JSON ファイルの読み取り、含まれる可能性のあるクライアント ID の上書き、その他の属性の設定、正常な作成後に設定を標準出力に出力する方法を示しています。

  • Linux:
$ kcreg.sh create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s 'redirectUris=["/myclient/*"]' -o
  • Windows:
C:\> kcreg create -f client-template.json -s clientId=myclient -s baseUrl=/myclient -s "redirectUris=[\"/myclient/*\"]" -o

kcreg create コマンドの詳細は、kcreg create --help を実行します。

kcreg attrs を使用して利用可能な属性を一覧表示できます。多くの設定属性は、有効性または一貫性についてチェックされないことに注意してください。適切な値を指定することが推奨されます。テンプレートに id フィールドを使用せず、kcreg create コマンドに引数として指定しないでください。

6.4.5. クライアント設定の取得

kcreg get コマンドを使用して、既存のクライアントを取得できます。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh get myclient
  • Windows:
C:\> kcreg get myclient

クライアント設定をアダプター設定ファイルとして取得することもできます。これは Web アプリケーションでパッケージ化できます。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh get myclient -e install > keycloak.json
  • Windows:
C:\> kcreg get myclient -e install > keycloak.json

kcreg get コマンドの詳細は、kcreg get --help コマンドを実行してください。

6.4.6. クライアント設定の変更

クライアント設定の更新方法は 2 つあります。

1 つの方法は、現在の設定を取得してファイルに保存し、編集してサーバーにポストバックした後に、完全に新しい状態をサーバーに送信することです。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh get myclient > myclient.json
$ vi myclient.json
$ kcreg.sh update myclient -f myclient.json
  • Windows:
C:\> kcreg get myclient > myclient.json
C:\> notepad myclient.json
C:\> kcreg update myclient -f myclient.json

2 つ目の方法は、現在のクライアントをフェッチし、そのクライアントのフィールドを設定または削除して、1 つのステップでポストバックします。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh update myclient -s enabled=false -d redirectUris
  • Windows:
C:\> kcreg update myclient -s enabled=false -d redirectUris

適用する変更のみを含むファイルを使用することもできるため、引数として値を多く指定する必要はありません。この場合は、--merge を指定して、JSON ファイルを完全かつ新規の設定として処理するのではなく、既存の設定に適用する属性セットとして処理する必要があることをクライアント登録 CLI に指示します。

たとえば、以下のようになります。

  • Linux:
$ kcreg.sh update myclient --merge -d redirectUris -f mychanges.json
  • Windows:
C:\> kcreg update myclient --merge -d redirectUris -f mychanges.json

kcreg update コマンドの詳細は、kcreg update --help コマンドを実行してください。

6.4.7. クライアント設定の削除

クライアントを削除するには、以下の例を使用します。

  • Linux:
$ kcreg.sh delete myclient
  • Windows:
C:\> kcreg delete myclient

kcreg delete コマンドの詳細は、kcreg delete --help コマンドを実行してください。

6.4.8. 無効な登録アクセストークンの更新

--no-config モードを使用して作成、読み取り、更新、および削除 (CRUD) 操作を実行すると、クライアント登録 CLI はユーザーの登録アクセストークンを処理できません。この場合、クライアントに対して最近発行した Registration Access Token の追跡できなくなる可能性があり、manage-clients パーミッションを持つアカウントで認証を行わずに、そのクライアントでの CRUD 操作を追加で実行できなくなります。

パーミッションがある場合は、クライアントの新しい登録アクセストークンを発行し、標準出力に出力したり、任意の設定ファイルに保存したりできます。それ以外の場合は、レルム管理者に、クライアント用の新しい登録アクセストークンを発行して送信するよう依頼する必要があります。--token オプションを使用して、これをすべての CRUD コマンドに渡すことができます。kcreg config registration-token コマンドを使用して新規トークンを設定ファイルに保存し、クライアント登録 CLI にこの時点から自動的に処理させることもできます。

kcreg update-token コマンドの詳細は、kcreg update-token --help コマンドを実行してください。

6.5. トラブルシューティング

  • Q: ログイン時にエラーが表示されます: Parameter client_assertion_type is missing [invalid_client]

    A: このエラーは、クライアントが Signed JWT トークン認証情報で設定されていることを意味します。つまり、ログイン時に --keystore パラメーターを使用する必要があります。

第7章 トークン交換の使用

注記

トークンの交換は テクノロジープレビュー であるため、完全にサポートされていません。この機能はデフォルトでは無効になっています。

-Dkeycloak.profile=preview または -Dkeycloak.profile.feature.token_exchange=enabled でサーバーの起動を有効にするには、以下を行います、詳細は、「Profiles」を参照してください。

注記

トークン交換を使用するには、token_exchange 機能も有効にする必要があります。「Profiles」を参照してください。

7.1. トークン交換の仕組み

Red Hat Single Sign-On では、トークン交換は、一連の認証情報またはトークンを使用して、まったく異なるトークンを取得するプロセスです。クライアントは、信頼性の低いアプリケーションで呼び出したい場合があるため、現在のトークンをダウングレードしたい場合があります。クライアントは、Red Hat Single Sign-On トークンをリンクされたソーシャルプロバイダーアカウント用に保存されているトークンと交換したい場合があります。他の Red Hat Single Sign-On レルムまたは外部 IDP によって作成された外部トークンを信頼することをお勧めします。クライアントでは、ユーザーの権限を借用しなければならない場合があります。以下は、トークン交換に関する Red Hat Single Sign-On の現在の機能の概要です。

  • クライアントは、特定のクライアント用に作成された既存の Red Hat Single Sign-On トークンを、別のクライアントを対象とする新しいトークンと交換できます。
  • クライアントは、既存の Red Hat Single Sign-On トークンを外部トークン (リンクされた Facebook アカウントなど) と交換できます。
  • クライアントは、外部トークンを、Red Hat Single Sign-On トークンと交換できます。
  • クライアントはユーザーの権限を借用できます。

Red Hat Single Sign-On でのトークン交換は、IETF での OAuth トークン交換 仕様の非常に大まかな実装になります。この仕様を少し拡張し、一部を無視して、他の部分は大まかに解釈しました。これは、レルムの OpenID Connect トークンエンドポイントにおける単純な付与タイプ呼び出しです。

/auth/realms/{realm}/protocol/openid-connect/token

これは、フォームパラメーター (application/x-www-form-urlencoded) を入力として受け付け、出力は交換を要求したトークンのタイプによって異なります。トークン交換はクライアントエンドポイントであるため、リクエストは呼び出し元のクライアントに対して認証情報を提供する必要があります。パブリッククライアントは、クライアント識別子を form パラメーターとして指定します。機密クライアントは、フォームパラメータを使用して、クライアント ID とシークレット、Basic 認証、または管理者がレルムで設定したクライアント認証フローを渡すこともできます。

7.1.1. フォームパラメーター

client_id
必須の可能性あり。このパラメーターは、認証にフォームパラメーターを使用するクライアントに必要です。Basic 認証、クライアント JWT トークン、またはクライアント証明書認証を使用している場合は、このパラメーターを指定しないでください。
client_secret
必須の可能性あり。このパラメーターは、認証にフォームパラメーターを使用し、認証情報としてクライアントシークレットを使用するクライアントに必要です。レルムのクライアント呼び出しが別の手段で認証されている場合は、このパラメーターは指定しないでください。
grant_type
必須。パラメーターの値は urn:ietf:params:oauth:grant-type:token-exchange にする必要があります。
subject_token
任意です。リクエストが行われている当事者の ID を表すセキュリティトークン。これは、既存のトークンを新しいトークンと交換する場合に必要です。
subject_issuer
任意です。subject_token の発行者を特定します。トークンが現在のレルムから送信される場合や、発行者が subject_token_type から判断できる場合は空白のままにすることができます。それ以外の場合は指定する必要があります。有効な値は、レルムに設定された ID プロバイダー のエイリアスです。または、特定の ID プロバイダー によって設定された発行者要求 ID です。
subject_token_type
任意です。このパラメーターは、subject_token パラメーターで渡されるトークンのタイプです。subject_token がレルムから取得され、アクセストークンである場合、デフォルトは urn:ietf:params:oauth:token-type:access_token に設定されます。外部トークンの場合には、subject_issuer の要件に応じてこのパラメーターを指定する必要がある場合とそうでない場合があります。
requested_token_type
任意です。このパラメーターは、クライアントが交換するトークンのタイプを表します。現在、oauth および OpenID Connect トークンタイプのみがサポートされます。このデフォルト値は urn:ietf:params:oauth:token-type:refresh_token であるかどうかによって異なります。この場合、応答内でアクセストークンと更新トークンの両方が返されます。その他の適切な値は、urn:ietf:params:oauth:token-type:access_token および urn:ietf:params:oauth:token-type:id_tokenです。
audience
任意です。このパラメーターは、新しいトークンを作成するターゲットクライアントを指定します。
requested_issuer
任意です。このパラメーターは、クライアントが外部プロバイダーによって作成されたトークンを必要とすることを指定します。レルム内で設定された ID プロバイダー のエイリアスである必要があります。
requested_subject
任意です。これは、クライアントが別のユーザーになりすます場合のユーザー名またはユーザー ID を指定します。
scope
実装ない。このパラメーターは、クライアントが要求する OAuth および OpenID Connect スコープのターゲットセットを表します。現時点では実装されていませんが、Red Hat Single Sign-On がスコープ全般をより適切にサポートするようになると実装されます。
注記

現在、OpenID Connect および OAuth の交換のみをサポートします。SAML ベースのクライアントおよびアイデンティティープロバイダーのサポートは、ユーザーの需要に応じて今後追加される可能性があります。

7.1.2. トークン交換要求からの応答

交換呼び出しからの正常な応答は、クライアントが要求する requested-token-typerequested_issuer に依存するコンテンツタイプを含む HTTP 200 応答コードを返します。OAuth が要求するトークンタイプは、OAuth Token Exchange 仕様で説明されているように、JSON ドキュメントを返します。

{
   "access_token" : ".....",
   "refresh_token" : ".....",
   "expires_in" : "...."
 }

更新トークンを要求するクライアントは、応答でアクセストークンと更新トークンの両方を返します。アクセストークンタイプのみを要求するクライアントは、応答でアクセストークンのみを取得します。requested_issuer パラメーターを介して外部発行者を要求するクライアントの有効期限情報は、含まれる場合とそうでない場合があります。

通常、エラー応答は 400 HTTP 応答コードカテゴリーに分類されますが、エラーの重大度に応じて他のエラーステータスコードが返される場合があります。エラー応答には、requested_issuer に依存するコンテンツが含まれる場合があります。OAuth ベースの交換では、以下のように JSON ドキュメントが返される場合があります。

{
   "error" : "...."
   "error_description" : "...."
}

交換タイプに応じて、追加のエラークレームを返すことができます。たとえば、ユーザーに ID プロバイダーへのリンクがない場合に、OAuth ID プロバイダーには追加の account-link-url 要求が含まれる場合があります。このリンクは、クライアントが開始したリンク要求に使用できます。

注記

トークンの交換の設定には、きめ細かな管理パーミッションに関する知識が必要です (詳細は、Server Administration Guide を参照)。交換にクライアントパーミッションを付与する必要があります。これについては、この章で後ほど説明します。

この章の残りの部分では、セットアップ要件について説明し、さまざまな交換シナリオの例を示します。分かりやすくするために、現在のレルムで作成された最小のトークンを 内部 トークンとして呼び出し、外部レルムまたは ID プロバイダーによって作成されたトークンを 外部 トークンと呼ぶことにします。

7.2. 内部トークンから内部トークンへの交換

内部のトークンからトークンへの交換では、特定のクライアントに作成された既存のトークンがあり、このトークンを別のターゲットクライアントに作成された新しいトークンと交換する必要があります。これを実行する理由これは通常、クライアントが自身のために作成したトークンを持っており、アクセストークン内で異なるクレームとパーミッションを必要とする他のアプリケーションに追加の要求を行う必要がある場合に発生します。このタイプの交換が必要となるかもしれないその他の理由は、アプリが信頼性の低いアプリで呼び出す必要があり、現在のアクセストークンを伝播したくない場合の「パーミッションのダウングレード」を実行する必要がある場合です。

7.2.1. 交換のパーミッションの付与

別のクライアントのトークンを交換する必要のあるクライアントは、管理コンソールで承認される必要があります。交換するパーミッションを付与するクライアントに、token-exchange の細かいパーミッションを定義する必要があります。

ターゲットクライアントパーミッション

Target Client Permission

手順

  1. Permissions EnabledON に切り替えます。

    ターゲットクライアントパーミッション

    exchange target client permission set

    そのページには、token-exchange のリンクが表示されます。

  2. そのリンクをクリックして、パーミッションの定義を開始します。

    このセットアップページが表示されます。

    ターゲットクライアント交換のパーミッション設定

    Target Client Exchange Permission Setup

  3. Authorization のリンクをクリックして、このパーミッションのポリシーを定義します。
  4. Policies タブをクリックします。
  5. クライアントポリシーを作成します。

    クライアントポリシーの作成

    exchange target client policy

  6. トークン交換を要求する認証されたクライアントである、開始クライアントを入力します。
  7. このポリシーを作成したら、ターゲットクライアントの token-exchange パーミッションに戻り、定義したクライアントポリシーを追加します。

    クライアントポリシーの適用

    exchange target client exchange apply policy

これでクライアントを呼び出すパーミッションがある。これを正しく行わないと、エクスチェンジを作成しようとすると、403 Forbidden 応答が返されます。

7.2.2. リクエストの作成

クライアントが、既存のトークンを他のクライアントをターゲットにしたトークンと交換する場合は、audience パラメーターを使用します。このパラメーターは、管理コンソールで設定したターゲットクライアントのクライアント識別子である必要があります。

curl -X POST \
    -d "client_id=starting-client" \
    -d "client_secret=the client secret" \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    -d "subject_token=...." \
    --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:refresh_token" \
    -d "audience=target-client" \
    http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

subject_token パラメーターは、ターゲットレルムのアクセストークンである必要があります。requested_token_type パラメーターが更新トークンタイプである場合、応答にはアクセストークン、更新トークン、および有効期限が含まれます。以下は、この呼び出しから返される JSON 応答の例です。

{
   "access_token" : "....",
   "refresh_token" : "....",
   "expires_in" : 3600
}

7.3. 内部トークンから外部トークンへの交換

レルムトークンを、外部 ID プロバイダーによって作成された外部トークンと交換できます。この外部 ID プロバイダーは、管理コンソールの ID プロバイダー セクション内で設定する必要があります。現時点で、OAuth/OpenID Connect ベースの外部 ID プロバイダーのみがサポートされます。これには、すべてのソーシャルプロバイダーが含まれます。Red Hat Single Sign-On は、外部プロバイダーへのバックチャネル交換を実行しません。そのため、アカウントがリンクされていない場合は、外部トークンを取得できなくなります。これらの条件の 1 つの外部トークンを取得できるようにするには、以下の条件を満たしている必要があります。

  • ユーザーは、少なくとも 1 回、外部 ID プロバイダーを使用してログインしている必要があります。
  • ユーザーは、ユーザーアカウントサービスを使用して、外部 ID プロバイダーとリンクされている必要があります。
  • このユーザーアカウントは、クライアント開始アカウントリンク API を使用して、外部の ID プロバイダー経由でリンクされました。

最後に、外部 ID プロバイダーがトークンを保存するように設定されている必要があります。または、上記のアクションの 1 つが、交換する内部トークンと同じユーザーセッションで実行されている必要があります。

アカウントがリンクされていない場合、交換応答には、アカウントを確立するために使用できるリンクが含まれます。詳細は、「リクエストの作成」セクションで説明されています。

7.3.1. 交換のパーミッションの付与

内部から外部へのトークン交換要求は、外部 ID プロバイダーとトークンを交換できるパーミッションを呼び出し元のクライアントに付与するまで、403、Forbidden 応答で拒否されます。クライアントにパーミッションを付与するには、ID プロバイダーの設定ページの Permissions タブに移動します。

ID プロバイダーパーミッション

exchange idp permission unset

手順

  1. Permissions EnabledON に切り替えます。

    ID プロバイダーパーミッション

    exchange idp permission set

    ページには、token-exchange のリンクが表示されます。

  2. リンクをクリックして、パーミッションの定義を開始します。

    このセットアップページが表示されます。

    アイデンティティープロバイダー交換のパーミッション設定

    Identity Provider Exchange Permission Setup

  3. Authorization のリンクをクリックし、Policies タブに移動し、クライアントポリシーを作成します。

    クライアントポリシーの作成

    Client Policy Creation

  4. トークン交換を要求する認証されたクライアントである、開始クライアントを入力します。
  5. ID プロバイダーの token-exchange パーミッションに戻り、定義したクライアントポリシーを追加します。

    クライアントポリシーの適用

    Apply Client Policy

これでクライアントを呼び出すパーミッションがある。これを正しく行わないと、エクスチェンジを作成しようとすると、403 Forbidden 応答が返されます。

7.3.2. リクエストの作成

クライアントが既存の内部トークンを外部に交換する場合には、requested_issuer パラメーターを指定します。このパラメーターは、設定済みのアイデンティティープロバイダーのエイリアスである必要があります。

curl -X POST \
    -d "client_id=starting-client" \
    -d "client_secret=the client secret" \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    -d "subject_token=...." \
    --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
    -d "requested_issuer=google" \
    http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

subject_token パラメーターは、ターゲットレルムのアクセストークンである必要があります。requested_token_type パラメーターは urn:ietf:params:oauth:token-type:access_token であるか、空欄のままにする必要があります。現時点では、他の要求されたトークンタイプはサポートされません。以下は、この呼び出しから返される正常な JSON 応答の例です。

{
   "access_token" : "....",
   "expires_in" : 3600
   "account-link-url" : "https://...."
}

外部 ID プロバイダーが何らかの理由でリンクされていない場合、以下の JSON ドキュメントで HTTP 400 応答コードが表示されます。

{
   "error" : "....",
   "error_description" : "..."
   "account-link-url" : "https://...."
}

error 要求は、token_expired または not_linked のいずれかになります。クライアントが クライアント開始アカウントリンク を実行できるように、account-link-url 要求が提供されます。ほとんど(あるいはすべて)のプロバイダーでは、ブラウザー OAuth プロトコルを使用したリンクが必要です。account-link-url では、単に redirect_uri クエリーパラメーターを追加し、ブラウザーに転送してリンクを実行できます。

7.4. 外部トークンから内部トークンへの交換

内部トークンの外部 ID プロバイダーが作成した外部トークンを信頼し、交換できます。これはレルム間をブリッジしたり、ソーシャルプロバイダーからのトークンを信頼したりするために使用できます。新しいユーザーが存在しない場合はレルムにインポートされるという点で、ID プロバイダーのブラウザーログインと同様に機能します。

注記

外部トークン交換に関する現在の制限として、外部トークンが既存のユーザーにマップされている場合、既存のユーザーが外部 ID プロバイダーへのアカウントリンクを既に持っていない限り、交換が許可されない点があります。

交換が完了すると、レルム内にユーザーセッションが作成され、requested_token_type パラメーターの値に応じてアクセストークンおよび更新トークンが送信されます。この新しいユーザーセッションは、タイムアウトするまで、またはこの新しいアクセストークンを渡すレルムのログアウトエンドポイントを呼び出すまで、アクティブなままである点に注意してください。

これらのタイプの変更には、管理コンソールで構成済みのアイデンティティープロバイダーが必要でした。

注記

SAML アイデンティティープロバイダーは現時点ではサポートされていません。Twitter トークンも交換できません。

7.4.1. 交換のパーミッションの付与

外部トークン交換を行う前に、呼び出し元のクライアントに交換を行うためのパーミッションを与えます。このパーミッションは、内部から外部へのパーミッションが付与されている のと同じ方法で付与されます。

呼び出し以外のクライアントを参照する値を持つ audience パラメーターを指定する場合、audience パラメーターに固有のターゲットクライアントに交換するための呼び出しクライアントのパーミッションも付与する必要があります。これを行う方法は、このセクションで 上述 されています。

7.4.2. リクエストの作成

subject_token_type は、urn:ietf:params:oauth:token-type:access_token または urn:ietf:params:oauth:token-type:jwt のいずれかである必要があります。タイプが urn:ietf:params:oauth:token-type:access_token の場合は、subject_issuer パラメーターを指定する必要があります。これは設定された ID プロバイダーのエイリアスです。タイプが urn:ietf:params:oauth:token-type:jwt の場合、プロバイダーは、プロバイダーのエイリアスである JWT 内の 発行者 要求、またはプロバイダー設定の登録済み発行者を介して照合されます。

検証のために、トークンがアクセストークンである場合、プロバイダーのユーザー情報サービスが呼び出されてトークンが検証されます。呼び出しに成功すると、アクセストークンが有効であることを意味します。サブジェクトトークンが JWT であり、プロバイダーで署名検証が有効になっている場合は、それが試行されます。それ以外の場合は、デフォルトでユーザー情報サービスも呼び出してトークンを検証します。

デフォルトでは、作成された内部トークンは、呼び出し元のクライアントを使用して、呼び出し元のクライアント用に定義されたプロトコルマッパーを使用してトークンの内容を判別します。または、audience パラメーターを使用して別のターゲットクライアントを指定することもできます。

curl -X POST \
    -d "client_id=starting-client" \
    -d "client_secret=the client secret" \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    -d "subject_token=...." \
    -d "subject_issuer=myOidcProvider" \
    --data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
    -d "audience=target-client" \
    http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

requested_token_type パラメーターが更新トークンタイプである場合、応答にはアクセストークン、更新トークン、および有効期限が含まれます。以下は、この呼び出しから返される JSON 応答の例です。

{
   "access_token" : "....",
   "refresh_token" : "....",
   "expires_in" : 3600
}

7.5. 権限借用

内部トークンと外部トークン交換の場合、クライアントは、ユーザーに代わって別のユーザーになりすますように要求できます。たとえば、サポートエンジニアが問題をデバッグできるように、ユーザーになりすます必要のある管理アプリケーションがある場合などです。

7.5.1. 交換のパーミッションの付与

サブジェクトトークンが表すユーザーには、他のユーザーになりすますためのパーミッションが必要です。このパーミッションを有効にする方法は、Server Administration Guide を参照してください。これは、ロールまたは粒度の細かい管理者権限を介して実行できます。

7.5.2. リクエストの作成

requested_subject パラメーターを追加で指定しない限り、他の章の説明どおりに要求を行います。このパラメーターの値は、ユーザー名またはユーザー ID である必要があります。

curl -X POST \
    -d "client_id=starting-client" \
    -d "client_secret=the client secret" \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    -d "subject_token=...." \
    --data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
    -d "audience=target-client" \
    -d "requested_subject=wburke" \
    http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

7.6. ダイレクトの Naked Impersonation

subject_token を指定せずに内部トークン交換要求を行うことができます。これは、クライアントがレルム内の任意のユーザーになりすますことができるため、クライアントに多くの信頼を置くことから、ダイレクトの Naked Impersonation と呼ばれます。交換するサブジェクトトークンを取得できないアプリケーションをブリッジするために、これが必要になる場合があります。たとえば、LDAP と直接ログインを実行するレガシーアプリケーションを統合している場合があります。この場合、レガシーアプリケーションはユーザー自身を認証できますが、トークンを取得することはできません。

警告

クライアントにダイレクトの Naked Impersonation を有効にすることは非常に危険です。クライアントの認証情報が盗まれた場合、そのクライアントは、システム内の任意のユーザーになりすますことができます。

7.6.1. 交換のパーミッションの付与

audience パラメーターを指定すると、呼び出し元のクライアントにはクライアントへの交換パーミッションが必要です。これを設定する方法については、この章の前半で説明しています。

さらに、呼び出し元のクライアントには、ユーザーになりすますためのアクセス許可を付与する必要があります。管理コンソールにおいて

手順

  1. メニューの Users をクリックします。
  2. Permissions タブをクリックします。

    ユーザー権限

    User Permissions

  3. Permissions Enabled を true に切り替えます。

    ID プロバイダーパーミッション

    exchange users permission set

    ページには、impersonation のリンクが表示されます。

  4. そのリンクをクリックして、パーミッションの定義を開始します。

    このセットアップページが表示されます。

    ユーザーのなりすましパーミッションの設定

    Users Impersonation Permission Setup

  5. Authorization のリンクをクリックします。
  6. Policies タブに移動し、クライアントポリシーを作成します。

    クライアントポリシーの作成

    Client Policy Creation

  7. トークン交換を要求する認証されたクライアントである、開始クライアントを入力します。
  8. ユーザーの impersonation パーミッションに戻り、定義したクライアントポリシーを追加します。

    クライアントポリシーの適用

    Apply Client Policy

クライアントには、ユーザーの権限を借用できるパーミッションがあります。これを正しく行わないと、このタイプの交換を行おうとすると、403 Forbidden 応答が返されます。

注記

パブリッククライアントは、ダイレクトの Naked Impersonation を行うことはできません。

7.6.2. リクエストの作成

要求を行うには、requested_subject パラメーターを指定します。これは、有効なユーザーのユーザー名またはユーザー ID である必要があります。必要に応じて、audience パラメーターを指定することもできます。

curl -X POST \
    -d "client_id=starting-client" \
    -d "client_secret=the client secret" \
    --data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
    -d "requested_subject=wburke" \
    http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token

7.7. サービスアカウントでアクセス許可モデルを展開

クライアントに交換のパーミッションを与える場合、必ずしもすべてのクライアントに対してそれらのパーミッションを手動で有効にしません。クライアントにサービスアカウントが関連付けられている場合、ロールを使用してパーミッションをグループ化し、クライアントのサービスアカウントにロールを割り当てることで交換パーミッションを割り当てることができます。たとえば、naked-exchange ロールと、そのロールを持つサービスアカウントが、そのままの交換を実行できるように定義することができます。

7.8. 交換の脆弱性

トークン交換を許可し始める際に、認識し、注意しなければならないさまざまなことがあります。

1 つ目はパブリッククライアントです。パブリッククライアントは、交換を実行するためのクライアント認証情報を持っていないか、またはこれを必要としません。有効なトークンを持つ Note は、パブリッククライアントに なりすまし て、パブリッククライアントが実行可能な交換を実行できます。レルムが管理するクライントで信頼できないクライアントが存在する場合、パブリッククライアントはパーミッションモデルに脆弱性を開放する可能性があります。この理由により、ダイレクトの Naked 交換は、パブリッククライアントを許可せず、呼び出し元のクライアントがパブリックの場合にエラーを表示して中止します。

Facebook や Google などが提供するソーシャルトークンをレルムトークンと交換することができます。これらのソーシャル Web サイトで、偽のアカウントを作成することは難しくないため、交換トークンで許可されていることには注意し、慎重に対応してください。デフォルトのロール、グループ、およびアイデンティティープロバイダーマッパーを使用して、外部のソーシャルユーザーに割り当てられた属性とロールを制御します。

ダイレクトの Naked の交換は非常に危険です。クライアントの認証情報をリークしない呼び出し元のクライアントに多大な信頼を置いています。これらの認証情報がリークされる場合、盗む側はシステム内の誰かになりすますことができます。これは、既存のトークンを持つ機密クライアントと直接対照的です。認証には、アクセストークンとクライアント認証情報の 2 つの要素があり、1 人のユーザーのみを処理します。したがって、ダイレクトの Naked の交換は控えめに使用してください。