9.2. 要求情報ポイント
Claim Information Point (CIP) は、ポリシーへのアクセスコンテキストに関する詳細情報を提供するために、要求を解決し、これらの要求を Red Hat build of Keycloak サーバーにプッシュします。policy-enforcer の設定オプションとして定義して、以下のような異なるソースから要求を解決できます。
- HTTP リクエスト (パラメーター、ヘッダー、ボディーなど)
- 外部 HTTP サービス
- 設定で定義された静的値
- Claim Information Provider SPI を実装するその他のソース
Red Hat build of Keycloak サーバーに要求をプッシュする場合、ポリシーは、ユーザーが誰であるかだけでなく、指定されたトランザクションの who、what、why、when、where、which に基づき、コンテキストとコンテンツを考慮して決定できます。コンテキストベースの認可や、粒度の細かい認可の決定をサポートするためにランタイム情報を使用する方法のみです。
9.2.1. HTTP リクエストからの情報の取得
HTTP 要求から要求を抽出する方法を示す例を以下に示します。
keycloak.json
{ "paths": [ { "path": "/protected/resource", "claim-information-point": { "claims": { "claim-from-request-parameter": "{request.parameter['a']}", "claim-from-header": "{request.header['b']}", "claim-from-cookie": "{request.cookie['c']}", "claim-from-remoteAddr": "{request.remoteAddr}", "claim-from-method": "{request.method}", "claim-from-uri": "{request.uri}", "claim-from-relativePath": "{request.relativePath}", "claim-from-secure": "{request.secure}", "claim-from-json-body-object": "{request.body['/a/b/c']}", "claim-from-json-body-array": "{request.body['/d/1']}", "claim-from-body": "{request.body}", "claim-from-static-value": "static value", "claim-from-multiple-static-value": ["static", "value"], "param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']}" } } } ] }
{
"paths": [
{
"path": "/protected/resource",
"claim-information-point": {
"claims": {
"claim-from-request-parameter": "{request.parameter['a']}",
"claim-from-header": "{request.header['b']}",
"claim-from-cookie": "{request.cookie['c']}",
"claim-from-remoteAddr": "{request.remoteAddr}",
"claim-from-method": "{request.method}",
"claim-from-uri": "{request.uri}",
"claim-from-relativePath": "{request.relativePath}",
"claim-from-secure": "{request.secure}",
"claim-from-json-body-object": "{request.body['/a/b/c']}",
"claim-from-json-body-array": "{request.body['/d/1']}",
"claim-from-body": "{request.body}",
"claim-from-static-value": "static value",
"claim-from-multiple-static-value": ["static", "value"],
"param-replace-multiple-placeholder": "Test {keycloak.access_token['/custom_claim/0']} and {request.parameter['a']}"
}
}
}
]
}
9.2.2. 外部 HTTP サービスからの情報の取得
以下は、外部 HTTP サービスから要求を抽出する方法を示しています。
keycloak.json
{ "paths": [ { "path": "/protected/resource", "claim-information-point": { "http": { "claims": { "claim-a": "/a", "claim-d": "/d", "claim-d0": "/d/0", "claim-d-all": [ "/d/0", "/d/1" ] }, "url": "http://mycompany/claim-provider", "method": "POST", "headers": { "Content-Type": "application/x-www-form-urlencoded", "header-b": [ "header-b-value1", "header-b-value2" ], "Authorization": "Bearer {keycloak.access_token}" }, "parameters": { "param-a": [ "param-a-value1", "param-a-value2" ], "param-subject": "{keycloak.access_token['/sub']}", "param-user-name": "{keycloak.access_token['/preferred_username']}", "param-other-claims": "{keycloak.access_token['/custom_claim']}" } } } } ] }
{
"paths": [
{
"path": "/protected/resource",
"claim-information-point": {
"http": {
"claims": {
"claim-a": "/a",
"claim-d": "/d",
"claim-d0": "/d/0",
"claim-d-all": [
"/d/0",
"/d/1"
]
},
"url": "http://mycompany/claim-provider",
"method": "POST",
"headers": {
"Content-Type": "application/x-www-form-urlencoded",
"header-b": [
"header-b-value1",
"header-b-value2"
],
"Authorization": "Bearer {keycloak.access_token}"
},
"parameters": {
"param-a": [
"param-a-value1",
"param-a-value2"
],
"param-subject": "{keycloak.access_token['/sub']}",
"param-user-name": "{keycloak.access_token['/preferred_username']}",
"param-other-claims": "{keycloak.access_token['/custom_claim']}"
}
}
}
}
]
}
9.2.3. 静的要求
keycloak.json
{ "paths": [ { "path": "/protected/resource", "claim-information-point": { "claims": { "claim-from-static-value": "static value", "claim-from-multiple-static-value": ["static", "value"] } } } ] }
{
"paths": [
{
"path": "/protected/resource",
"claim-information-point": {
"claims": {
"claim-from-static-value": "static value",
"claim-from-multiple-static-value": ["static", "value"]
}
}
}
]
}
9.2.4. クレーム情報プロバイダー SPI
Claim Information Provider SPI は、組み込みプロバイダーが要件に対応するために十分ではない場合に開発者が異なる要求情報ポイントをサポートするために使用できます。
たとえば、新しい CIP プロバイダーを実装するには、org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory
および ClaimInformationPointProvider
and also provide the file META-INF/services/org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory
をアプリケーションのクラスパスに指定する必要があります。
org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory
の例:
public class MyClaimInformationPointProviderFactory implements ClaimInformationPointProviderFactory<MyClaimInformationPointProvider> { @Override public String getName() { return "my-claims"; } @Override public void init(PolicyEnforcer policyEnforcer) { } @Override public MyClaimInformationPointProvider create(Map<String, Object> config) { return new MyClaimInformationPointProvider(config); } }
public class MyClaimInformationPointProviderFactory implements ClaimInformationPointProviderFactory<MyClaimInformationPointProvider> {
@Override
public String getName() {
return "my-claims";
}
@Override
public void init(PolicyEnforcer policyEnforcer) {
}
@Override
public MyClaimInformationPointProvider create(Map<String, Object> config) {
return new MyClaimInformationPointProvider(config);
}
}
すべての CIP プロバイダーは、MyClaimInformationPointProviderFactory.getName
メソッドで上記で定義されている名前に関連付ける必要があります。この名前は、policy-enforcer
設定の claim-information-point
セクションから実装に設定をマップするために使用されます。
リクエストの処理時に、ポリシーエンフォーサーは MyClaimInformationPointProviderFactory.create メソッドを呼び出して MyClaimInformationPointProvider のインスタンスを取得します。呼び出されると、この特定の CIP プロバイダーに定義されたすべての設定がマップとして渡されます (claim-information-point により)。
ClaimInformationPointProvider
の例:
public class MyClaimInformationPointProvider implements ClaimInformationPointProvider { private final Map<String, Object> config; public MyClaimInformationPointProvider(Map<String, Object> config) { this.config = config; } @Override public Map<String, List<String>> resolve(HttpFacade httpFacade) { Map<String, List<String>> claims = new HashMap<>(); // put whatever claim you want into the map return claims; } }
public class MyClaimInformationPointProvider implements ClaimInformationPointProvider {
private final Map<String, Object> config;
public MyClaimInformationPointProvider(Map<String, Object> config) {
this.config = config;
}
@Override
public Map<String, List<String>> resolve(HttpFacade httpFacade) {
Map<String, List<String>> claims = new HashMap<>();
// put whatever claim you want into the map
return claims;
}
}