第9章 ポリシーエンフォーサー
Policy Enforcement Point (PEP: Policy Enforcement Point) は、異なる方法で実装できる設計パターンです。Red Hat build of Keycloak は、さまざまなプラットフォーム、環境、およびプログラミング言語に PEP を実装するのに必要な方法をすべて提供します。Red Hat build of Keycloak Authorization Services は RESTful API を提供し、一元化された認可サーバーを使用して詳細な認可に OAuth2 認可機能を活用します。
Red Hat build of Keycloak で利用可能な Policy Enforcer は次のとおりです。
- Java Policy Enforcer - Java クライアントアプリケーションで使用すると便利です。
- Javascript Policy Enforcer - Red Hat build of Keycloak Javascript アダプターで保護されたアプリケーションで使用すると便利です。
9.1. Policy Enforcer の JavaScript インテグレーション リンクのコピーリンクがクリップボードにコピーされました!
Red Hat build of Keycloak サーバーには JavaScript ライブラリーが含まれており、このライブラリーを使用して、ポリシーエンフォーサーで保護されたリソースサーバーとの対話に使用できます。このライブラリーは、Red Hat build of Keycloak JavaScript アダプターをベースとしています。これを統合して、クライアントが Red Hat build of Keycloak サーバーからパーミッションを取得できるようにすることができます。
このライブラリーは、NPM から インストールすることで入手できます。
npm install keycloak-js
次に、以下のように KeycloakAuthorization インスタンスを作成できます。
import Keycloak from "keycloak-js";
import KeycloakAuthorization from "keycloak-js/authz";
const keycloak = new Keycloak({
url: "http://keycloak-server",
realm: "my-realm",
clientId: "my-app"
});
const authorization = new KeycloakAuthorization(keycloak);
await keycloak.init();
// Now you can use the authorization object to interact with the server.
keycloak-js/authz ライブラリーは、主に 2 つの機能を提供します。
- UMA 保護リソースサーバーにアクセスする場合、パーミッションチケットを使用してサーバーからパーミッションを取得します。
- リソースを送信し、アプリケーションがアクセスできるスコープを指定して、サーバーからパーミッションを取得します。
どちらの場合も、ライブラリーを使用することで、リソースサーバーと Red Hat build of Keycloak Authorization Services の両方と簡単に対話して、クライアントがベアラートークンとして使用してリソースサーバー上で保護されているリソースにアクセスするためのパーミッションを持つトークンを取得できます。
9.1.1. UMA-Protected Resource Server からの認可応答の処理 リンクのコピーリンクがクリップボードにコピーされました!
ポリシーエンフォーバーによってリソースサーバーが保護されている場合、ベアラートークンとともに実行されたパーミッションに基づいてクライアント要求に応答します。通常、保護されているリソースへのアクセスパーミッションがないベアラートークンを持つリソースサーバーにアクセスしようとすると、リソースサーバーは 401 ステータスコードと WWW-Authenticate ヘッダーを返します。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
as_uri="https://${host}:${port}/realms/${realm}",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
詳細は、UMA 認可プロセス を参照してください。
クライアントが必要とする内容は、リソースサーバーから返された ヘッダーからパーミッションチケットを抽出し、以下のようにライブラリーを使用して認可要求を送信します。
WWW-Authenticate
// prepare a authorization request with the permission ticket
const authorizationRequest = { ticket };
// send the authorization request, if successful retry the request
authorization.authorize(authorizationRequest).then((rpt) => {
// onGrant
}, () => {
// onDeny
}, () => {
// onError
});
authorize 機能は完全に非同期で、サーバーから通知を受信するいくつかのコールバック機能をサポートします。
-
onGrant: 関数の最初の引数。認可が成功し、サーバーが要求されたパーミッションを持つ RPT を返す場合、コールバックは RPT を受け取ります。 -
onDeny: 関数の 2 つ目の引数。サーバーが認可要求を拒否した場合にのみ呼び出されます。 -
onError: 関数の 3 つ目の引数。サーバーが予期せず応答する場合にのみ呼び出されます。
ほとんどのアプリケーションは、onGrant コールバックを使用して、401 応答の後にリクエストを再試行する必要があります。後続の要求には、再試行のベアラートークンとして RPT を含める必要があります。
9.1.2. エンタイトルメントの取得 リンクのコピーリンクがクリップボードにコピーされました!
keycloak-js/authz ライブラリーは、クライアントがアクセスするリソースとスコープを提供することで、サーバーから RPT を取得するために使用できる entitlement 関数を提供します。
すべてのリソースのパーミッションと、ユーザーがアクセスできるスコープが設定された RPT を取得する方法の例
authorization.entitlement("my-resource-server-id").then((rpt) => {
// onGrant callback function.
// If authorization was successful you'll receive an RPT
// with the necessary permissions to access the resource server
});
特定のリソースおよびスコープのパーミッションのある RPT を取得する方法の例
authorization.entitlement("my-resource-server", {
permissions: [
{
id: "Some Resource"
}
]
}).then((rpt) => {
// onGrant
});
エンタイトルメント 機能を使用する場合は、アクセスするリソースサーバーの client_id を指定する必要があります。
エンタイトルメント 機能は完全に非同期で、サーバーから通知を受信するためのコールバック関数をいくつかサポートします。
-
onGrant: 関数の最初の引数。認可が成功し、サーバーが要求されたパーミッションを持つ RPT を返す場合、コールバックは RPT を受け取ります。 -
onDeny: 関数の 2 つ目の引数。サーバーが認可要求を拒否した場合にのみ呼び出されます。 -
onError: 関数の 3 つ目の引数。サーバーが予期せず応答する場合にのみ呼び出されます。
9.1.3. 認可要求 リンクのコピーリンクがクリップボードにコピーされました!
authorize と entitlement 関数はどちらも認可要求オブジェクトを受け入れます。このオブジェクトは以下のプロパティーで設定できます。
permissions
リソースとスコープを表すオブジェクトの配列。以下に例を示します。
const authorizationRequest = { permissions: [ { id: "Some Resource", scopes: ["view", "edit"] } ] }metadata
プロパティーが、サーバーによる認可要求の処理方法を定義するオブジェクト。
response_include_resource_name
リソース名を RPT のパーミッションに含める必要があるかどうかを示すブール値。false の場合、リソース識別子のみが含まれます。
response_permissions_limit
RPT が持つパーミッションの量の制限を定義する整数 N。
rptパラメーターとともに使用する場合は、最後に要求された N 個のパーミッションのみが RPT に保持されます。
submit_request
サーバーがリソースに対するパーミッション要求を作成するかどうか、およびパーミッションチケットによって参照されるスコープを許可するかどうかを示すブール値。このパラメーターは、UMA 認可プロセスの一部として
ticketパラメーターと共に使用する場合にのみ有効になります。
9.1.4. RPT の取得 リンクのコピーリンクがクリップボードにコピーされました!
ライブラリーが提供するいずれかの認可機能を使用して RPT をすでに取得している場合は、認可オブジェクトからフォローするように常に RPT を取得できます (上記で説明した技術のいずれかによって初期化されていることを前提とします)。
const rpt = authorization.rpt;