1. 概要
Keycloakはきめ細かい認可ポリシーをサポートし、以下のような異なるアクセス・コントロール機構を組み合わせることができます。
-
属性ベースのアクセス・コントロール(ABAC)
-
ロールベースのアクセス・コントロール(RBAC)
-
ユーザーベースのアクセス・コントロール(UBAC)
-
コンテキストベースのアクセス・コントロール(CBAC)
-
ルールベースのアクセス・コントロール
-
Javascriptを使用
-
JBoss Droolsを使用
-
-
時間ベースのアクセス・コントロール
-
ポリシー・プロバイダー・サービス・プロバイダー・インターフェイス(SPI)によるカスタム・アクセス・コントロール機構(ACMs)のサポート
Keycloakは管理UIとRESTful APIのセットに基づいており、保護されるリソースとスコープのアクセス許可を作成し、そのアクセス許可を認可ポリシーに関連づけ、アプリケーションやサービスで認可判断を行うために必要な手段を提供します。
保護されたリソースへのアクセスを許可するかどうかを判定するために、リソースサーバー(保護されたリソースを処理するアプリケーションまたはサービス)は、通常、何らかの情報に依存しています。RESTfulベースのリソースサーバーの場合、通常、その情報はセキュリティトークンから取得されます。そのトークンは、通常、サーバーへのリクエストごとにベアラートークンとして送信されます。ユーザーを認証するためにセッションに依存するWebアプリケーションの場合、通常、その情報はユーザーのセッションに格納され、リクエストごとにそこから取得されます。
多くの場合、リソースサーバーはロールベースのアクセス・コントロール(RBAC)に基づいて認可判断のみを行います。ロールベースのアクセス・コントロールでは、保護されたリソースにアクセスしようとするユーザーに付与されたロールが、同リソースにマップされたロールに対してチェックされます。ロールは非常に有用でアプリケーションで使用されますが、以下のようないくつかの制限もあります。
-
リソースとロールは密結合されており、ロールへの変更(アクセス・コンテキストの追加、削除、変更など)は複数のリソースに影響を与える可能性があります。
-
セキュリティ要件の変更は、反映するにはアプリケーション・コードに大幅な変更が必要となるでしょう。
-
アプリケーションのサイズによっては、ロール管理が困難になり、エラーを起こしやすくなる可能性があります。
-
これは最も柔軟なアクセス・コントロール機構ではありません。ロールは、誰であるかを表すものではなく、コンテキスト情報が欠けています。ロールが付与されているということは、少なくともいくらかのアクセス権を持っている、ということを表すだけです。
今日、ユーザーは異なるローカルポリシーの異なる地域におり、異なるデバイスを使用し、情報共有のニーズが高い異種環境を考慮する必要があります。Keycloak認可サービスは以下を提供し、アプリケーションやサービスの認可機能を向上させるのに役立つでしょう。
-
きめ細かい認可ポリシーと異なるアクセス・コントロール機構を使用したリソース保護
-
一元的なリソース、アクセス許可、およびポリシー管理
-
一元的なポリシー決定点
-
一連のRESTベースの認可サービスに基づくRESTセキュリティ
-
認可ワークフローとUser-Managed Access
-
プロジェクト間でのコードの複製(と再デプロイ)を防止し、セキュリティ要件の変更に迅速に対応するのに役立つ基盤
1.1. アーキテクチャー
設計の観点から、認可サービスは、明確に定義された認可パターンのセットに基づいて次の機能を提供します。
-
ポリシー管理ポイント(PAP)
リソースサーバー、リソース、スコープ、パーミッション、およびポリシーを管理するためのKeycloak管理コンソールに基づいたUIのセットを提供します。このうちの一部は、保護APIを使用してリモートでも実現できます。
-
ポリシー決定点(PDP)
認可リクエストが送信され、リクエストが許可されることでポリシーが評価される場所に配布可能なポリシー決定点を提供します。このうちの一部は、エンタイトルメントAPIを使用してリモートでも実現されます。
-
ポリシー実施ポイント(PEP)
異なる環境に実装を提供し、リソースサーバー側で実際に認可の決定を実施します。Keycloakには、組み込みのポリシー・エンフォーサーが用意されています。
-
ポリシー情報ポイント(PIP)
Keycloak認証サーバーに基づいて、認可ポリシーの評価中にアイデンティティーとラインタイム環境から属性を取得できます。
1.1.1. 認可プロセス
Keycloakを使用してアプリケーションにきめ細かな権限を与える方法を、理解するために必要な手順を定義する3つの主要なプロセスは、以下のとおりです。
-
リソース管理
-
パーミッションとポリシーの管理
-
ポリシーの実施
リソース管理
リソース管理 には、何が保護されているかを定義するために必要なすべてのステップが含まれます。
まず、保護しようとしているものをKeycloakに指定する必要があります。これは通常、Webアプリケーションまたは1つ以上のサービスのセットを表します。リソース・サーバーの詳細については、用語集を参照してください。
リソース・サーバーは、Keycloak管理コンソールを使用して管理されます。そこで、登録されたクライアント・アプリケーションをリソース・サーバーとして有効にし、保護するリソースとスコープの管理を開始できます。
リソースには、Webページ、RESTFulリソース、ファイルシステム内のファイル、EJBなどがあります。それらはリソースのグループ(Javaのクラスと同様)、または単一の特定のリソースを表すことができます。
例えば、すべての銀行口座を表す Bank Account リソースを持ったとして、それを使用してすべての銀行口座に共通する認可ポリシーを定義することができます。ただし、 Alice Account (顧客に属しているリソース・インスタンス)に対して特定のポリシーを定義したい場合は、オーナーだけが情報にアクセスしたり、操作を実行することができます。
リソースは、Keycloak管理コンソールまたは保護APIを使用して管理できます。後者の場合、リソースサーバーはリソースをリモートで管理できます。
スコープは、通常、リソースに対して実行できるアクションを表しますが、これに限定されるものではありません。スコープを使用して、リソース内の1つ以上の属性を表すこともできます。
権限とポリシーの管理
リソースサーバーと保護するすべてのリソースを定義したら、パーミッションとポリシーを設定する必要があります。
このプロセスには、リソースを管理するセキュリティおよびアクセス要件を実際に定義するために必要なすべての手順が含まれます。
ポリシーは、何か(リソースまたはスコープ)へのアクセスや操作を実行するために満たす条件を定義しますが、保護しているものとは結びついていません。これらは一般的なもので、パーミッションやさらに複雑なポリシーを構築するために再利用することができます。
例えば、ロール"User Premium"が付与されたユーザーに対してのみリソースのグループへのアクセスを許可するために、RBAC(ロールベースのアクセス・コントロール)を使用できます。
Keycloakには、最も一般的なアクセス・コントロール機構をカバーするいくつかの組み込みのポリシー・タイプ(およびそれぞれのポリシー・プロバイダー)が用意されています。JavaScriptやJBoss Droolsを使用して作成されたルールに基づいてポリシーを作成することもできます。
ポリシーを定義したら、パーミッションの定義を開始できます。パーミッションは、保護しているリソースと結合されます。ここでは、保護する対象(リソースまたはスコープ)と、パーミッションを許可または拒否するために満たす必要のあるポリシーを指定します。
ポリシー実施
Policy Enforcement には、リソースサーバーへの認可の決定を実際に実施するために必要な手順が含まれます。これは、認可サーバーと通信できるリソース・サーバーで Policy Enforcement Point またはPEPを有効にし、サーバーによって返された決定とパーミッションに基づいて認可データを要求し、保護されたリソースへのアクセスを制御することによって実現されます。
Keycloakには、実行中のプラットフォームに応じてアプリケーションを保護するために使用できる組み込みのポリシー・エンフォーサー実装がいくつか用意されています。
1.1.2. 認可サービス
認可サービスは以下のRESTFul APIで構成されています。
-
保護API
-
認可API
-
エンタイトルメントAPI
これらの各サービスは、認可プロセスに関わるさまざまなステップをカバーする特定のAPIを提供します。
保護API
保護APIは、リソースサーバーがリソースとスコープを管理するのに役立つ細かい一連の操作を提供する、 UMA準拠 のエンドポイントです。リソースサーバーだけがこのAPIにアクセスできますが、 uma_protection スコープも必要です。
保護APIによって提供される操作は、次の2つの主要なグループに分けられます。
-
リソース管理
-
リソースの作成
-
リソースの削除
-
IDで検索
-
全検索
-
フィルタで検索(例えば、名前、タイプ、またはURIで検索)
-
-
パーミッション管理
-
パーミッション・チケットの発行
-
デフォルトでは、リモートリソース管理が有効になっています。Keycloak管理コンソールを使用して変更することができ、コンソールからのリソース管理のみを許可できます。 |
UMAプロトコルを使用する場合、保護APIによるパーミッション・チケットの発行は、認可プロセス全体の重要な部分です。次のセクションで説明するように、これらはクライアントによって要求されたパーミッションを表し、要求されているリソースとスコープに関連付けられたパーミッションとポリシーの評価中に付与されたすべてのパーミッションを持つ最終的なトークンを取得するためにサーバーに送信されます。
より詳細な情報は保護APIを参照してください。
認可API
認可APIは、アクセス・トークンとパーミッション・チケットをリクエスティング・パーティー・トークン(RPT)と交換する単一の操作を提供する UMA準拠 のエンドポイントです。
RPTには、クライアントに付与されたすべてのパーミッションが含まれており、保護されたリソースにアクセスするためにリソースサーバーを呼び出す目的で使用できます。
RPTを要求する際に、以前に発行したRPTを提供することもできます。この場合、結果として得られるRPTは、以前のRPTのパーミッショとパーミッション・チケット内の新しいパーミッションの結合で構成されます。
詳細については、認可APIを参照してください。
1.1.3. エンタイトルメントAPI
エンタイトルメントAPIは、RPTを発行するための1-leggedプロトコルを提供します。認可APIとは異なり、エンタイトルメントAPIはアクセストークンのみを要求します。
このAPIから、ユーザー(特定のリソースサーバーによって管理されるリソースに基づいた)のすべてのエンタイトルメントまたはパーミッション、または1つ以上のリソースのセットに対するエンタイトルメントのみを取得できます。
より詳細な情報はエンタイトルAPIを参照してください。
1.2. 用語
先に進む前に、Keycloak認可サービスで紹介されたこれらの用語と概念を理解することが重要です。
1.2.1. リソース・サーバー
OAuth2の用語では、リソース・サーバーは保護されたリソースをホスティングし、保護されたリソースへのリクエストを受け入れてレスポンスを返すことができます。
通常、リソース・サーバーは、保護されたリソースへのアクセスを許可するかどうかを決定するために、何らかの情報に依存しています。RESTfulベースのリソース・サーバーの場合、大抵、その情報はセキュリティー・トークンに格納され、一般的に、サーバーへのすべてのリクエストと一緒にベアラー・トークンとして送信されます。セッションを利用してユーザーを認証するWebアプリケーションは、その情報をユーザーのセッションに格納し、リクエストごとにそこから取得します。
Keycloakでは、 confidential クライアント・アプリケーションはリソース・サーバーとして動作できます。このクライアントのリソースとそれぞれのスコープは、一連の認可ポリシーによって保護、管理されます。
1.2.2. リソース
リソースは、アプリケーションと組織の資産の一部です。これは、1つ以上のエンドポイントのセット(HTMLページなどの古典的なWebリソースなど)です。認可ポリシーの用語では、リソースは保護される object です。
すべてのリソースには、単一のリソースまたはリソースのセットを表すことができる一意の識別子があります。例えば、すべての銀行口座に対して一連の認可ポリシーを表し定義する Banking Account Resource を管理することができます。ただし、 Alice’s Banking Account と呼ばれる別のリソースを持つこともできます。これは、単一の顧客が所有する単一のリソースを表し、独自の一連の認可ポリシーを持つことができます。
1.2.3. スコープ
リソースのスコープは、リソース上で実行可能な限定されたアクセスの範囲です。認可ポリシーの用語では、スコープは論理的にリソースに適用できる、潜在的に多くの verbs の1つです。
通常は、特定のリソースで何ができるかを示します。スコープの例としては、表示、編集、削除などです。ただし、リソースによって提供される特定の情報に関連付けることもできます。この場合、プロジェクト・リソースとコスト・スコープを持つことができます。コスト・スコープは、ユーザーがプロジェクトのコストにアクセスするための特定のポリシーとパーミッションを定義するために使用されます。
1.2.4. パーミッション
シンプルでとても一般的なパーミッションを考えてみましょう。
パーミッションは、保護されるオブジェクトと、アクセスが許可されるかどうかを判断するために評価されなければならないポリシーとを関連付けます。
-
X CAN DO Y ON RESOURCE Z
-
ここでは、X、Y、Zは以下を意味します。
-
X 1つ以上のユーザー、ロール、またはグループ、またはそれらの組み合わせを表します。クレームとコンテキストを使うこともできます。
-
Y 実行するアクション(書き込み、表示など)を表します。
-
Z "/accounts"などの保護されたリソースを表します。
-
-
Keycloakは、単純なルールから非常に複雑なルールベースの動的なパーミッションまで、幅広いパーミッション戦略を構築するための豊富なプラットフォームを提供します。柔軟性を提供し、次のことに役立ちます。
-
コードのリファクタリングとパーミッション管理のコストを削減
-
より柔軟なセキュリティー・モデルをサポートし、セキュリティー要件の変更に容易に対応できます
-
ランタイムに変更を加えます。アプリケーションは、保護されているリソースとスコープについてのみに関係し、それらがどのように保護されるかには関係ありません。
1.2.5. ポリシー
ポリシーは、オブジェクトへのアクセスを許可するために必要な条件を定義します。パーミッションとは異なり、保護されるオブジェクトを指定するのではなく、特定のオブジェクト(リソース、スコープ、またはその両方)へのアクセスを満たす条件を指定します。ポリシーは、リソースを保護するために使用できるさまざまなアクセス・コントロール・メカニズム(ACM)に強く関連しています。ポリシーを使用すると、属性ベースのアクセス・コントロール(ABAC)、ロールベースのアクセス・コントロール(RBAC)、コンテキストベースのアクセス・コントロール、またはこれらの任意の組み合わせのための戦略を実装できます。
Keycloakは、"ポリシーのポリシー"を構築して評価の動作を制御できる集約されたポリシーの概念を提供することによって、ポリシーの概念とその定義方法を活用します。特定のリソースへのアクセスを満たすすべての条件を含んだ1つの大きなポリシーを書くのではなく、Keycloak認可サービスのポリシー実装は分割統治のテクニックに従います。つまり、個々のポリシーを作成し、異なる権限でそれらを再利用し、個々のポリシーを組み合わせてより複雑なポリシーを構築することができます。
1.2.6. ポリシー・プロバイダー
ポリシー・プロバイダーは、特定のポリシー・タイプの実装です。Keycloakには、対応するポリシー・プロバイダーに基づいた組み込みのポリシーが用意されており、独自のポリシー・タイプを作成して特定の要件をサポートすることができます。
Keycloakには、独自のポリシー・プロバイダー実装をプラグイン化するために使用できるSPI(サービス・プロバイダー・インターフェイス)が用意されています。
1.2.7. パーミッション・チケット
パーミッション・チケットは、 OAuth2のUMA(User-Managed Access)プロファイル 仕様で定義された特別なタイプのトークンで、フォームが認可サーバーによって決定される不透明なストラクチャーを提供します。このストラクチャーは、クライアントによって要求されているリソースおよび(または)スコープ、および認可データのリクエスト(リクエスティング・パーティー・トークン[RPT])に適用する必要のあるポリシーを表します。
UMAでは、個人対個人の共有や個人対組織の共有をサポートするためにパーミッション・チケットが重要です。承認ワークフローにパーミッション・チケットを使用すると、単純なものから複雑なものまでさまざまなシナリオが可能になります。リソース・オーナーとリソース・サーバーは、これらのリソースへのアクセスを管理するきめ細かいポリシーに基づいてリソースを完全に制御できます。
UMAのワークフローでは、パーミッション・チケットは認可サーバーによってリソース・サーバーに発行されます。リソース・サーバーは、保護されたリソースにアクセスしようとするクライアントにパーミッション・チケットを返します。クライアントは、チケットを受信すると、チケットを認可サーバーに送り返すことによって、RPT(認可データを保持する最後のトークン)を要求することができます。
2. Getting Started
このチュートリアルをはじめる前に、Keycloakのインストールを完了し、Getting Started Guideのチュートリアルに沿って初期管理者ユーザーを作成する必要があります。これには注意事項があります。Keycloakサーバーと同じマシンで、別途WildFlyインスタンスを起動する必要があります。この別インスタンスではJavaサーブレットのアプリケーションを起動します。そのため、同じマシンで起動させる際にポートが競合しないように、異なるポートでKeycloakを起動する必要があります。コマンドラインで jboss.socket.binding.port-offset
システムプロパティを使います。当プロパティの値は、Keycloakサーバーで開いた全ポートの基準値に加算される数値です。
Keycloakサーバーを起動するには下記を実行します。
$ .../bin/standalone.sh -Djboss.socket.binding.port-offset=100
> ...\bin\standalone.bat -Djboss.socket.binding.port-offset=100
WildFlyのインストールと設定方法の詳細については、Securing Applications and Services Guideチュートリアルの手順に従ってください。
インストールと両サーバーの起動後、Keycloak管理コンソールは http://localhost:8180/auth/admin/ 、WildFlyインスタンスは http://localhost:8080 でアクセス可能となります。
2.1. サーブレット・アプリケーションのセキュリティ保護
このgetting startedガイドの目的はできるだけ短時間でKeycloakの様々な認可機能を試すことができるようにすることです。本書はデフォルトのデータベースとサーバ設定に大きく依存したクイックツアーとなっています。複雑な配備オプションは本書の範囲外です。機能と設定の詳細については本書の適切な章を参照してください。
本ガイドはKeycloak認可サービスについての重要な概念を説明します。
-
クライアント・アプリケーションに対するきめ細かい認可の有効化
-
保護されたリソースをもつリソースサーバーとしてのクライアント・アプリケーションの設定
-
保護されたリソースへのアクセスを統括するためのパーミッションと認可ポリシーの定義
-
アプリケーションのポリシー実行の有効化
2.2. レルムとユーザーの作成
最初のステップは、そのレルムにレルムとユーザーを作成することです。レルムは次のように構成されています。
-
単一のユーザー
-
単一のクライアント・アプリケーション。認可サービスを有効にする必要があるリソースサーバーになります。
レルムとユーザーを作成するには、次の手順を実行します。
-
hello-world-authz という名前のレルムを作成します。作成されると、次のようなページが表示されます。
hello-world-authzレルム -
新しく作成したレルムのユーザーを作成します。 Users をクリックします。ユーザーリストのページが開きます。
-
空のユーザーリストの右側にある Add User をクリックします。
-
新しいユーザーを作成するには、 Username 、 Email 、 First Name 、 Last Name フィールドを入力します。 User Enabled を On に切り替えて、 Save をクリックします。
Add User -
Credentials タブをクリックして、ユーザーのパスワードを設定します。
ユーザーのパスワード設定 -
New Password と Password Confirmation フィールドにパスワードを入力し、 Temporary を OFF に切り替えます。
-
Reset Password をクリックして、ユーザーのパスワードを設定します。
2.3. 認可サービスの有効化
OpenID Connectプロトコルを使用するように設定された既存のクライアント・アプリケーションで、認可サービスを有効にすることができます。新しいクライアントを作成することもできます。
新しいクライアントを作成するには、次の手順を実行します。
-
Clients をクリックして新しいクライアント・アプリケーションの作成を開始し、 Client ID 、 Client Protocol 、 Root URL フィールドを入力します。
クライアント・アプリケーションの作成 -
Save をクリックします。クライアントの詳細ページが表示されます。
クライアントの詳細 -
クライアントの詳細ページで、 Authorization Enabled を ON に切り替えて Save をクリックします。新しい Authorization タブがクライアント用に表示されます。
-
Authorization タブをクリックすると、次のような認可の設定ページが表示されます。
認可の設定
クライアント・アプリケーションの認可サービスを有効にすると、Keycloakはクライアントの認可設定のためのいくつかのデフォルト設定を自動的に作成します。
認可設定の詳細については、認可サービスの有効化を参照してください。
2.4. アプリケーションのビルド、デプロイ、およびテスト
app-authz-vanilla リソース・サーバー(またはクライアント)が正しく設定され、認可サービスが有効になったので、サーバーにデプロイすることができます。
デプロイするアプリケーションのプロジェクトとコードは、Keycloakクイックスタートリポジトリから入手できます。続行するには、マシンに以下をインストールし、PATHを通す必要があります。
-
Java JDK 8
-
Apache Maven 3.1.1以上
-
Git
You can obtain the code by cloning the repository at https://github.com/keycloak/keycloak-quickstarts. The quickstarts are designed to work with the most recent Keycloak release.
コードをダウンロードするには、次の手順に従います。
$ git clone https://github.com/keycloak/keycloak-quickstarts
ビルドおよびデプロイをするアプリケーションは次の場所にあります
$ cd keycloak-quickstarts/app-authz-jee-vanilla
2.4.1. アダプターの設定を取得
アプリケーションをビルドおよびデプロイする前に、まずアダプターの設定を取得する必要があります。
Keycloak管理コンソールからアダプターの設定を取得するには、以下の手順を実行します。
-
Clients をクリックします。クライアントの一覧で、 app-authz-vanilla クライアント・アプリケーションをクリックします。クライアントの詳細ページが開きます。
クライアントの詳細 -
Installation タブをクリックします。Format Optionドロップダウン・リストから、 Keycloak OIDC JSON を選択します。アダプターの設定はJSON形式で表示されます。 Download をクリックします。
アダプターの設定 -
keycloak.json
ファイルをapp-authz-jee-vanilla/config
ディレクトリーに移動します。 -
(省略可能)デフォルトでは、ポリシー・エンフォーサーは、ユーザーがリソース・サーバー上の保護されたリソースにアクセスする許可がない場合に、
403
ステータス・コードで応答します。ただし、権限のないユーザーに対して、リダイレクトURLを指定することもできます。リダイレクトURLを指定するには、手順3で更新した keycloak.json ファイルを編集し、policy-enforcer
の設定を次のものに置き換えます。"policy-enforcer": { "on-deny-redirect-to" : "/app-authz-vanilla/error.jsp" }
この変更は、保護されたリソースにアクセスするための必要な権限を持っていない場合に、ポリシー・エンフォーサーに対して、ユーザーを
/app-authz-vanilla/error.jsp
ページにリダイレクトするよう指定します(役に立たない403 Unauthorized
メッセージを返すのではなく)。
2.4.2. アプリケーションのビルドとデプロイ
アプリケーションをビルドしてデプロイするには、次のコマンドを実行します。
$ cd redhat-sso-quickstarts/app-authz-jee-vanilla
$ mvn clean package wildfly:deploy
2.4.3. アプリケーションのテスト
アプリケーションが正常にデプロイされた場合は、 http://localhost:8080/app-authz-vanilla でアクセスできます。Keycloakログインページが開きます。
ユーザー alice として、指定したパスワードでログインします。認証後、次のページが表示されます。
クライアント・アプリケーションの認可サービスを有効にしたときに、Keycloakで定義されたデフォルト設定は、このポリシーで保護されているリソースへのアクセスを常に許可する単純なポリシーを提供します。
まず、デフォルトのアクセス許可とポリシーを変更し、アプリケーションの応答方法をテストするか、Keycloakが提供するさまざまなポリシータイプを使用して新しいポリシーを作成します。
このアプリケーションをテストするために今できることはたくさんあります。例えば、クライアントのAuthorizationタブをクリックし、 Policies
タブをクリックして、デフォルトポリシーを変更することができます。次に、リスト内の `Default Policy`をクリックします。
//デフォルト値は$evaluation.grant()です。
//$evaluation.deny()に変更したときに何が起こるかを見てみましょう。
$evaluation.deny();
さて、デモアプリケーションからログアウトして、もう一度ログインしてください。アプリケーションにアクセスできなくなりました。
これを修正してみましょう。 Default Policy
コードを変更する代わりに、ポリシー・コードのテキストエリアの下にあるドロップダウン・リストを使用して、 Logic
を Negative
に変更します。これにより、デフォルトではすべてのアクセス要求が拒否されますが、そのポリシーの結果が否定されるため、アプリケーションへのアクセスが再度有効になります。再度、この変更をテストする前に、必ずログアウトして再ログインしてください。
2.4.4. 次のステップ
追加で次のようなことができます。
-
スコープを作成し、ポリシーとアクセス許可を定義し、アプリケーション側でテストします。ユーザーがアクション(または作成したスコープで表されるもの)を実行できるでしょうか?
-
ルールベースなどの異なるタイプのポリシーを作成し、これらのポリシーを
Default Permission
に関連付けます。 -
複数のポリシーを
Default Permission
に適用し、動作をテストします。 例えば、複数のポリシーを組み合わせて、それに応じてDecision Strategy
を変更します。 -
アプリケーション内で権限を表示およびテストする方法の詳細については、認可コンテキストの取得を参照してください。
2.5. サンプル
Keycloak Authorizationは、認可サービスを迅速に開始し、開発するアプリケーションに同じ概念を適用する方法を理解するのにも役立ちます。
次のKeycloakのデモ用配布物を使用しており、ファイルシステムに適切に展開している場合は、
-
keycloak-demo-3.4.3.Final.[zip|tar.gz]
以下のディレクトリから利用可能なサンプルをチェックアウトすることができます。
cd ${KEYCLOAK_DEMO_SERVER_DIR}/examples/authz
または、GitHubから入手できます。
各サンプルには、そのサンプルをビルド、デプロイ、テストする方法を説明するREADMEファイルがあります。
各サンプルの簡単な説明は次のとおりです。
名前 | 説明 |
---|---|
Keycloackサーバーから取得した権限を基に、ユーザーがそのページにアクセスできるかどうかを判定するPolicy Enforcerによって保護されたシングルページ・アプリケーションです。 |
|
HTML5 + AngularJS + JAX-RSをベースにつくられたシンプルなアプリケーションで、RESTFulベースのサービスとHTML5クライアントに対するきめ細かなアクセス許可を有効にする方法を示します。 |
|
JBoss/Wildflyサーブレットアプリケーションに対するきめ細かな認可を有効にする方法を示すサーブレットベースのアプリケーションです。 |
3. リソースサーバーの管理
OAuth2の仕様によれば、リソース・サーバーは保護されたリソースをホストし、保護されたリソースへのリクエストを受け入れて応答することができるサーバーです。
Keycloakでは、リソース・サーバーに保護されたリソースに対してきめ細かい認可を与えるための豊富なプラットフォームが用意されており、異なるアクセス制御の仕組みに基いた認可決定を行うことができます。
きめ細かいパーミッションをサポートするクライアント・アプリケーションを設定することができます。その際に、概念的にクライアント・アプリケーションをリソース・サーバーに変換します。
3.1. クライアント・アプリケーションの作成
Keycloak認可サービスを有効にするための最初の手順は、リソースサーバーにするクライアント・アプリケーションを作成することです。
クライアント・アプリケーションを作成するには、次の手順を実行します。
-
Clients をクリックします。
Clients -
このページで、 Create をクリックします。
クライアントの作成 -
クライアントの
Client ID
を入力します。例えば、 my-resource-server 。 -
アプリケーションの
Root URL
を入力します。例えばhttp://${host}:${port}/my-resource-server
-
Save をクリックします。クライアントが作成され、クライアントの設定ページが開きます。次のようなページが表示されます。
クライアントの設定
3.2. 認可サービスの有効化
OIDCクライアント・アプリケーションをリソースサーバーに変えて、きめ細かい認可を有効にするには、 Authorization Enabled を ON にして Save をクリックします。
クライアントに新しいAuthorizationタブが表示されます。 Authorization タブをクリックすると、次のようなページが表示されます。
Authorizationタブには、アプリケーションのリソースを実際に保護するために従わなければならないさまざまなステップを補う追加のサブタブが含まれています。各タブは、このドキュメントの特定のトピックで個別に補足されています。ここではそれぞれについて簡単に説明します。
-
Settings
リソースサーバーの一般設定。このページの詳細については、リソースサーバーの設定のセクションを参照してください。
-
Resource
このページから、アプリケーションのリソースを管理できます。
-
Scope
このページから、スコープを管理できます。
-
Policies
このページから、認可ポリシーを管理し、許可を得るために必要な条件を定義することができます。
-
Permissions
このページから、保護されたリソースとスコープの権限を、作成したポリシーとリンクさせることにより管理できます。
-
Evaluate
このページでは、認可リクエストのシミュレート、および定義した権限と認可ポリシーの評価結果を表示できます。
3.2.1. リソースサーバーの設定
リソースサーバー設定ページでは、ポリシーの強制モードの設定や、リモートリソース管理の許可、認可構成の設定のエクスポートができます。
-
Policy Enforcement Mode
サーバーに送信された認可要求を処理するときに、ポリシーがどのように強制されるかを指定します。
-
Enforcing
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
-
Permissive
Requests are allowed even when there is no policy associated with a given resource.
-
Disabled
すべてのポリシーの評価を無効にし、すべてのリソースへのアクセスを許可します。
-
-
Allow Remote Resource Management
リソースサーバーによってリソースをリモート管理できるかどうかを指定します。falseの場合、リソースは管理コンソールからのみ管理できます。
-
Export Settings
認可構成の設定をJSONファイルにエクスポートできます。 Export をクリックするとダウンロード用のJSON設定がすべて表示されます。設定ファイルには、リソースサーバーに対して定義されているすべてのもの(保護されたリソース、スコープ、アクセス許可、およびポリシー)が含まれています。
3.3. デフォルト設定
リソース・サーバーを作成すると、Keycloakは新しく作成したリソース・サーバーのデフォルト設定を作成します。
デフォルト設定は次の通りです。
-
アプリケーションのすべてのリソースを表すデフォルトの保護されたリソース。
-
このポリシーで保護されているリソースへのアクセスを常に許可するポリシー。
-
デフォルトのポリシーに基づいてすべてのリソースへのアクセスを管理するパーミッション。
デフォルトの保護されたリソースは default resource と呼ばれ、 Resources タブに移動すると表示できます。
このリソースは Type
、すなわち urn:my-resource-server:resources:default
と URI
/*
を定義します。ここで、URIフィールドは、このリソースがアプリケーションのすべてのパスを表すことをKeycloakが示すワイルドカード・パターンで定義します。つまり、アプリケーションのポリシー適用を有効にすると、アクセス権を付与する前に、リソースに関連付けられているすべてのパーミッションが検査されます。
前述の Type
は、デフォルトのリソースまたは同じタイプを使用して作成したリソースに適用させるタイプ付きリソース・パーミッションを作成するために使用できる値を定義します。
デフォルトのポリシーは、 only from realm policy と呼ばれ、 Policies タブに移動すると表示できます。
このポリシーは、ポリシーで保護されているリソースへのアクセスを常に許可する条件を定義したJavaScriptベースのポリシーです。このポリシーをクリックすると、次のようにルールが定義されていることが分かります。
// デフォルトでは、このポリシーに関連する全てのパーミッションを付与します。
$evaluation.grant();
最後に、デフォルトのパーミッションは、 default permission と呼ばれ、 Permissions タブに移動すると表示できます。
このパーミッションはリソースベースのパーミッションで、特定のタイプのすべてのリソースに適用される1つ以上のポリシーのセットを定義します。
3.3.1. デフォルト設定の変更
デフォルトの設定を変更するには、デフォルトのリソース、ポリシー、またはパーミッションの定義を削除し、独自の定義を作成します。
デフォルトのリソースは、 /* パターンを使用してアプリケーション内のリソースまたはパスにマップされる URI で作成されます。独自のリソース、権限、ポリシーを作成する前に、デフォルト設定が自分の設定と矛盾しないことを確認してください。
デフォルト設定では、アプリケーションのすべてのパスに対応するリソースを定義します。独自のリソースにパーミッションを書き込もうとしている場合は、 Default Resource を削除するか、 フィールドをアプリケーション内の特定のパスに変更してください。それ以外の場合は、デフォルト・リソース(デフォルトでは常にアクセスを許可する)に関連付けられたポリシーにより、Keycloakは保護されたリソースへのアクセスを許可します。
|
3.4. 認可設定のエクスポートおよびインポート
リソースサーバー(またはクライアント)の構成設定をエクスポートおよびダウンロードできます。また、リソースサーバーの既存の設定ファイルをインポートすることもできます。設定ファイルのインポートとエクスポートは、リソースサーバーの初期設定を作成したり、既存の設定を更新する場合に役立ちます。設定ファイルには次の定義が含まれています。
-
保護されたリソースとスコープ
-
ポリシー
-
パーミッション
4. リソースとスコープの管理
リソース管理は簡単かつ一般的です。リソースサーバーを作成したら、保護するリソースとスコープの作成を開始できます。リソースおよびスコープは、 Resource タブおよび Scope タブにそれぞれナビゲートすることで管理できます。
4.1. リソースの表示
Resource ページには、リソースサーバーに関連付けられているリソースの一覧が表示されます。
リソースリストには、次のような保護されたリソースに関する情報が表示されます。
-
タイプ
-
URI
-
オーナー
-
関連スコープ(存在する場合)
-
関連するパーミッション
このリストから、パーミッションを作成したいリソースに対して Create Permission をクリックして、パーミッションを直接作成することもできます。
リソースに対するパーミッションを作成する前に、そのパーミッションに関連付けたいポリシーを定義済みであることを確認してください。 |
4.2. リソースの作成
リソースの作成は簡単で一般的です。主な関心事は、作成するリソースの粒度です。言い換えれば、1つ以上のリソースのセットを作成することができ、それらを定義する方法はパーミッションを管理するために重要なことです。
新しいリソースを作成するには、リソース・リストの右上にある Create をクリックします。
Keycloakでは、リソースは、次のようなさまざまなタイプのリソースに共通する細かい情報のセットを定義します。
-
Name
このリソースを説明する、人間が読める形式で一意な文字列。
-
Type
1つ以上のリソースのセットのタイプを一意に識別する文字列。タイプは、異なるリソース・インスタンスをグループ化するために使用される string です。例えば、自動的に作成されるデフォルト・リソースのデフォルトのタイプは、
urn:resource-server-name:resources:default
です。
-
URI
リソースのロケーション/アドレスを提供するURI。HTTPリソースの場合、URIは通常、これらのリソースを提供するために使用される相対パスです。
-
Scopes
リソースに関連付ける1つ以上のスコープ。
4.2.2. リソース・オーナー
リソースはオーナーを持ちます。デフォルトでは、リソースはリソース・サーバーによって所有されています。
ただし、リソースはユーザーと関連付けることもできるため、リソース・オーナーに基づいてパーミッションを作成できます。例えば、リソース・オーナーだけが特定のリソースを削除または更新することができます。
4.2.3. リモートでリソースを管理する
リソース管理は、保護APIを介しても公開され、リソース・サーバーがリソースをリモートで管理できます。
保護APIを使用すると、リソース・サーバーを実装して、ユーザーが所有するリソースを管理できます。この場合、リソースを特定のユーザーに属するものとして設定するためのユーザー識別子を指定できます。
Keycloakは、リソース・サーバーがリソースを完全に制御できるようにします。将来的には、特にUMAプロトコルを使用している場合に、ユーザーが自分のリソースを制御したり、認可リクエストを承認したり、パーミッションを管理できるようにする必要があります。 |
5. ポリシーの管理
前の章で述べたように、ポリシーはオブジェクトへのアクセスを与えられる前に満たすべき条件を定義します。
リソース・サーバーに関連付けられたポリシーを閲覧するには、リソース・サーバーの設定画面上の Policy タブをクリックします。
このタブでは、ポリシーの閲覧、作成、変更を行うことができます。
新規ポリシーを作成するには、ポリシーのリストの右上の Create policy
ドロップダウン・リストからポリシー・タイプを選択します。それぞれのポリシー・タイプの詳細については本章で説明します。
5.1. ユーザー・ベース・ポリシー
1人以上のユーザーの集合がオブジェクトへのアクセスを許可されるパーミッションの条件を定義するために、このタイプのポリシーを使用することができます。
新しいユーザー・ベース・ポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウン・リストから User を選択します。
5.1.1. 設定
-
Name
A human-readable and unique string identifying the policy. A best practice is to use names that are closely related to your business and security requirements, so you can identify them more easily.
-
Description
A string containing details about this policy.
-
Users
このポリシーによってアクセス権が与えられるユーザーを指定します。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.2. ロール・ベース・ポリシー
1つ以上のロールの集合がオブジェクトへのアクセスを許可されるパーミッションの条件を定義するために、このタイプのポリシーを使用することができます。
デフォルトでは、このポリシーに追加されたロールは、Requiredとして指定されず、アクセスを要求するユーザーにこれらのロールのいずれかが付与されている場合に、ポリシーはアクセスを許可します。ただし、特定のロールを強制したい場合は、Requiredとして特定のロールを指定できます。レルムまたはクライアントのロールにかかわらず、RequiredのロールとRequiredではないロールを組み合わせることもできます。
ロールのポリシーは、オブジェクトへのアクセスを許可するのに特定のロールを強制する必要がある、より限定されたロールベースのアクセス・コントロール(RBAC)が必要な場合に役立ちます。例えば、ユーザーがクライアント・アプリケーション(ユーザーの代理として動作している)がユーザーのリソースにアクセスできるようにするのにユーザーが同意する必要があることを強制できます。Keycloakクライアント・スコープ・マッピングを使用して同意ページを有効にしたり、Keycloakサーバーからアクセス・トークンを取得するときに明示的にスコープを指定したりすることもできます。
新しいロール・ベース・ポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウンリストから Role を選択します。
5.2.1. 設定
-
Name
ポリシーを説明する、人が判読可能で一意の文字列。ベストプラクティスは、ビジネス要件とセキュリティ要件に密接に関連する名前を使用することです。そうすることで簡単に識別することができます。
-
Description
A string containing details about this policy.
-
Realm Roles
このポリシーによって、どの realm ロールが許可されるかを指定します。
-
Client Roles
このポリシーで許可される client ロールを指定します。このフィールドを有効にするには、最初に
Client
を選択する必要があります。 -
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.2.2. ロールを必須として定義する
ロールベース・ポリシーを定義するとき、特定のロールを Required
と指定することができます。こうすることで、 全て の 必須 ロールを付与されたユーザーにのみアクセス権を与えることができます。レルムロールとクライアントロールの両方にこの設定を適用することができます。
ロールを必須と指定するには、そのロールの Required
チェックボックスをチェックします。
複数のロールがポリシーに定義されており、そのうちのいくつかが必須の場合にこの機能は有用です。より細かいロールベース・アクセス・コントロール(RBAC)のためにレルムロールとクライアントロールを組み合わせることが可能です。例えば、あるクライアントに適用されるポリシーがある場合、そのクライアントに関連付けられた特定のクライアントロールを必須とすることができます。また、特定のレルムロールを持つ場合のみアクセスを許可することもできます。1つのポリシーに両方のアプローチを適用することもできます。
5.3. JavaScriptベースポリシー
このポリシーは、JavaScriptを使用可能にする条件を定義するために使うことができます。これはKeycloakによってサポートされるルール・ベースのポリシータイプの1つであり、評価APIに基づいて任意のポリシーを柔軟に作成できます。
新しいJavaScriptベースポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウン・リストから JavaScript を選択します。
5.3.1. 設定
-
Name
ポリシーを説明する、人が判読可能で一意の文字列。ベストプラクティスは、ビジネス要件とセキュリティ要件に密接に関連する名前を使用することです。そうすることで簡単に識別することができます。
-
Description
A string containing details about this policy.
-
Code
このポリシーの条件を指定するJavaScriptコード。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.3.2. サンプル
コンテキストから取得した属性で条件を定義するために、属性ベース・アクセス・コントロール(ABAC)を使用するJavaScriptベースポリシーの簡単な例です。
var context = $evaluation.getContext();
var contextAttributes = context.getAttributes();
if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1')) {
$evaluation.grant();
}
ロール・ベース・アクセス・コントロール(RBAC)を使用することもできます。以下の例では、ユーザーが keycloak_user
レルム ロールを与えられているかどうかを調べています。
var context = $evaluation.getContext();
var identity = context.getIdentity();
if (identity.hasRealmRole('keycloak_user')) {
$evaluation.grant();
}
または、ユーザが my-client-role
クライアント ・ロールを与えられているかどうかを確認できます。my-clientはクライアント・アプリケーションのクライアントIDです。
var context = $evaluation.getContext();
var identity = context.getIdentity();
if (identity.hasClientRole('my-client', 'my-client-role')) {
$evaluation.grant();
}
いくつかのアクセス・コントロール機構の組み合わせを使用することもできます。 以下の例は、同じポリシー内でロール(RBAC)とクレーム/属性(ABAC)のチェックをどのように使用できるかを示しています。この場合は、ユーザーが admin
ロールを与えられているか、または、keycloak.org
ドメインの電子メールを持っているかどうかを調べています。
var context = $evaluation.getContext();
var identity = context.getIdentity();
var attributes = identity.getAttributes();
var email = attributes.getValue('email').asString(0);
if (identity.hasRealmRole('admin') || email.endsWith('@keycloak.org')) {
$evaluation.grant();
}
独自のルールを作成するときは、 $evaluation オブジェクトが org.keycloak.authorization.policy.evaluation.Evaluation を実装するオブジェクトであることに注意してください。このインターフェイスからアクセスできるものの詳細については、評価APIを参照してください。 |
5.4. ルールベースのポリシー
このタイプのポリシーでは、ルール評価環境である Drools を使用してパーミッションの条件を定義できます。これはKeycloakでサポートされている ルールベース のポリシー・タイプの1つであり、評価APIに基づいたポリシーを柔軟に作成できます。
新しいルールベースのポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウン・リストで、 Rule を選択します。
5.4.1. 設定
-
Name
ポリシーを説明する、人が判読可能な一意の文字列。ビジネス要件とセキュリティ要件に密接に関連する名前を使用することを強くお勧めします。そうすることで簡単に識別することができます。
-
Description
このポリシーの詳細を示す文字列。
-
Policy Maven Artifact
ルールが定義されているアーティファクトを指し示すMavenのgroupId-artifactId-version(GAV)。GAVを提供したら、 Resolve をクリックして、 Module と Session フィールドの両方を読み込むことができます。
-
Group Id
アーティファクトのgroupId。
-
Artifact Id
アーティファクトのartifactId。
-
Version
アーティファクトのversion。
-
-
Module
このポリシーで使用されるモジュール。ルールがロードされる特定のセッションを選択するためのモジュールを提供する必要があります。
-
Session
このポリシーで使用されるセッション。セッションは、ポリシーの処理時に評価するすべてのルールを提供します。
-
Update Period
アーティファクトの更新をスキャンする間隔を指定します。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.4.2. サンプル
認証されたユーザーがリクエストされたリソースのオーナーである場合にのみ、GRANTに評価される条件を定義するために属性ベースのアクセス・コントロール(ABAC)を使用するDroolsベースのポリシーの簡単な例を次に示します。
import org.keycloak.authorization.policy.evaluation.Evaluation;
rule "Authorize Resource Owner"
dialect "mvel"
when
$evaluation : Evaluation(
$identity: context.identity,
$permission: permission,
$permission.resource != null && $permission.resource.owner.equals($identity.id)
)
then
$evaluation.grant();
end
アイデンティティから属性を取得し、それに応じて条件を定義するために、ABAC(属性ベースのアクセス・コントロール)の別のバリアントを使用することもできます。
import org.keycloak.authorization.policy.evaluation.Evaluation;
rule "Authorize Using Identity Information"
dialect "mvel"
when
$evaluation : Evaluation(
$identity: context.identity,
identity.attributes.containsValue("someAttribute", "you_can_access")
)
then
$evaluation.grant();
end
org.keycloak.authorization.policy.evaluation.Evaluation
インターフェイスからアクセスできるものの詳細については、<< _ policy_evaluation_api, 評価 API >>を参照してください。
5.5. タイムベース・ポリシー
このタイプのポリシーを使用して、パーミッションの時間条件を定義することができます。
新しいタイム・ベース・ポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウン・リストから Time を選択します。
5.5.1. 設定
-
Name
ポリシーを説明する、人が判読可能で一意の文字列。ベストプラクティスは、ビジネス要件とセキュリティ要件に密接に関連する名前を使用することです。そうすることで簡単に識別することができます。
-
Description
A string containing details about this policy.
-
Not Before
アクセスを許可 しない 時間を定義します。現在の日付/時刻がこの値よりも後の場合にのみ許可が与えられます。
-
Not On or After
アクセスを許可 しない 時間を定義します。 現在の日付/時刻がこの値より前の場合にのみ、許可が与えられます。
-
Day of Month
アクセスを許可する月の日を定義します。また、日付の範囲を指定することもできます。この場合、その月の現在の日が指定された2つの値の間にあるまたは等しい場合にのみ許可が与えられます。
-
Month
アクセスを許可する月を定義します。また、月の範囲を指定することもできます。この場合、現在の月が指定された2つの値の間にあるまたは等しい場合にのみ許可が与えられます。
-
Year
アクセスを許可する年を定義します。また、年の範囲を指定することもできます。この場合、現在の年が指定された2つの値の間にあるまたは等しい場合にのみ許可が与えられます。
-
Hour
アクセスを許可する時間を定義します。また、時間の範囲を指定することもできます。この場合、現在の時間が指定された2つの値の間にあるまたは等しい場合にのみ許可が与えられます。
-
Minute
アクセスを許可する分を定義します。また、分の範囲を指定することもできます。この場合、現在の分が指定された2つの値の間にあるまたは等しい場合にのみ許可が与えられます。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
アクセスは、すべての条件が満たされている場合にのみ許可されます。Keycloakは、各条件の結果に基づいて AND を実行します。
5.6. 集約されたポリシー
前述のとおり、Keycloakではポリシーのポリシーを構築できます。これはポリシー集約と呼ばれる概念です。 ポリシー集約を使用すると、既存のポリシーを再利用してより複雑なポリシーを構築し、認可リクエストの処理中に評価されるポリシーとのアクセスをさらに分離することができます。
新しい集約されたポリシーを作成するには、ポリシーリストの右上隅にあるドロップダウン・リストで Aggregated を選択します。
Confidential Resource というリソースがあり、 keycloak.org ドメインと特定の範囲のIPアドレスからアクセスできるユーザーがいるとします。両方の条件で単一のポリシーを作成できます。ただし、このポリシーのドメイン部分を再利用して、元のネットワークに関係なく動作するパーミッションに適用したいかもしれません。
ドメインとネットワークの両方の条件に対して個別のポリシーを作成し、これらの2つのポリシーの組み合わせに基づいて第3のポリシーを作成することができます。集約されたポリシーを使用すると、他のポリシーを自由に組み合わせて、新しい集約ポリシーを任意のパーミッションに適用できます。
集約されたポリシーを作成する場合は、ポリシー間で循環参照または依存関係を導入していないことに注意してください。循環依存が検出された場合、ポリシーを作成または更新することはできません。 |
5.6.1. 設定
-
Name
ポリシーを説明する、人が判読可能な一意の文字列。ビジネス要件とセキュリティ要件に密接に関連する名前を使用することを強くお勧めします。そうすることで、それらが実際に何を意味するのか簡単に識別することができます。
-
Description
このポリシーの詳細を示す文字列。
-
Apply Policy
ポリシーに関連付ける1つ以上のポリシーのセットを定義します。
-
Decision Strategy
このパーミッションのための決定戦略。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.6.2. 集約されたポリシーの決定戦略
集約されたポリシーを作成する際には、各ポリシーの結果に基づいて最終的な決定をするために使用される決定戦略を定義することもできます。
-
Unanimous
The default strategy if none is provided. In this case, all policies must evaluate to a positive decision for the final decision to be also positive.
-
Affirmative
この場合、最終決定が肯定的であるために、 少なくとも1つ のポリシーが、肯定的な決定に評価されなければなりません。
-
Consensus
この場合、肯定的決定の数は否定的決定の数よりも大きくなければなりません。肯定的な決定と否定的な決定の数が同じであれば、最終的な決定は否定的になります。
5.7. クライアント・ベース・ポリシー
このポリシーは、1つ以上のクライアントが、ある対象へアクセスすることを可能にする条件を定義するために使うことができます。
新しいクライアント・ベース・ポリシーを作成するには、ポリシー・リストの右上隅にあるドロップダウン・リストから Client を選択します。
5.7.1. 設定
-
Name
A human-readable and unique string identifying the policy. A best practice is to use names that are closely related to your business and security requirements, so you can identify them more easily.
-
Description
A string containing details about this policy.
-
Clients
このポリシーによってアクセス権が与えられるクライアントを指定します。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.8. グループ・ベース・ポリシー
このポリシーは、1つ以上のグループ(およびそれらの階層)が、ある対象へアクセスすることを可能にする条件を定義するために使うことができます。
新しいグループ・ベース・ポリシーを作成するには、ポリシー・リストの右上隅にあるドロップダウン・リストから Group を選択します。
5.8.1. 設定
-
Name
ポリシーを説明する、人が判読可能で一意の文字列。ベストプラクティスは、ビジネス要件とセキュリティ要件に密接に関連する名前を使用することです。そうすることで簡単に識別することができます。
-
Description
A string containing details about this policy.
-
Groups Claim
グループ名および/またはパスを保持するトークン内のクレームの名前を指定します。通常、認可リクエストは、以前に一部のユーザーに代わって動作するクライアントに発行されたIDトークンまたはアクセストークンに基づいて処理されます。トークンには、このポリシーがユーザーの所属するグループを取得する場所からのクレームが含まれている必要があります。
-
Groups
パーミッションを評価するときに、このポリシーにより実施されるグループを選択できます。 グループを追加した後、 Extend to Children チェックボックスをオンにすることで、子グループへのアクセスを拡張できます。マークされていない場合、アクセス制限は選択したグループにのみ適用されます。
-
Logic
The Logic of this policy to apply after the other conditions have been evaluated.
5.9. 肯定ロジックと否定ロジック
ポリシーには肯定または否定のオプションを付与できます。これにより、ポリシー適用の結果を反転させることができます。
例えば、特定のロールを与えられて いない ユーザーのみアクセスを許可したいとします。この場合、まずそのロールを使ったロールベース・ポリシーを作成し、 Logic を Negative にセットします。Positive のままにしておくと、ポリシーはその定義通りに適用されます。
5.10. ポリシー評価API
JavaScriptまたはJBoss Droolsを使用してルールベースのポリシーを作成する場合、Keycloakは、パーミッションを与える必要があるかどうかを判断するのに役立つ情報を提供する評価APIを提供します。
このAPIは、次のような情報へのアクセスを提供するいくつかのインターフェイスで構成されています。
-
要求しているパーミッション
-
クレーム/属性を取得できるパーミッションを要求しているアイデンティティー
-
ランタイム環境および実行コンテキストに関連付けられたその他の属性
主なインタフェースは org.keycloak.authorization.policy.evaluation.Evaluation で、次のコントラクトを定義します。
public interface Evaluation {
/**
* Returns the {@link ResourcePermission} to be evaluated.
*
* @return the permission to be evaluated
*/
ResourcePermission getPermission();
/**
* Returns the {@link EvaluationContext}. Which provides access to the whole evaluation runtime context.
*
* @return the evaluation context
*/
EvaluationContext getContext();
/**
* Grants the requested permission to the caller.
*/
void grant();
/**
* Denies the requested permission.
*/
void deny();
}
認証リクエストを処理する際、Keycloakは、ポリシーを評価する前に Evaluation
インスタンスを作成します。このインスタンスは、各ポリシーに渡され、アクセスが GRANT か DENY かを判断します。
ポリシーは、 Evaluation
インスタンスで grant()
または deny()
メソッドを呼び出すことでこれを判断します。デフォルトでは、 Evaluation
インスタンスの状態は拒否されています。つまり、ポリシーが明示的に grant()
メソッドを呼び出してポリシー評価エンジンに許可を与える必要があることを示す必要があります。
評価APIの詳細については、 JavaDocs を参照してください。
5.10.1. 評価コンテキスト
評価コンテキストは、評価中にポリシーに有用な情報を提供します。
public interface EvaluationContext {
/**
* Returns the {@link Identity} that represents an entity (person or non-person) to which the permissions must be granted, or not.
*
* @return the identity to which the permissions must be granted, or not
*/
Identity getIdentity();
/**
* Returns all attributes within the current execution and runtime environment.
*
* @return the attributes within the current execution and runtime environment
*/
Attributes getAttributes();
}
このインターフェイスから、ポリシーは以下を取得できます。
-
認証された
Identity
-
実行コンテキストとランタイム環境に関する情報
Identity
は、認可リクエストとともに送信されたOAuth2アクセス・トークンに基づいて作成され、このコンストラクトはオリジナルのトークンから抽出されたすべてのクレームにアクセスできます。例えば、 Protocol Mapper を使用してカスタム・クレームをOAuth2アクセス・トークンに含める場合、ポリシーからこのクレームにアクセスして、条件を作成することもできます。
EvaluationContext
は、実行およびランタイム環境の両方に関連する属性へのアクセスも提供します。今のところ、いくつかの組み込み属性しかありません。
名前 | 説明 | タイプ |
---|---|---|
kc.time.date_time |
現在の日付と時刻 |
String。フォーマット |
kc.client.network.ip_address |
クライアントのIPv4アドレス |
String |
kc.client.network.host |
クライアントのホスト名 |
String |
kc.client.id |
クライアントID |
String |
kc.client.user_agent |
'User-Agent' HTTPヘッダーの値 |
String[] |
kc.realm.name |
レルムの名前 |
String |
6. パーミッションの管理
パーミッションは、保護されているオブジェクトとアクセスを許可するかどうかを決定するために評価されなければならないポリシーを関連付けます。
保護したいリソースを作成し、それらのリソースを保護するために使用するポリシーを作成したら、権限の管理を開始できます。権限を管理するには、リソース・サーバーを編集するときに Permissions タブをクリックします。
主な2つのタイプのオブジェクトを保護するパーミッションを作成できます。
-
Resources
-
Scopes
パーミッションを作成するには、パーミッションのリストの右上隅にあるドロップダウン・リストから、作成するパーミッション・タイプを選択します。次のセクションでは、これら2種類のオブジェクトについて詳しく説明します。
6.1. リソースベースのパーミッションの作成
リソースベースのパーミッションは、1つ以上の認可ポリシーのセットを使用して保護する1つ以上のリソースのセットを定義します。
新しいリソースベースのパーミッションを作成するには、パーミッション・リストの右上隅にあるドロップダウン・リストで Resource-based を選択します。
6.1.1. 設定
-
Name
A human-readable and unique string describing the permission. A best practice is to use names that are closely related to your business and security requirements, so you can identify them more easily.
-
Description
パーミッションに関する詳細を含む文字列。
-
Apply To Resource Type
指定されたタイプのすべてのリソースにパーミッションを適用するかどうかを指定します。このフィールドを選択すると、保護するリソースタイプを入力するよう求められます。
-
Resource Type
保護するリソース・タイプを定義します。定義されている場合、このパーミッションはそのタイプに一致するすべてのリソースに対して評価されます。
-
-
Resources
保護する1つ以上のリソースのセットを定義します。
-
Apply Policy
パーミッションに関連付ける1つ以上のポリシーのセットを定義します。
-
Decision Strategy
パーミッションのための決定戦略
6.1.2. タイプ付きリソースのパーミッション
リソース・パーミッションは、特定のタイプのすべてのリソースに適用されるポリシーを定義するためにも使用できます。この形式のリソース・ベースのパーミッションは、共通のアクセス要件と制約を共有するリソースを持つ場合に役立ちます。
多くの場合、アプリケーション内のリソースは、カプセル化したデータまたは提供する機能に基づいて分類(またはタイプ指定)できます。例えば、金融アプリケーションは、それぞれが特定の顧客に属する異なる銀行口座を管理することができます。それらは異なる銀行口座であるが、銀行組織によって全体的に定義される共通のセキュリティ要件および制約を共有します。タイプされたリソース・パーミッションを使用して、以下のようなすべての銀行口座に適用する共通ポリシーを定義することができます。
-
オーナーのみが自分のアカウントを管理できます。
-
オーナーの国や地域からのアクセスのみを許可します。
-
特定の認証方法を強制します。
タイプ付きリソースのパーミッションを作成するには、新しいリソース・ベースのパーミッションを作成するときに、Apply to Resource Typeをクリックします。 Apply to Resource Type
を On
に設定すると、保護するタイプと、指定したタイプのすべてのリソースへのアクセスを制御するために適用されるポリシーを指定できます。
6.2. スコープベースのパーミッションの作成
スコープベースのパーミッションは、1つ以上の認可ポリシーのセットを使用して保護する1つ以上のスコープのセットを定義します。リソースベースのパーミッションとは異なり、このパーミッションのタイプを使用して、リソースだけでなく、それに関連付けられたスコープのパーミッションを作成し、リソースを管理するパーミッションとそれらに対して実行可能なアクションを定義する際に、より詳細な情報を提供します。
新しいスコープベースのパーミッションを作成するには、パーミッション・リストの右上隅にあるドロップダウン・リストで Scope-based を選択します。
6.2.1. 設定
-
Name
A human-readable and unique string describing the permission. A best practice is to use names that are closely related to your business and security requirements, so you can identify them more easily.
-
Description
パーミッションに関する詳細を含む文字列。
-
Resource
選択したリソースに関連付けられているものにスコープを制限します。選択されていない場合は、すべてのスコープを使用できます。
-
Scopes
保護する1つ以上のスコープのセットを定義します。
-
Apply Policy
パーミッションに関連付ける1つ以上のポリシーのセットを定義します。
-
Decision Strategy
パーミッションのための決定戦略
6.3. ポリシー決定戦略
ポリシーにパーミッションを関連付けるときに、決定戦略を定義して、関連付けされたポリシーの結果を評価して最終的なアクセスを判断する方法を指定できます
-
Unanimous
The default strategy if none is provided. In this case, all policies must evaluate to a positive decision for the final decision to be also positive.
-
Affirmative
この場合、最終的に 少なくとも1つの ポリシーの判定結果が肯定と判定される必要があります。
-
Consensus
この場合、肯定判定数は否定判定数よりも多くなければならない。肯定と否定の判定数が等しい場合、最終的に否定と判定されます。
7. ポリシーの評価とテスト
ポリシーを設計する際に、認可リクエストをシミュレートして、ポリシーの評価方法をテストすることができます。
リソース・サーバーを編集するときに Evaluate
タブをクリックすると、ポリシー評価ツールにアクセスできます。そこで、さまざまな入力を指定して、実際の認可リクエストをシミュレートし、ポリシーの効果をテストすることができます。
7.1. アイデンティティー情報の提供
Identity Information フィルターを使用して、パーミッションを要求するユーザーを指定できます。
Entitlement をクリックして、選択したユーザーのすべてのパーミッションを取得することもできます。
8. 認可サービス
Keycloak認可サービスは、OAuth2のUser-Managed Access(UMA)プロファイルに基づいています。
このセクションでは、アプリケーションとサービスのきめ細かな認可を可能にするために対話できる、さまざまなRESTfulエンドポイントについて説明します。
8.1. 保護API
保護APIは、UMA準拠のエンドポイントのセットを提供します。
-
Resource Registration
このエンドポイントを使用すると、リソースサーバーはリソースをリモートで管理し、ポリシー・エンフォーサーが保護を必要とするリソースをサーバーに問い合わせできるようになります。
-
Permission Registration
UMAプロトコルでは、リソースサーバーはこのエンドポイントにアクセスし、パーミッション・チケットを発行します。
このAPIの重要な要件は、保護APIトークン(PAT)と呼ばれる特別なOAuth2アクセストークンを使用して、リソースサーバー だけ がエンドポイントにアクセスできることです。 UMAでは、PATはスコープ uma_protection を持つトークンです。
8.1.1. PATとは何か、そしてそれをどのように取得するか
保護APIトークン (PAT)は、 uma_protection として定義されたスコープを持つ特殊なOAuth2アクセストークンです。リソースサーバーを作成すると、Keycloakは対応するクライアント・アプリケーションのロール uma_protection を自動的に作成し、クライアントのサービス・アカウントに関連付けます。
リソースサーバーは、Keycloakから他のOAuth2アクセストークンと同様にPATを取得できます。たとえば、次のようにcurlを使用します。
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}' \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
上記の例では、 client_credentials グラントタイプを使用してサーバーからPATを取得しています。その結果、サーバーは次のような応答を返します。
{
"access_token": ${PAT},
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": ${refresh_token},
"token_type": "bearer",
"id_token": ${id_token},
"not-before-policy": 0,
"session_state": "ccea4a55-9aec-4024-b11c-44f6f168439e"
}
Keycloakは、さまざまな方法でクライアント・アプリケーションを認証できます。わかりやすくするため、ここでは client_credentials グラント・タイプが使用されています。これには client_id と client_secret が必要です。サポートされている認証方法の使用を選択することができます。 |
8.1.2. リソースの管理
リソースサーバーは、UMA準拠のエンドポイントを使用して、リモートでリソースを管理できます。
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/resource_set
This endpoint provides registration operations outlined as follows (entire path omitted for clarity):
-
リソースセットの説明を作成する: POST /resource_set
-
リソースセットの説明を読み込む: GET /resource_set/{_id}
-
リソースセットの説明を更新する: PUT /resource_set/{_id}
-
リソースセットの説明を削除する: DELETE /resource_set/{_id}
-
リソースセットの説明を表示する: GET /resource_set
-
フィルターを使用して、リソースセットの説明を表示する: GET /resource_set?filter=${filter}
各操作の規約の詳細については、 UMAリソースセットの登録 を参照してください。
8.1.3. パーミッション・リクエストの管理
UMAプロトコルを使用するリソースサーバーは、特定のエンドポイントを使用してパーミッション・リクエストを管理できます。このエンドポイントは、パーミッション・リクエストを登録し、パーミッション・チケットを取得するためのUMA準拠のフローを提供します。
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/permission
パーミッション・チケットは、パーミッション・リクエストを表す特殊なセキュリティ・トークン・タイプです。 UMA仕様では、パーミッション・チケットは次のとおりです。
認可サーバーからリソースサーバー、リソースサーバーからクライアント、最終的にはクライアントから認可サーバーに伝達され、認可サーバーが認可データの要求に適用する正しいポリシーを評価できるようにする相関ハンドル。
パーミッション・チケットのサポートは制限されています。完全なUMAプロトコルでは、リソースサーバーは、リソースオーナー(要求されているリソースを所有するユーザー)が第三者によるリソースへのアクセスを他の方法で承認することができる認可フローをサポートするためにサーバーにパーミッション・リクエストを登録することができます。これは、UMA仕様の主な機能の1つを表します。リソースオーナーは、独自のリソースとそれらを管理するポリシーを制御できます。現在のところ、KeycloakのUMA実装のサポートは、この点で非常に制限されています。例えば、システムはサーバー上にパーミッション・チケットを保存せず、基本的にはUMAを使用してAPIセキュリティーを提供し、認可サービスをベースにしています。将来、UMAやその他のユースケースの完全なサポートが計画されています。 |
ほとんどの場合、このエンドポイントを直接処理する必要はありません。Keycloakは、リソースサーバーのUMAを有効にするポリシー・エンフォーサーを提供し、認可サーバーからパーミッション・チケットを取得し、このチケットをクライアント・アプリケーションに戻し、最後にリクエスティング・パーティ・トークン(RPT)に基づいて認可決定を実施することができます。
Keycloakからパーミッション・チケットを取得するプロセスは、クライアントがリソースにアクセスするために必要な許可なく保護されたリソースにアクセスしようとしたときに、パーミッション・チケットが取得される通常のクライアント・アプリケーションではなくリソースサーバーによって実行されます。パーミッション・チケットの発行は、UMAを使用する際の重要な側面です。これにより、リソースサーバーは次のことが可能になります。
-
リソースサーバーによって保護されているリソースに関連付けられたデータをクライアントから抽出します。
-
Keycloakの認可リクエストに登録します。これは、後からワークフローを使用して、リソースの所有者の承認に基づいてアクセスを許可します。
-
リソースサーバーを認可サーバーから切り離し、異なる認証サーバーを使用してリソースを保護および管理できます。
クライアントの賢明な点として、パーミッション・チケットには重要な側面もあります。
-
クライアントは、認可データが保護されたリソースにどのように関連付けられているかを知る必要はありません。パーミッション・チケットは、クライアントにとって完全に不透明です。
-
クライアントは、異なるリソースサーバー上のさまざまな認可サーバーによって保護されたリソースにアクセスできます。
これらは、UMAの他の側面が、特にプライバシーとリソースへのアクセス制御されたユーザーに関するパーミッション・チケットに強く基づいたUMAのメリットのほんの一部です。
8.2. 認可API
認可APIは、サーバーから認可データを取得するためのUMA準拠のエンドポイントを提供します。ここで、認可データは、要求されているリソースに関連するすべてのパーミッションおよび認可のポリシーの評価結果を表します。
保護APIとは異なり、どんなクライアント・アプリケーションでも認可APIエンドポイントにアクセスできます。これには、認可APIトークン(AAT)と呼ばれる特殊なOAuth2アクセストークンが必要です。UMAでは、AATは uma_authorization スコープ付きのトークンです。
8.2.1. AATとは何か、そしてそれをどのように取得するか
認可APIトークン(AAT)は、 uma_authorization というスコープを持つ特別なOAuth2アクセス・トークンです。ユーザーを作成すると、Keycloakは自動的に uma_authorization というロールをユーザーに割り当てます。 uma_authorization ロールは、デフォルトのレルム・ロールです。
AATを使用すると、クライアント・アプリケーションはサーバーにユーザーのパーミッションを問い合わせることができます。
クライアント・アプリケーションは、他のOAuth2アクセス・トークンと同様にKeycloakからAATを取得できます。通常、クライアント・アプリケーションは、Keycloakでユーザーが正常に認証された後にAATを取得します。デフォルトでは、 authorization_code グラント・タイプはユーザーの認証に使用され、サーバーは代わりにクライアント・アプリケーションにOAuth2アクセス・トークンを発行します。
以下の例では、リソース・オーナー・パスワード・クレデンシャル・グラント・タイプを使用してAATをリクエストしています。
curl -X POST \
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpwYXNzd29yZA==" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'username=${username}&password=${user_password}&grant_type=password' \
"http://localhost:8080/auth/realms/${realm_name}/protocol/openid-connect/token"
その結果、サーバーの応答は次のようになります。
{
"access_token": ${AAT},
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": ${refresh_token},
"token_type": "bearer",
"id_token": ${id_token},
"not-before-policy": 0,
"session_state": "3cad2afc-855b-47b7-8e4d-a21c66e312fb"
}
8.2.2. 認可データとトークンの要求
UMAプロトコルを使用するクライアント・アプリケーションは、特定のエンドポイントを使用して、リクエスティング・パーティー・トークン(RPT)と呼ばれる特別なセキュリティー・トークンを取得できます。このトークンは、要求されているリソースに関連するパーミッションおよび認可ポリシーの評価の結果として、ユーザーに付与されたすべてのパーミッションで構成されます。RPTを使用すると、クライアント・アプリケーションはリソースサーバーで保護されたリソースにアクセスできます。
http://${host}:${port}/auth/realms/${realm_name}/authz/authorize
RPTを要求するときは、次の2つのことを指定する必要があります。
-
アクセスしたいリソースを表すパーミッション・チケット
-
(ベアラートークンとして)ユーザーのアイデンティティーを表す認可APIトークン(AAT)、およびそのユーザーに代わって認可データにアクセスするための同意。
パーミッション・チケットは、ベアラートークンとしてAATを使用してリクエストを認証するために、AATが
ヘッダーに含まれているかどうかを示すパラメーターとして、HTTPリクエストに追加されます。Authorization
curl -X POST
-H "Authorization: Bearer ${AAT}" -d '{
"ticket" : ${PERMISSION_TICKET}
}' "http://localhost:8080/auth/realms/hello-world-authz/authz/authorize"
その結果、サーバーの応答は次のようになります。
{"rpt":"${RPT}"}
8.3. エンタイトルメントAPI
エンタイトルメントAPIは、サーバーから認可データを取得するための1-leggedプロトコルを提供します。ここで、認可データは、要求されているリソースに関連するすべてのパーミッションおよび認可ポリシーの評価の結果を表します。
Authorization API とは異なり、エンタイトルメントAPIはUMA準拠ではなく、パーミッション・チケットを必要としません。
このAPIの目的は、有効なOAuth2アクセストークンを所有しているクライアントが、ユーザーに代わって必要な認可データを取得できる、認可データを取得するためのより軽量なAPIを提供することです。
8.3.1. エンタイトルメントの要求
クライアント・アプリケーションは、特定のエンドポイントを使用して、リクエスティング・パーティー・トークン(RPT)と呼ばれる特別なセキュリティ・トークンを取得できます。このトークンは、要求されているリソースに関連する権限および認可ポリシーの評価の結果として、ユーザーのすべてのエンタイトルメント(または権限)で構成されます。RPTを使用すると、クライアント・アプリケーションはリソース・サーバーで保護されたリソースにアクセスできます。
http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}
Keycloakでリソースサーバーとして機能するクライアント・アプリケーションを識別するために、上記の client_id パラメーターを指定する必要があります。評価の範囲を特定のリソースサーバーによって管理されるリソース、スコープおよび権限に制限するには、クライアント識別子を指定する必要があります。
エンタイトルメントAPIには次の2種類があります。
-
HTTP GET を使用して、特定のユーザーが所有するリソース、および(または)リソースサーバー自体が所有、管理する一般的なリソースに基づくすべてのエンタイトルメントを取得します。
-
HTTP POST を使用して、エンタイトルメントのリクエストと共に送信される1つ以上のリソースとスコープのセットに基づくエンタイトルメントを取得します。
どちらを使用するかは、ユースケースとKeycloakに登録したリソースの量によって異なります。 GET は、サーバーからのエンタイトルメントを取得する簡単な方法を提供しますが、ユーザーに関連するリソースが多すぎる場合には、適切ではない可能性があります。この場合は、 POST メソッドが推奨されます。 |
エンタイトルメントAPIエンドポイントは、ユーザーの識別情報を表すリクエスト内のアクセス・トークンと、ユーザーの代理として認可データにアクセスするための同意を期待します。アクセス・トークンは、HTTP
ヘッダーを使用してベアラー・トークンとして送信する必要があります。Authorization
エンタイトルメントAPIエンドポイントを正常に呼び出すと、サーバーによって付与されたすべての権限を持つRPTが取得されます。
エンタイトルメントの取得
特定のユーザーのエンタイトルメントを取得する最も簡単な方法は、HTTP GETリクエストを使用することです。たとえば、次のようにcurlを使用します。
curl -X GET \
-H "Authorization: Bearer ${access_token}" \
"http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
その結果、サーバーの応答は次のようになります。
{
"rpt": ${RPT}
}
このメソッドを使用してエンタイトルメントを取得すると、サーバーは、ユーザーまたはリソース・サーバー自体が所有するリソースに関連付けられている権限および認可ポリシーの評価に基づいて、ユーザーの すべて のエンタイトルメントを要求元のクライアントに応答します。例えば、次のリソースのKeycloakで定義されている権限があるとします。
-
Main Page
-
Alice Bank Account
-
Bob Bank Account
Main Page はアプリケーションの共通リソースで、リソースサーバー自体が所有しています。アプリケーションのランディング・ページまたはメインページを表します。一方、 Alice Bank Account は、ユーザー alice が所有者であるリソースです。別のユーザー bob が所有している Bob Bank Account についても同様です。
ユーザー alice のエンタイトルメントを取得するとき、サーバーはリソースの Main Page と Alice Bank Account に関連するすべての権限を評価します。これらのリソースを表す権限のセットを使用してRPT(実際に権限が与えられた場合)を返します。
特定のリソースのセットに対するエンタイトルメントの取得
エンタイトルメント・エンドポイントを使用して、1つ以上のリソースのセットに対するユーザーのエンタイトルメントを取得することもできます。たとえば、次のようにcurlを使用します。
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer ${access_token}" -d '{
"permissions" : [
{
"resource_set_name" : "Alice Bank Account"
}
]
}' "http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
その結果、サーバーの応答は次のようになります。
{
"rpt": ${RPT}
}
GETバージョンとは異なり、サーバーは、要求されているリソースに関連付けられている権限および許可ポリシーの評価中に付与された権限を保持するRPTで応答します。
アクセスするスコープを指定することもできます。たとえば、次のようにcurlを使用します。
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
"permissions" : [
{
"resource_set_name" : "Alice Bank Account",
"scopes" : [
"withdraw"
]
}
]
}' "http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
8.3.2. エンタイトルメント・リクエスト・メタデータ
エンタイトルメントを要求するとき、クライアント・アプリケーションは、メタデータ情報をリクエストに関連付けさせて、パーミッションの取得方法を定義することができます。
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
"metadata" : {
"include_resource_name" : false
},
"permissions" : [
...
]
}' "http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
エンタイトルメントAPIエンドポイントでは、HTTP POSTを使用しているときにエンタイトルメント・リクエストに沿ってメタデータを渡すことしかできません。 |
次のセクションでは、エンタイトルメント・リクエストに含めることができるさまざまな情報を、メタデータとして使用する方法とタイミングについて説明します。
8.3.3. リソースの名前をレスポンスに含めるかどうかを決定する
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
"metadata" : {
"include_resource_name" : false
},
"permissions" : [
...
]
}' "http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
クライアントは、
を使用して、サーバーによって付与された各パーミッションにリソースの名前を含めるかどうかを決定できます。このオプションを使用すると、RPTのサイズを縮小し、クライアントとサーバー間の通信を最適化できます。include_resource_name
デフォルトでは、RPT内のパーミッションには、単一のパーミッションごとに付与されたリソースのIDと名前の両方が含まれています。このオプションは、リソース・サーバーがリソースのIDに基づいてのみリソースをマップできる場合に特に便利です。
8.3.4. RPT内のパーミッションの数を制限する
curl -X POST -H "Authorization: Bearer ${access_token}" -d '{
"metadata" : {
"limit" : 10
},
"permissions" : [
...
]
}' "http://${host}:${port}/auth/realms/${realm_name}/authz/entitlement/{client_id}"
クライアントは、
を使用して、サーバーから返されるRPT内で予想されるパーミッションの数を指定できます。制限オプションは次のように動作します。limit
-
以前に発行されたRPTを 使用せず にリクエストが送信された場合、
クレームのリソース/スコープに基づいて、permissions
パーミッションのみが返されます。limit
-
以前に発行されたRPTを 使用して リクエストが送信された場合、以前に発行されたRPTのパーミッションが
に達していない場合にのみ、limit
クレームのリソース/スコープに関連付けられたパーミッションが優先されます。以前に発行されたRPTからの権限に対して十分な空きがある場合、サーバーはそこに定義されている最初のパーミッションを含めます。permissions
このオプションを使用すると、クライアントはRPTのサイズを制御し、サーバーによって付与された最後の権限のみを保持できます。クライアントが以前に発行されたRPTを送信することができ、新しい権限(別名: Incremental Authorization)を求めている場合にのみ意味があります。
8.4. リクエスティング・パーティ・トークン
Requesting party token(RPT)は JSON web signature(JWS) でデジタル署名された JSON web token(JWT) です。RPTは、Keycloakによって発行されたOAuth2アクセストークンをベースとして、ユーザーの代わりに動作する特定のクライアントに組み込まれます。
RPT をデコードすると、次のようなペイロードが得られます:
{
"authorization": {
"permissions": [
{
"resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
"resource_set_name": "Hello World Resource"
}
]
},
"jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405",
"exp": 1464906971,
"nbf": 0,
"iat": 1464906671,
"sub": "f1888f4d-5172-4359-be0c-af338505d86c",
"typ": "kc_ett",
"azp": "hello-world-authz-service"
}
このトークンの permissions クレームから、サーバーによって与えられる全てのパーミッションを取得できます。
パーミッションは保護されたリソース/スコープに直接関連していますが、アクセス・コントロール・メソッドからは完全に独立していることに注意して下さい。
8.4.1. リクエスティング・パーティー・トークンのイントロスペクション
場合によっては、リクエスティング・パーティー・トークン(RPT)をイントロスペクトして、その有効性をチェックしたり、トークン内の権限を取得して、リソース・サーバー側で認可の決定を行うことがあります。
トークンのイントロスペクションが役立つ2つの主な使用例があります。
-
クライアント・アプリケーションがトークンの有効性を問い合わせて、同じまたは追加の権限を持つ新しいトークンを取得する必要がある場合
-
リソース・サーバー側で認可の決定を実施する場合、特に組み込みのポリシー・エンフォーサーがアプリケーションに適合しない場合
8.4.2. RPTに関する情報の取得
トークン・イントロスペクションは基本的に、RPTに関する情報を取得するための OAuth2トークン・イントロスペクション 準拠のエンドポイントです。
http://${host}:${port}/auth/realms/${realm_name}/protocol/openid-connect/token/introspect
このエンドポイントを使用してRPTをイントロスペクションするには、次のようにしてサーバーにリクエストを送信します。
curl -X POST \
-H "Authorization: Basic aGVsbG8td29ybGQtYXV0aHotc2VydmljZTpzZWNyZXQ=" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'token_type_hint=requesting_party_token&token=${RPT}' \
"http://localhost:8080/auth/realms/hello-world-authz/protocol/openid-connect/token/introspect"
上記のリクエストは、HTTP BASICを使用し、クライアントのクレデンシャル(クライアントIDとシークレット)を渡してトークンのイントロスペクションを試みるクライアントを認証しますが、Keycloakでサポートされている他のクライアント認証方式を使用することもできます。 |
イントロスペクション・エンドポイントには2つのパラメータが必要です。
-
token_type_hint
このパラメーターの値として requesting_party_token を使用します。これは、RPTをイントロスペクションすることを示します。
-
token
このパラメーターの値として、認可処理中にサーバーから返されたトークン文字列を使用します。
その結果、サーバーの応答は次のようになります。
{
"permissions": [
{
"resource_set_id": "90ccc6fc-b296-4cd1-881e-089e1ee15957",
"resource_set_name": "Hello World Resource"
}
],
"exp": 1465314139,
"nbf": 0,
"iat": 1465313839,
"aud": "hello-world-authz-service",
"active": true
}
RPTがアクティブでない場合、代わりにこのレスポンスが返されます。
{
"active": false
}
8.4.3. RPTをイントロスペクションするたびにサーバーを呼び出す必要がありますか?
いいえ、両方のエンタイトルメントAPIは、RPTのデフォルトの形式として JSON web token(JWT) 仕様を使用します。
リモート・イントロスペクション・エンドポイントを呼び出さずにこれらのトークンを検証する場合は、RPTをデコードしてローカルでその有効性を問い合わせることができます。トークンをデコードすると、トークン内の権限を使用して認可の決定を行うこともできます。
これは本来、ポリシー・エンフォーサーが行うことです。次のことを確認してください。
-
RPTのシグネチャーを検証する(レルムの公開鍵に基づいて)
-
exp 、iat 、および_aud_のクレームに基づいてトークンの有効性を問い合わせる
8.5. 認可クライアントJava API
要件に応じて、リソース・サーバーはリソースをリモートで管理したり、プログラムでパーミッションをチェックしたりすることもできます。Javaを使用している場合は、認可クライアントAPIを使用してKeycloak認可サービスにアクセスできます。
これは、保護API、認可API、エンタイトルメントAPIなど、サーバーが提供するさまざまなAPIにアクセスするリソース・サーバーを対象としています。
8.5.1. Maven依存関係
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-authz-client</artifactId>
<version>${KEYCLOAK_VERSION}</version>
</dependency>
</dependencies>
8.5.2. 設定
クライアントの設定は、 keycloak.json
ファイルで次のように定義されています。
{
"realm": "hello-world-authz",
"auth-server-url" : "http://localhost:8080/auth",
"resource" : "hello-world-authz-service",
"credentials": {
"secret": "secret"
}
}
-
realm (required)
レルムの名前。
-
auth-server-url (required)
KeycloakサーバーのベースURL。 他のすべてのKeycloakページとRESTサービス・エンドポイントは、これから派生しています。通常、https://host:port/authという形式です。
-
resource (required)
アプリケーションのクライアントID。各アプリケーションには、アプリケーションを識別するために使用されるクライアントIDがあります。
-
credentials (required) アプリケーションのクレデンシャルを指定します。これは、キーがクレデンシャル・タイプであり、値がクレデンシャル・タイプの値であるオブジェクトの表記法です。
設定ファイルは通常、クライアントの
ファイルを見つける際のデフォルトのローケーションであるアプリケーションのクラスパスにあります。keycloak.json
8.5.3. 認可クライアントの作成
クラスパスに
ファイルがあることを考慮して、次のように新しい keycloak.json
インスタンスを作成することができます。AuthzClient
// create a new instance based on the configuration defined in a keycloak.json located in your classpath
AuthzClient authzClient = AuthzClient.create();
8.5.4. ユーザー・エンタイトルメントの取得
ユーザー・エンタイトルメントを取得する方法の例を示します。
// create a new instance based on the configuration defined in keycloak-authz.json
AuthzClient authzClient = AuthzClient.create();
// obtain an Entitlement API Token to get access to the Entitlement API.
// this token is an access token issued to a client on behalf of an user
// with a uma_authorization scope
String eat = getEntitlementAPIToken(authzClient);
// send the entitlement request to the server to
// obtain an RPT with all permissions granted to the user
EntitlementResponse response = authzClient.entitlement(eat).getAll("hello-world-authz-service");
String rpt = response.getRpt();
// now you can use the RPT to access protected resources on the resource server
1つ以上のリソースのセットに対してユーザー・エンタイトルメントを取得する方法の例を示します。
// create a new instance based on the configuration defined in keycloak-authz.json
AuthzClient authzClient = AuthzClient.create();
// obtain an Entitlement API Token to get access to the Entitlement API.
// this token is an access token issued to a client on behalf of an user
// with a uma_authorization scope
String eat = getEntitlementAPIToken(authzClient);
// create an entitlement request
EntitlementRequest request = new EntitlementRequest();
PermissionRequest permission = new PermissionRequest();
permission.setResourceSetName("Hello World Resource");
request.addPermission(permission);
// send the entitlement request to the server to obtain an RPT
// with all permissions granted to the user
EntitlementResponse response = authzClient.entitlement(eat).get("hello-world-authz-service", request);
String rpt = response.getRpt();
// now you can use the RPT to access protected resources on the resource server
8.5.5. 保護APIを使用したリソースの作成
// create a new instance based on the configuration defined in keycloak-authz.json
AuthzClient authzClient = AuthzClient.create();
// create a new resource representation with the information we want
ResourceRepresentation newResource = new ResourceRepresentation();
newResource.setName("New Resource");
newResource.setType("urn:hello-world-authz:resources:example");
newResource.addScope(new ScopeRepresentation("urn:hello-world-authz:scopes:view"));
ProtectedResource resourceClient = authzClient.protection().resource();
Set<String> existingResource = resourceClient.findByFilter("name=" + newResource.getName());
if (!existingResource.isEmpty()) {
resourceClient.delete(existingResource.iterator().next());
}
// create the resource on the server
RegistrationResponse response = resourceClient.create(newResource);
String resourceId = response.getId();
// query the resource using its newly generated id
ResourceRepresentation resource = resourceClient.findById(resourceId).getResourceDescription();
8.5.6. RPTのイントロスペクション
AuthzClient authzClient = AuthzClient.create();
String rpt = getRequestingPartyToken(authzClient);
TokenIntrospectionResponse requestingPartyToken = authzClient.protection().introspectRequestingPartyToken(rpt);
if (requestingPartyToken.getActive()) {
for (Permission granted : requestingPartyToken.getPermissions()) {
// iterate over the granted permissions
}
}
9. ポリシー・エンフォーサー
ポリシー実施ポイント(PEP)は設計パターンとなり、さまざまな方法で実装できます。Keycloakは、さまざまなプラットフォーム、環境、およびプログラミング言語に対してPEPを実装するために必要なすべての手段を提供します。Keycloak認可サービスは、RESTfulなAPIを提供し、一元的な認可サーバーを使用してきめ細かな認可を行うための、OAuth2認可機能を活用します。
9.1. Keycloak アダプター・ポリシー・エンフォーサー
Keycloak OIDCアダプターを使用している場合は、アプリケーションの認可の決定を行うことができます。
Keycloakアプリケーションのポリシーの適用を有効にすると、対応するアダプターはアプリケーションへのすべてのリクエストをインターセプトし、サーバーから取得した認可の決定を行います。
ポリシー適用は、アプリケーションのパスと、Keycloak管理コンソールを使用してリソースサーバー用に作成したリソースに強く関連しています。デフォルトでは、リソースサーバーを作成すると、Keycloakはリソースサーバーのデフォルト設定を作成し、ポリシー適用を即時に有効化することができます。
デフォルト設定では、認証されたユーザーが保護対象のリソースサーバーと同じレルムに属している場合、アプリケーション内のすべてのリソースにアクセスできます。
9.1.1. ポリシー適用の設定
アプリケーションのポリシー適用を有効にするには、 keycloak.json ファイルに次のプロパティーを追加します。
{
"policy-enforcer": {}
}
または、保護されているリソースを手動で定義する場合は、以下のようにもう少し詳細化します。
{
"policy-enforcer": {
"user-managed-access" : {},
"enforcement-mode" : "ENFORCING"
"paths": [
{
"path" : "/someUri/*",
"methods" : [
{
"method": "GET",
"scopes" : ["urn:app.com:scopes:view"]
},
{
"method": "POST",
"scopes" : ["urn:app.com:scopes:create"]
}
]
},
{
"name" : "Some Resource",
"path" : "/usingPattern/{id}",
"methods" : [
{
"method": "DELETE",
"scopes" : ["urn:app.com:scopes:delete"]
}
]
},
{
"path" : "/exactMatch"
},
{
"name" : "Admin Resources",
"path" : "/usingWildCards/*"
}
]
}
}
各設定オプションの説明は次のとおりです。
-
policy-enforcer
ポリシーが実際にどのように実施されるのかを定義する設定オプションと、保護したいパス(任意)を指定します。指定されていない場合、ポリシー・エンフォーサーは、保護されているリソースサーバーに関連付けられているすべてのリソースをサーバーに問い合わせます。この場合、保護するパスと一致するURIプロパティを持つリソースが適切に設定されていることを確認する必要があります。
-
user-managed-access
アダプターがUMAプロトコルを使用することを指定します。指定されている場合、アダプターはサーバーにパーミッション・チケットを問い合わせ、UMA仕様に従ってクライアントに戻します。指定されていない場合、アダプターはサーバーに送信されたリクエスティング・パーティー・トークン(RPT)に基づいてパーミッションを適用します。
-
enforcement-mode
ポリシーの適用方法を指定します。
-
ENFORCING
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
-
PERMISSIVE
Requests are allowed even when there is no policy associated with a given resource.
-
DISABLED
ポリシーの評価を完全に無効にし、任意のリソースへのアクセスを許可します。
-
-
on-deny-redirect-to
サーバーから"access denied"のメッセージを取得したときに、クライアント・リクエストがリダイレクトされるURLを定義します。デフォルトでは、アダプターは403 HTTPステータスコードで応答します。
-
paths
保護するパスを指定します。
-
name
指定されたパスに関連付けられるサーバー上のリソースの名前。ポリシー・エンフォーサーは、 path と組み合わせて使用すると、リソースの URI プロパティーを無視し、代わりに指定したパスを使用します。 * path
(必須)アプリケーションのコンテキストパスに関連するURI。このオプションを指定すると、ポリシー・エンフォーサーは、同じ値の URI を持つリソースをサーバーに問い合わせます。現在、パスマッチングのための最も基本的なロジックがサポートされています。有効なパスの例は次のとおりです。
-
Wildcards:
/*
-
Suffix:
/*.html
-
Sub-paths:
/path/*
-
Path parameters: /resource/{id}
-
Exact match: /resource
-
Patterns: /{version}/resource, /api/{version}/resource, /api/{version}/resource/*
-
-
methods 保護するHTTPメソッド(GET、POST、PATCHなど)と、サーバー内の特定のリソースのスコープにどのように関連付けられているかを示します。 +[/'']
-
method
HTTPメソッドの名前。
-
scopes
メソッドに関連付けられたスコープを持つ文字列の配列。スコープを特定のメソッドに関連付けると、保護されたリソース(またはパス)にアクセスしようとするクライアントは、そのリストに指定されたすべてのスコープにアクセス権を与えるRPTを提供する必要があります。例えば、スコープ create を持つメソッド POST を定義した場合、RPTにはパスへのPOSTを実行したときに create スコープへのアクセスを許可するパーミッションが含まれていなければなりません。
-
scopes-enforcement-mode
メソッドに関連付けられたスコープの強制モードを参照する文字列。値は ALL または ANY にすることができます。 ALL の場合、そのメソッドを使用してリソースにアクセスするには、すべての定義されたスコープを付与する必要があります。 ANY の場合は、そのメソッドを使用してリソースにアクセスするために、少なくとも1つのスコープを付与する必要があります。デフォルトでは、強制モードは ALL に設定されています。
-
-
enforcement-mode
ポリシーの適用方法を指定します。
-
ENFORCING
(default mode) Requests are denied by default even when there is no policy associated with a given resource.
-
DISABLED
パスのポリシーの評価を無効にします。
-
-
-
9.1.2. ベアラー・トークンを使用したステートレス・サービスの保護
アダプターが bearer-only
の設定オプションで設定されている場合、ポリシー・エンフォーサーは、ベアラー・トークンのパーミッションに基づいて、保護されたリソースへのアクセス・リクエストが許可または拒否されるかどうかを決定します。
-
ベアラー・トークンとしてRPTを渡すHTTP GETの例
GET /my-resource-server/my-protected-resource HTTP/1.1
Host: host.com
Authorization: Bearer ${RPT}
...
この例では、アプリケーションの keycloak.json ファイルは次のようになります。
...
"bearer-only" : true,
...
認可レスポンス
クライアントが、保護されたリソースにアクセスするためのパーミッションがないベアラー・トークンを持つリソース・サーバーにアクセスしようとすると、リソース・サーバーは 401 ステータスコードと WWW-Authenticate
ヘッダーで応答します。 WWW-Authenticate
ヘッダーの値は、リソース・サーバーで使用されている認可プロトコルによって異なります。
次に、認可プロトコルとしてUMAを使用しているリソース・サーバーからのレスポンスの例を示します。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="photoz-restful-api",as_uri="http://localhost:8080/auth/realms/photoz/authz/authorize",ticket="${PERMISSION_TICKET}"
また、リソース・サーバーがエンタイトルメント・プロトコルを使用している場合の別の例を以下に示します。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: KC_ETT realm="photoz-restful-api",as_uri="http://localhost:8080/auth/realms/photoz/authz/entitlement"
クライアントがサーバーからレスポンスを受け取ると、ステータス・コードと WWW-Authenticate
ヘッダーを調べて、KeycloakサーバーからRPTを取得します。
9.1.3. 認可コンテキストの取得
ポリシーの施行が有効になっている場合、サーバーから取得したパーミッションは org.keycloak.AuthorizationContext
で利用できます。このクラスは、パーミッションを取得し、特定のリソースまたはスコープに対してアクセス権が付与されているかどうかを確認するために使用できるいくつかのメソッドを提供します。
サーブレット・コンテナ-内の認可コンテキストの取得
HttpServletRequest request = ... // 取得javax.servlet.http.HttpServletRequest
KeycloakSecurityContext keycloakSecurityContext =
(KeycloakSecurityContext) request
.getAttribute(KeycloakSecurityContext.class.getName());
AuthorizationContext authzContext =
keycloakSecurityContext.getAuthorizationContext();
KeycloakSecurityContext を得る方法の詳細については、アダプターの設定を参照してください。Keycloakでサポートされているサーブレット・コンテナーのいずれかを使用してアプリケーションを起動している場合は、上記の例でコンテキストを取得できます。
|
認可コンテキストを使用すると、サーバーによって行われて返された決定を、より詳細に制御できます。たとえば、リソースまたはスコープに関連付けられたパーミッションに応じて、アイテムを表示または非表示にする動的なメニューを作成することができます。
if (authzContext.hasResourcePermission("Project Resource")) {
// user can access the Project Resource
}
if (authzContext.hasResourcePermission("Admin Resource")) {
// user can access administration resources
}
if (authzContext.hasScopePermission("urn:project.com:project:create")) {
// user can create new projects
}
AuthorizationContext
は、Keycloak認可サービスのメイン機能の1つです。上記の例から、保護されたリソースはそれらを管理するポリシーに直接関連付けられていないことが分かります。
次のような、ロールベースのアクセス制御(RBAC)を使用した同様のコードを考えてみましょう。
if (User.hasRole('user')) {
// user can access the Project Resource
}
if (User.hasRole('admin')) {
// user can access administration resources
}
if (User.hasRole('project-manager')) {
// user can create new projects
}
どちらの例も同じ要件に対応していますが、異なる方法で対応しています。RBACでは、ロールはリソースに対するアクセスのみを 暗黙的に 定義します。Keycloakを使用すると、RBAC、属性ベースのアクセス制御(ABAC)、その他のBACバリアントのいずれを使用していても、リソースに直接フォーカスした管理しやすいコードを作成できます。与えられたリソースまたはスコープに対するパーミッションを持っているかどうかです。
セキュリティ要件が変更され、プロジェクト・マネージャーに加えて、PMOが新しいプロジェクトを作成できるようになったとします。
セキュリティ要件は変更されますが、Keycloakを使用すると、新しい要件を満たすためにアプリケーションコードを変更する必要はありません。アプリケーションがリソースとスコープの識別子に基づいていれば、認可サーバー内の特定のリソースに関連付けられているパーミッションまたはポリシーの設定を変更するだけで済みます。この場合、 Project Resource
および(または)スコープ urn:project.com:project:create
に関連するパーミッションとポリシーが変更されます。
9.1.4. 認可クライアント・インスタンスを取得するためAuthorizationContextを使用する
AuthorizationContext
は、以下のようにアプリケーションに設定された認可クライアントAPIへの参照を取得するためにも使用できます。
ClientAuthorizationContext clientContext = ClientAuthorizationContext.class.cast(authzContext);
AuthzClient authzClient = clientContext.getClient();
場合によっては、ポリシー・エンフォーサーによって保護されたリソース・サーバーが、認可サーバーによって提供されるAPIにアクセスする必要があります。取得した
インスタンスで、リソース・サーバーはリソースを作成したり、プログラムで特定のパーミッションをチェックするためにサーバーとやりとりすることができます。AuthzClient
9.1.5. JavaScriptの統合
Keycloakサーバーには、ポリシー・エンフォーサーによって保護されたリソース・サーバーと対話するために使用できるJavaScriptライブラリが付属しています。このライブラリはKeycloak JavaScriptアダプターに基づいています。これを統合すると、クライアントはKeycloakサーバーからアクセス権を取得できます。
次の script
タグをWebページに含めることで、実行中のKeycloakサーバー・インスタンスからこのライブラリを入手できます。
<script src="http://.../auth/js/keycloak-authz.js"></script>
これを実行すると、次のように KeycloakAuthorization
インスタンスを作成できます。
var keycloak = ... // obtain a Keycloak instance from keycloak.js library
var authorization = new KeycloakAuthorization(keycloak);
keycloak-authz.js ライブラリには2つの主な機能があります。
-
Keycloakポリシー・エンフォーサーによって保護されたリソース・サーバーからのレスポンスを処理し、リソース・サーバー上の保護されたリソースにアクセスするために必要な権限を持つリクエスティング・パーティー・トークン(RPT)を取得します。
-
この場合、ライブラリは、リソース・サーバーが使用している認可プロトコル(エンタイトルメント)を処理できます。
-
-
エンタイトルメントAPIを使用してKeycloakサーバーから権限を取得します。
いずれの場合も、リソース・サーバーとKeycloak認可サービスの両方との対話を容易にし、クライアントがリソース・サーバー上の保護されたリソースにアクセスするベアラー・トークンとして使用できる権限を持つトークンを取得できます。
リソース・サーバーからの認可レスポンスの処理
リソース・サーバーがポリシー・エンフォーサーによって保護されている場合、リソース・サーバーは、ベアラートークンベアラー・トークンとともに送信される権限に基づいてクライアント・リクエストに応答します。通常、保護されたリソースにアクセスするための権限がないベアラー・トークンを使用してリソース・サーバーにアクセスしようとすると、リソース・サーバーは 401 ステータスコードと WWW-Authenticate
ヘッダーで応答します。
WWW-Authenticate
ヘッダーの値は、リソース・サーバーで使用されている認可プロトコルによって異なります。使用中のプロトコルが何であれ、 KeycloakAuthorization
インスタンスを使用して次のようにレスポンスを処理できます。
var wwwAuthenticateHeader = ... // extract WWW-Authenticate Header from the response in case of a 401 status code
authorization.authorize(wwwAuthenticateHeader).then(function (rpt) {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
}, function () {
// onDeny callback function.
// Called when the authorization request is denied by the server
}, function () {
// onError callback function. Called when the server responds unexpectedly
});
authorize
関数は完全に非同期で、サーバーからの通知を受け取るためのいくつかのコールバック関数をサポートしています。
-
onGrant
: 関数の第1引数。認可が成功し、サーバーが要求された権限でRPTを返した場合、コールバックはRPTを受け取ります。 -
onDeny
: 関数の第2引数。サーバーがリクエストを拒否した場合にのみ呼び出されます。 -
onError
: 関数の第3引数。サーバーが予期せず応答する場合にのみ呼び出されます。
ほとんどのアプリケーションは、 onGrant
コールバックを使用して401応答後にリクエストをリトライする必要があります。以降のリクエストには、RPTをリトライのためのベアラー・トークンとして含める必要があります。
エンタイトルメントの取得
keycloak-authz.jsライブラリには、エンタイトルメントAPIを使用してサーバーからRPTを取得するために使用できる entitlement
関数が用意されています。
authorization.entitlement('my-resource-server-id').then(function (rpt) {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
});
entitlement
を使用する場合は、アクセスするリソース・サーバーの client_id を指定する必要があります。
entitlement
関数は完全に非同期で、サーバーからの通知を受け取るためのコールバック関数をいくつかサポートしています。
-
onGrant
: 関数の第1引数。認可が成功し、サーバーが要求された権限でRPTを返した場合、コールバックはRPTを受け取ります。 -
onDeny
: 関数の第2引数。サーバーがリクエストを拒否した場合にのみ呼び出されます。 -
onError
: 関数の第3引数。サーバーが予期せず応答する場合にのみ呼び出されます。