8.4. 保護 API
この保護 API は、以下を提供する UMA 準拠のエンドポイントセットを提供します。
リソースの管理
このエンドポイントでは、リソースサーバーはリソースをリモートで管理し、ポリシーエンフォーサー が保護する必要のあるリソースについてサーバーをクエリーできるようにします。
パーミッションの管理
UMA プロトコルでは、リソースサーバーがこのエンドポイントにアクセスしてパーミッションチケットを作成します。Red Hat build of Keycloak は、パーミッションおよびクエリーパーミッションの状態を管理するエンドポイントも提供します。
Policy API
Red Hat build of Keycloak は UMA Protection API を利用して、リソースサーバーがユーザーのパーミッションを管理できるようにします。Red Hat build of Keycloak は、Resource API や Permission API の他に、ユーザーの代わりにリソースサーバーがパーミッションを設定できる Policy API を提供します。
この API の重要な要件は、保護 API トークン (PAT) と呼ばれる特別な OAuth2 アクセストークンを使用して、リソースサーバー のみ がエンドポイントにアクセスできることです。UMA では、PAT はスコープの uma_protection を持つトークンです。
8.4.1. PAT および取得法
保護 API トークン (PAT) は、スコープが uma_protection として定義されている特別な OAuth2 アクセストークンです。リソースサーバーを作成すると、Red Hat build of Keycloak は対応するクライアントアプリケーションのロール uma_protection を自動的に作成し、それをクライアントのサービスアカウントに関連付けます。
uma_protection ロールで付与されたサービスアカウント
リソースサーバーは、他の OAuth2 アクセストークンと同様に、Red Hat build of Keycloak から 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://${host}:${port}/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" }
Red Hat build of Keycloak は、さまざまな方法でクライアントアプリケーションを認証できます。分かりやすくするために、client_credentials 付与タイプを使用します。これには client_id と client_secret が必要です。サポート対象の認証方法を選択できます。
8.4.2. リソースの管理
リソースサーバーは、UMA 準拠のエンドポイントを使用してリソースをリモートで管理できます。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set
このエンドポイントは、以下のように要約された操作を提供します (分かりやすくするために終了となるパスを省略します)。
- リソースセットの説明の作成: POST /resource_set
- リソースセットの説明の読み取り: GET /resource_set/{_id}
- リソースセットの説明の更新: PUT /resource_set/{_id}
- リソースセットの説明の削除: DELETE /resource_set/{_id}
- リソースセットの説明のリスト表示: GET /resource_set
各操作のコントラクトに関する詳細は、UMA リソース登録 API を参照してください。
8.4.2.1. リソースの作成
リソースを作成するには、以下のように HTTP POST リクエストを送信する必要があります。
curl -v -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '{ "name":"Tweedl Social Service", "type":"http://www.example.com/rsrcs/socialstream/140-compatible", "icon_uri":"http://www.example.com/icons/sharesocial.png", "resource_scopes":[ "read-public", "post-updates", "read-private", "http://www.example.com/scopes/all" ] }'
デフォルトでは、リソースの所有者はリソースサーバーです。特定のユーザーなど、異なる所有者を定義する場合は、以下のようにリクエストを送信できます。
curl -v -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '{ "name":"Alice Resource", "owner": "alice" }'
プロパティーの owner
はユーザーのユーザー名または識別子で設定できます。
8.4.2.2. ユーザー管理リソースの作成
デフォルトでは、保護 API で作成されたリソースは、アカウントコンソール を通じてリソースの所有者によって管理できません。
リソースを作成し、リソースの所有者がこれらのリソースを管理できるようにするには、ownerManagedAccess
プロパティーを以下のように設定する必要があります。
curl -v -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '{ "name":"Alice Resource", "owner": "alice", "ownerManagedAccess": true }'
8.4.2.3. リソースの更新
既存のリソースを更新するには、以下のように HTTP PUT 要求を送信します。
curl -v -X PUT \ http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id} \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '{ "_id": "Alice Resource", "name":"Alice Resource", "resource_scopes": [ "read" ] }'
8.4.2.4. リソースの定義
既存のリソースを削除するには、以下のように HTTP DELETE リクエストを送信します。
curl -v -X DELETE \ http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id} \ -H 'Authorization: Bearer '$pat
8.4.2.5. リソースのクエリー
id
別にリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set/{resource_id}
name
を指定してリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource
デフォルトでは、name
フィルターは指定されたパターンのすべてのリソースと一致します。完全に一致するリソースのみを返すようにクエリーを制限するには、次を使用します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?name=Alice Resource&exactName=true
uri
を指定してリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?uri=/api/alice
owner
を指定してリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?owner=alice
タイプ
のあるリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?type=albums
scope
を指定してリソースをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm_name}/authz/protection/resource_set?scope=read
サーバーに対してパーミッションをクエリーする場合は、first
パラメーターおよび max
パラメーターを使用すると結果が制限されます。
8.4.3. パーミッション要求の管理
UMA プロトコルを使用するリソースサーバーは、特定のエンドポイントを使用してパーミッション要求を管理できます。このエンドポイントは、パーミッション要求を登録し、パーミッションチケットを取得するための UMA 準拠のフローを提供します。
http://${host}:${port}/realms/${realm_name}/authz/protection/permission
パーミッションチケット は、パーミッション要求を表す特別なセキュリティートークンタイプです。UMA 仕様では、パーミッションチケットは以下のようになります。
認可サーバーからリソースサーバーへ、リソースサーバーからクライアントへ、最終的にはクライアントから認可サーバーに返信される相関ハンドル。これにより、認可サーバーは正しいポリシーを評価し、認可データのリクエストに適用されます。
ほとんどの場合、このエンドポイントを直接処理する必要はありません。Red Hat build of Keycloak は、リソースサーバーに対して UMA を有効にする ポリシーエンフォーサー を提供します。これにより、認可サーバーからパーミッションチケットを取得し、そのチケットをクライアントアプリケーションに返し、最終的な要求者トークン (RPT) に基づいき認可について決定できます。
Red Hat build of Keycloak からパーミッションチケットを取得するプロセスは、通常のクライアントアプリケーションではなくリソースサーバーによって実行されます。その場合、クライアントが適切なアクセス権を持たないまま保護されたリソースにアクセスしようとすると、パーミッションチケットが取得されます。パーミッションチケットの発行は、リソースサーバーを許可する UMA を使用する場合の重要な要素です。
- リソースサーバーが保護するリソースに関連付けられたデータをクライアントから抽象化します。
- Red Hat build of Keycloak 認可要求に登録します。これは後のワークフローで、リソース所有者の同意に基づきアクセス権を付与するために使用できます。
- 認可サーバーからリソースサーバーを分離し、異なる認可サーバーを使用してリソースを保護します。
クライアントについては、パーミッションチケットには重要な要素があり、その重要な側面は重要なものであり、以下の重要なものが重要となります。
- クライアントは、保護リソースと認可データがどのように関連付けられているのかを把握する必要はありません。パーミッションチケットはクライアントに完全に不透明です。
- クライアントは、異なるリソースサーバーのリソースにアクセスでき、異なる認可サーバーによって保護されます。
これは、UMA の他の側面がパーミッションチケットに基づいて設計されているという利点があります。これは、リソースへのプライバシーやユーザー管理に関しては、パーミッションチケットに基づいて強く使用されます。
8.4.3.1. パーミッションチケットの作成
パーミッションチケットを作成するには、以下のように HTTP POST リクエストを送信します。
curl -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/permission \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '[ { "resource_id": "{resource_id}", "resource_scopes": [ "view" ] } ]'
チケットの作成時に、任意の要求をプッシュし、これらの要求をチケットに関連付けることもできます。
curl -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/permission \ -H 'Authorization: Bearer '$pat \ -H 'Content-Type: application/json' \ -d '[ { "resource_id": "{resource_id}", "resource_scopes": [ "view" ], "claims": { "organization": ["acme"] } } ]'
これらの要求は、パーミッションチケットに関連付けられたリソースおよびスコープのパーミッションの評価時にポリシーで利用できます。
8.4.3.2. UMA 以外のエンドポイント
8.4.3.2.1. パーミッションチケットの作成
リソースの所有者が以下のように HTTP POST 要求を送信するため、ID {user_id} の特定のリソースに ID {user_id} の特定のリソースのパーミッションを付与するには、以下を実行します。
curl -X POST \ http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket \ -H 'Authorization: Bearer '$access_token \ -H 'Content-Type: application/json' \ -d '{ "resource": "{resource_id}", "requester": "{user_id}", "granted": true, "scopeName": "view" }'
8.4.3.2.2. パーミッションチケットの取得
curl http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket \ -H 'Authorization: Bearer '$access_token
これらのクエリーパラメーターのいずれかを使用することができます。
-
scopeId
-
resourceId
-
owner
-
requester
-
granted
-
returnNames
-
first
-
max
8.4.3.2.3. パーミッションチケットの更新
curl -X PUT \ http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket \ -H 'Authorization: Bearer '$access_token \ -H 'Content-Type: application/json' \ -d '{ "id": "{ticket_id}" "resource": "{resource_id}", "requester": "{user_id}", "granted": false, "scopeName": "view" }'
8.4.3.2.4. パーミッションチケットの削除
curl -X DELETE http://${host}:${port}/realms/${realm_name}/authz/protection/permission/ticket/{ticket_id} \ -H 'Authorization: Bearer '$access_token
8.4.4. Policy API を使用したリソースパーミッションの管理
Red Hat build of Keycloak は UMA Protection API を利用して、リソースサーバーがユーザーのパーミッションを管理できるようにします。Red Hat build of Keycloak は、Resource API や Permission API の他に、ユーザーの代わりにリソースサーバーがパーミッションを設定できる Policy API を提供します。
Policy API は以下で使用できます。
http://${host}:${port}/realms/${realm_name}/authz/protection/uma-policy/{resource_id}
この API はベアラートークンで保護されています。ベアラートークンは、ユーザーに代わって権限を管理するためにユーザーがリソースサーバーに付与した同意を表す必要があります。ベアラートークンは、以下を使用してトークンエンドポイントから取得した通常のアクセストークンになります。
- リソースオーナーパスワードの認証情報の付与タイプ
- オーディエンスがリソースサーバーである場合に、一部のクライアント (パブリッククライアント) に付与されるアクセストークンを交換するトークン Exchange
8.4.4.1. リソースへのパーミッションの関連付け
パーミッションを特定リソースに関連付けるには、以下のように HTTP POST 要求を送信する必要があります。
curl -X POST \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{resource_id} \ -H 'Authorization: Bearer '$access_token \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "name": "Any people manager", "description": "Allow access to any people manager", "scopes": ["read"], "roles": ["people-manager"] }'
上記の例では、resource_id
で表されるリソースに新しいパーミッションを作成し、関連付けています。ここでは、people-manager
ロールを持つすべてのユーザーに 読み取り
スコープが付与されます。
グループの使用など、他のアクセス制御メカニズムを使用してポリシーを作成することもできます。
curl -X POST \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{resource_id} \ -H 'Authorization: Bearer '$access_token \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "name": "Any people manager", "description": "Allow access to any people manager", "scopes": ["read"], "groups": ["/Managers/People Managers"] }'
または特定のクライアント:
curl -X POST \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{resource_id} \ -H 'Authorization: Bearer '$access_token \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "name": "Any people manager", "description": "Allow access to any people manager", "scopes": ["read"], "clients": ["my-client"] }'
または、JavaScript を使用してカスタムポリシーを使用する場合でも、以下を実行します。
アップロードスクリプトは 非推奨 となり、今後のリリースで削除されます。この機能はデフォルトでは無効になっています。
-Dkeycloak.profile.feature.upload_scripts=enabled
でサーバーの起動を有効にするには、次のコマンドを実行します。詳細は、機能の有効化と無効化 ガイドを参照してください。
curl -X POST \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{resource_id} \ -H 'Authorization: Bearer '$access_token \ -H 'Cache-Control: no-cache' \ -H 'Content-Type: application/json' \ -d '{ "name": "Any people manager", "description": "Allow access to any people manager", "scopes": ["read"], "condition": "my-deployed-script.js" }'
これらのアクセス制御メカニズムの組み合わせを設定することもできます。
既存のパーミッションを更新するには、以下のように HTTP PUT 要求を送信します。
curl -X PUT \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{permission_id} \ -H 'Authorization: Bearer '$access_token \ -H 'Content-Type: application/json' \ -d '{ "id": "21eb3fed-02d7-4b5a-9102-29f3f09b6de2", "name": "Any people manager", "description": "Allow access to any people manager", "type": "uma", "scopes": [ "album:view" ], "logic": "POSITIVE", "decisionStrategy": "UNANIMOUS", "owner": "7e22131a-aa57-4f5f-b1db-6e82babcd322", "roles": [ "user" ] }'
8.4.4.2. パーミッションの削除
リソースに関連付けられたパーミッションを削除するには、以下のように HTTP DELETE リクエストを送信します。
curl -X DELETE \ http://localhost:8180/realms/photoz/authz/protection/uma-policy/{permission_id} \ -H 'Authorization: Bearer '$access_token
8.4.4.3. パーミッションのクエリー
リソースに関連付けられたパーミッションをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?resource={resource_id}
その名前のパーミッションをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?name=Any people manager
特定のスコープに関連付けられたパーミッションをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy?scope=read
すべてのパーミッションをクエリーするには、以下のように HTTP GET リクエストを送信します。
http://${host}:${port}/realms/${realm}/authz/protection/uma-policy
サーバーに対してパーミッションをクエリーする場合は、first
パラメーターおよび max
パラメーターを使用すると結果が制限されます。