keycloak-aplcache
Changes
adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java 11(+5 -6)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/MyCustomCIPFactory.java 63(+63 -0)
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java 31(+30 -1)
Details
diff --git a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
index 943f517..138e143 100644
--- a/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
+++ b/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/authorization/AbstractPolicyEnforcer.java
@@ -349,24 +349,23 @@ public abstract class AbstractPolicyEnforcer {
}
protected Map<String, List<String>> resolveClaims(PathConfig pathConfig, OIDCHttpFacade httpFacade) {
- Map<String, List<String>> claims = getClaims(getEnforcerConfig().getClaimInformationPointConfig(), httpFacade);
+ Map<String, List<String>> claims = new HashMap<>();
- claims.putAll(getClaims(pathConfig.getClaimInformationPointConfig(), httpFacade));
+ resolveClaims(claims, getEnforcerConfig().getClaimInformationPointConfig(), httpFacade);
+ resolveClaims(claims, pathConfig.getClaimInformationPointConfig(), httpFacade);
return claims;
}
- private Map<String, List<String>> getClaims(Map<String, Map<String, Object>>claimInformationPointConfig, HttpFacade httpFacade) {
+ private void resolveClaims(Map<String, List<String>> claims, Map<String, Map<String, Object>> claimInformationPointConfig, HttpFacade httpFacade) {
if (claimInformationPointConfig != null) {
for (Entry<String, Map<String, Object>> claimDef : claimInformationPointConfig.entrySet()) {
ClaimInformationPointProviderFactory factory = getPolicyEnforcer().getClaimInformationPointProviderFactories().get(claimDef.getKey());
if (factory != null) {
- return factory.create(claimDef.getValue()).resolve(httpFacade);
+ claims.putAll(factory.create(claimDef.getValue()).resolve(httpFacade));
}
}
}
-
- return new HashMap<>();
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/MyCustomCIPFactory.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/MyCustomCIPFactory.java
new file mode 100644
index 0000000..163bee0
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/MyCustomCIPFactory.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.admin.client.authorization;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.adapters.authorization.ClaimInformationPointProvider;
+import org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory;
+import org.keycloak.adapters.authorization.PolicyEnforcer;
+import org.keycloak.adapters.spi.HttpFacade;
+
+public class MyCustomCIPFactory implements ClaimInformationPointProviderFactory<MyCustomCIP> {
+
+ @Override
+ public String getName() {
+ return "my-custom-cip";
+ }
+
+ @Override
+ public void init(PolicyEnforcer policyEnforcer) {
+
+ }
+
+ @Override
+ public MyCustomCIP create(Map<String, Object> config) {
+ return new MyCustomCIP(config);
+ }
+}
+
+class MyCustomCIP implements ClaimInformationPointProvider {
+
+ private final Map<String, Object> config;
+
+ MyCustomCIP(Map<String, Object> config) {
+ this.config = config;
+ }
+
+ @Override
+ public Map<String, List<String>> resolve(HttpFacade httpFacade) {
+ Map<String, List<String>> claims = new HashMap<>();
+
+ claims.put("resolved-claim", Arrays.asList(config.get("claim-value").toString()));
+
+ return claims;
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java
index 160113d..a38db00 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/client/authorization/PolicyEnforcerTest.java
@@ -34,6 +34,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -68,6 +69,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.Permission;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
@@ -175,13 +177,40 @@ public class PolicyEnforcerTest extends AbstractKeycloakTest {
@Override
public String apply(String s) {
Assert.assertTrue(resolved.compareAndSet(false, true));
- return "claim-value";
+ return "value-" + s;
}
});
AuthorizationContext context = policyEnforcer.enforce(httpFacade);
+ Permission permission = context.getPermissions().get(0);
+ Map<String, Set<String>> claims = permission.getClaims();
assertTrue(context.isGranted());
+ assertEquals("value-claim-a", claims.get("claim-a").iterator().next());
+ assertEquals("claim-b", claims.get("claim-b").iterator().next());
+ }
+
+ @Test
+ public void testCustomClaimProvider() {
+ KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only-with-cip.json"));
+ PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer();
+
+ oauth.realm(REALM_NAME);
+ oauth.clientId("public-client-test");
+ oauth.doLogin("marta", "password");
+
+ String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
+ OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null);
+ String token = response.getAccessToken();
+
+ OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea", token);
+
+ AuthorizationContext context = policyEnforcer.enforce(httpFacade);
+ Permission permission = context.getPermissions().get(0);
+ Map<String, Set<String>> claims = permission.getClaims();
+
+ assertTrue(context.isGranted());
+ assertEquals("test", claims.get("resolved-claim").iterator().next());
}
@Test
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json
index 1b78f5f..8ca0253 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/authorization-test/enforcer-bearer-only-with-cip.json
@@ -19,6 +19,9 @@
"claim-information-point": {
"claims": {
"claim-a": "{request.parameter['claim-a']}"
+ },
+ "my-custom-cip": {
+ "claim-value": "test"
}
}
}
diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory
new file mode 100644
index 0000000..fa1de4b
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/services/org.keycloak.adapters.authorization.ClaimInformationPointProviderFactory
@@ -0,0 +1,18 @@
+#
+# * Copyright 2018 Red Hat, Inc. and/or its affiliates
+# * and other contributors as indicated by the @author tags.
+# *
+# * Licensed under the Apache License, Version 2.0 (the "License");
+# * you may not use this file except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# * http://www.apache.org/licenses/LICENSE-2.0
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+#
+
+org.keycloak.testsuite.admin.client.authorization.MyCustomCIPFactory
\ No newline at end of file