9.2. 클레임 정보 포인트
클레임 정보 포인트(CIP)는 정책에 대한 액세스 컨텍스트에 대한 자세한 정보를 제공하기 위해 클레임을 해결하고 이러한 클레임을 Red Hat Single Sign-On 서버로 푸시해야 합니다. 다음과 같은 다양한 소스의 클레임을 해결하기 위해 policy-enforcer에 대한 구성 옵션으로 정의할 수 있습니다.
- HTTP 요청(parameters, headers, body 등)
- 외부 HTTP 서비스
- 구성에 정의된 정적 값
- 클레임 정보 공급자 SPI를 구현한 기타 소스
Red Hat Single Sign-On 서버에 클레임을 푸시할 때 정책은 사용자가 누구인지뿐만 아니라 주어진 트랜잭션에 대해 누가, 무엇을, 언제, 어디에서, 어떤지, 어떤지, 언제, 어디서, 어떤지, 어떤지, 컨텍스트 및 콘텐츠를 고려하여 기본 결정을 내릴 수 있습니다. 컨텍스트 기반 권한 부여와 런타임 정보를 사용하여 세분화된 권한 결정을 지원하는 방법에 관한 것입니다.
9.2.1. HTTP 요청에서 정보 가져오기
다음은 HTTP 요청에서 클레임을 추출하는 방법을 보여주는 몇 가지 예입니다.
keycloak.json
"policy-enforcer": { "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']} " } } } ] }
"policy-enforcer": {
"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
"policy-enforcer": { "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']}" } } } } ] }
"policy-enforcer": {
"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
"policy-enforcer": { "paths": [ { "path": "/protected/resource", "claim-information-point": { "claims": { "claim-from-static-value": "static value", "claim-from-multiple-static-value": ["static", "value"], } } } ] }
"policy-enforcer": {
"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.ClaimanchorProviderFactory.Claim>-<ProviderFactory
및 Claim>
파일을 제공해야 합니다.
-<Provider
Provider 파일을 구현해야 하며, 애플리케이션 클래스 경로에 META-INF/services/org.keycloak.adapters.ClaimanchorProviderFactory
org.keycloak.adapters.authorization.Claim#177ProviderFactory
의 예:
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 공급자는 위에서 정의한 MyClaimanchorProviderFactory.getName
메서드와 이름이 연결되어 있어야 합니다. name은 policy-enforcer
구성의 claim-point
섹션의 구성을 구현에 매핑하는 데 사용됩니다.
요청을 처리할 때 정책 적용자는 MyClaimanchorProviderFactory.create 메서드를 호출하여 MyClaim#177Provider의 인스턴스를 가져옵니다. 이 특정 CIP 공급자에 대해 정의된 모든 구성이 맵으로 전달됩니다(Claim-point를 통해).
Claim#177Provider의
예:
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;
}
}