Only enable JS policies if the scripts feature is enabled

Closes #44132

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2026-01-28 08:28:32 -03:00 committed by GitHub
parent d73b1f926f
commit b9243a7270
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 719 additions and 351 deletions

View file

@ -1,14 +1,18 @@
package org.keycloak.authorization.policy.provider.js;
import org.keycloak.Config;
import org.keycloak.Config.Scope;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.common.Profile;
import org.keycloak.common.Profile.Feature;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.RealmModel;
import org.keycloak.models.ScriptModel;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.scripting.EvaluatableScriptAdapter;
@ -17,7 +21,7 @@ import org.keycloak.scripting.ScriptingProvider;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
public class JSPolicyProviderFactory implements PolicyProviderFactory<JSPolicyRepresentation> {
public class JSPolicyProviderFactory implements PolicyProviderFactory<JSPolicyRepresentation>, EnvironmentDependentProviderFactory {
private final JSPolicyProvider provider = new JSPolicyProvider(this::getEvaluatableScript);
private ScriptCache scriptCache;
@ -129,4 +133,9 @@ public class JSPolicyProviderFactory implements PolicyProviderFactory<JSPolicyRe
throw new RuntimeException("Script upload is disabled");
}
}
@Override
public boolean isSupported(Scope config) {
return Profile.isFeatureEnabled(Feature.SCRIPTS);
}
}

View file

@ -4,7 +4,15 @@
Breaking changes are identified as those that might require changes for existing users to their configurations or applications.
In minor or patch releases, {project_name} will only introduce breaking changes to fix bugs.
=== <TODO>
=== JavaScript-based policies can only be deployed now if the `scripts` feature is enabled
In this version, JavaScript-based policies can only be deployed if the `scripts` feature is enabled.
Until now, JavaScript-based policies were always enabled regardless of the `scripts` feature flag. However, this behavior
was causing confusion as users expected that disabling the `scripts` feature would also disable JavaScript-based policies.
It was also not aligned with how other script-based features work in {project_name}.
If you have existing JavaScript-based policies, make sure to enable the `scripts` feature when starting {project_name}.
// ------------------------ Notable changes ------------------------ //
== Notable changes

View file

@ -346,7 +346,7 @@ public class AbstractPartialImportTest {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder builder) {
return builder.dependency("org.keycloak.tests", "keycloak-tests-custom-scripts");
return builder.dependency("org.keycloak.tests", "keycloak-tests-custom-providers");
}
}
}

View file

@ -26,7 +26,7 @@
{
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "script-scripts/default-policy.js",
"type": "always-grant",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE"
},

View file

@ -0,0 +1,76 @@
package org.keycloak.testsuite.authorization.policy;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class GrantPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Always Grant";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "always-grant";
}
@Override
public void evaluate(Evaluation evaluation) {
evaluation.grant();
}
}

View file

@ -0,0 +1 @@
org.keycloak.testsuite.authorization.policy.GrantPolicyProvider

View file

@ -27,21 +27,6 @@
"fileName": "scripts/default-policy.js",
"description": "A policy that grants access only for users within this realm"
},
{
"name": "Only Owner Policy",
"fileName": "scripts/only-owner-policy.js",
"description": "Defines that only the resource owner is allowed to do something"
},
{
"name": "Only From a Specific Client Address",
"fileName": "scripts/only-from-specific-address-policy.js",
"description": "Defines that only clients from a specific address can do something"
},
{
"name": "Only From @keycloak.org or Admin",
"fileName": "scripts/only-from-specific-domain-or-admin-policy.js",
"description": "Defines that only users from @keycloak.org"
},
{
"name": "Claim A Policy",
"fileName": "scripts/add-claim-a-policy.js"
@ -54,10 +39,6 @@
"name": "Policy Claim C",
"fileName": "scripts/add-claim-c-policy.js"
},
{
"name": "Deny Policy",
"fileName": "scripts/always-deny-policy.js"
},
{
"name": "Deny Policy With Claim",
"fileName": "scripts/always-deny-with-claim-policy.js"
@ -65,9 +46,6 @@
{
"fileName": "scripts/withdraw-limit-policy.js"
},
{
"fileName": "scripts/resource-visibility-attribute-policy.js"
},
{
"fileName": "scripts/allow-group-name-in-role-policy.js"
},
@ -130,15 +108,6 @@
},
{
"fileName": "scripts/allow-group-in-role-policy.js"
},
{
"fileName": "scripts/deny-from-specific-address-policy.js"
},
{
"fileName": "scripts/allow-value-from-request-claim.js"
},
{
"fileName": "scripts/enforce-withdraw-limit-policy.js"
}
]
}

View file

@ -1,7 +0,0 @@
var context = $evaluation.getContext();
var attributes = context.getAttributes();
var claim = attributes.getValue('request-claim');
if (claim && claim.asString(0) == 'expected-value') {
$evaluation.grant();
}

View file

@ -1,5 +0,0 @@
var contextAttributes = $evaluation.getContext().getAttributes();
if (contextAttributes.containsValue('kc.client.network.ip_address', '127.3.3.3') || contextAttributes.containsValue('kc.client.network.ip_address', '0:0:0:0:0:ffff:7f03:303')) {
$evaluation.grant();
}

View file

@ -1,7 +0,0 @@
var context = $evaluation.getContext();
var attributes = context.getAttributes();
var withdrawalAmount = attributes.getValue('withdrawal.amount');
if (withdrawalAmount && withdrawalAmount.asDouble(0) <= 100) {
$evaluation.grant();
}

View file

@ -1,5 +0,0 @@
var contextAttributes = $evaluation.getContext().getAttributes();
if (contextAttributes.containsValue('kc.client.network.ip_address', '127.0.0.1') || contextAttributes.containsValue('kc.client.network.ip_address', '0:0:0:0:0:0:0:1')) {
$evaluation.grant();
}

View file

@ -1,8 +0,0 @@
var context = $evaluation.getContext();
var identity = context.getIdentity();
var attributes = identity.getAttributes();
var email = attributes.getValue('email').asString(0);
if (identity.hasRealmRole('admin') || email.endsWith('@keycloak.org')) {
$evaluation.grant();
}

View file

@ -1,9 +0,0 @@
var permission = $evaluation.getPermission();
var identity = $evaluation.getContext().getIdentity();
var resource = permission.getResource();
if (resource) {
if (resource.getOwner().equals(identity.getId())) {
$evaluation.grant();
}
}

View file

@ -1,13 +0,0 @@
var createPermission = $evaluation.getPermission();
var resource = createPermission.getResource();
if (resource) {
var attributes = resource.getAttributes();
var visibility = attributes.get('visibility');
if (visibility && "private".equals(visibility.get(0))) {
$evaluation.deny();
} else {
$evaluation.grant();
}
}

View file

@ -0,0 +1,76 @@
package org.keycloak.testsuite.authorization;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class DenyPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Always Deny";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "always-deny";
}
@Override
public void evaluate(Evaluation evaluation) {
evaluation.deny();
}
}

View file

@ -0,0 +1,76 @@
package org.keycloak.testsuite.authorization;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class GrantPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Always Grant";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "always-grant";
}
@Override
public void evaluate(Evaluation evaluation) {
evaluation.grant();
}
}

View file

@ -0,0 +1,83 @@
package org.keycloak.testsuite.authorization;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.identity.Identity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class GrantResourceOwnerPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Allow Resource Owner";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "allow-resource-owner";
}
@Override
public void evaluate(Evaluation evaluation) {
Resource resource = evaluation.getPermission().getResource();
Identity identity = evaluation.getContext().getIdentity();
if (identity.getId().equals(resource.getOwner())) {
evaluation.grant();
}
}
}

View file

@ -0,0 +1,90 @@
package org.keycloak.testsuite.authorization;
import java.util.List;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.permission.ResourcePermission;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class ResourceVisibilityAttributePolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Check resource visibility";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "resource-visibility-attribute-policy";
}
@Override
public void evaluate(Evaluation evaluation) {
ResourcePermission permission = evaluation.getPermission();
Resource resource = permission.getResource();
if (isPublic(resource)) {
evaluation.grant();
}
}
private static boolean isPublic(Resource resource) {
List<String> values = resource.getAttributes().get("visibility");
return values == null || !values.contains("private");
}
}

View file

@ -0,0 +1,83 @@
package org.keycloak.testsuite.authorization;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.attribute.Attributes;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.evaluation.EvaluationContext;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class SpecificAddressPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Allow from specific address";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "only-from-specific-address-policy";
}
@Override
public void evaluate(Evaluation evaluation) {
EvaluationContext context = evaluation.getContext();
Attributes attributes = context.getAttributes();
if (attributes.containsValue("kc.client.network.ip_address", "127.0.0.1") || attributes.containsValue("kc.client.network.ip_address", "0:0:0:0:0:0:0:1")) {
evaluation.grant();
}
}
}

View file

@ -0,0 +1,82 @@
package org.keycloak.testsuite.authorization;
import org.keycloak.Config;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.identity.Identity;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.policy.evaluation.Evaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
public class SpecificDomainOrAdminPolicyProvider implements PolicyProviderFactory<PolicyRepresentation>, PolicyProvider {
@Override
public String getName() {
return "Allow from Specific Domain or Admin";
}
@Override
public String getGroup() {
return "Test Suite";
}
@Override
public PolicyProvider create(AuthorizationProvider authorization) {
return this;
}
@Override
public PolicyRepresentation toRepresentation(Policy policy, AuthorizationProvider authorization) {
return new PolicyRepresentation();
}
@Override
public Class getRepresentationType() {
return PolicyRepresentation.class;
}
@Override
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
return null;
}
@Override
public PolicyProvider create(KeycloakSession session) {
return null;
}
@Override
public void init(Config.Scope config) {
}
@Override
public void postInit(KeycloakSessionFactory factory) {
}
@Override
public void close() {
}
@Override
public String getId() {
return "only-from-specific-domain-or-admin-policy";
}
@Override
public void evaluate(Evaluation evaluation) {
Identity identity = evaluation.getContext().getIdentity();
String email = identity.getAttributes().getValue("email").asString(0);
if (identity.hasRealmRole("admin") || email.endsWith("@keycloak.org")) {
evaluation.grant();
}
}
}

View file

@ -15,4 +15,10 @@
# limitations under the License.
#
#
org.keycloak.testsuite.authorization.TestPolicyProviderFactory
org.keycloak.testsuite.authorization.TestPolicyProviderFactory
org.keycloak.testsuite.authorization.GrantPolicyProvider
org.keycloak.testsuite.authorization.DenyPolicyProvider
org.keycloak.testsuite.authorization.GrantResourceOwnerPolicyProvider
org.keycloak.testsuite.authorization.ResourceVisibilityAttributePolicyProvider
org.keycloak.testsuite.authorization.SpecificDomainOrAdminPolicyProvider
org.keycloak.testsuite.authorization.SpecificAddressPolicyProvider

View file

@ -1,8 +1,11 @@
package org.keycloak.testsuite.authz;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.ProfileAssume;
@ -30,4 +33,31 @@ public abstract class AbstractAuthzTest extends AbstractKeycloakTest {
}
return accessToken;
}
protected PolicyRepresentation createAlwaysGrantPolicy(AuthorizationResource authorization) {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("always-grant");
authorization.policies().create(policy).close();
return policy;
}
protected PolicyRepresentation createAlwaysDenyPolicy(AuthorizationResource authorization) {
PolicyRepresentation policy = new PolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("always-deny");
authorization.policies().create(policy).close();
return policy;
}
protected PolicyRepresentation createOnlyOwnerPolicy(AuthorizationResource authorization) {
PolicyRepresentation onlyOwnerPolicy = new PolicyRepresentation();
onlyOwnerPolicy.setName(KeycloakModelUtils.generateId());
onlyOwnerPolicy.setType("allow-resource-owner");
authorization.policies().create(onlyOwnerPolicy).close();
return onlyOwnerPolicy;
}
}

View file

@ -33,9 +33,9 @@ import org.keycloak.representations.JsonWebToken;
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.PermissionRequest;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.testsuite.Assert;
@ -116,14 +116,7 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
Response response = authorization.resources().create(resource);
response.close();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Default Policy");
policy.setType("script-scripts/default-policy.js");
response = authorization.policies().js().create(policy);
response.close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName(resource.getName() + " Permission");
@ -204,7 +197,6 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
List<Permission> permissions = authzClient.authorization("marta", "password").getPermissions(request);
assertFalse(permissions.isEmpty());
assertTrue(permissions.get(0) instanceof Permission);
}
public void testResourceServerAsAudience(String clientId, String resourceServerClientId, String authzConfigFile) throws Exception {

View file

@ -35,8 +35,8 @@ import org.keycloak.representations.AccessToken.Authorization;
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.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
@ -61,6 +61,7 @@ import static org.junit.Assert.assertTrue;
public class AuthorizationTest extends AbstractAuthzTest {
private AuthzClient authzClient;
private PolicyRepresentation grantPolicy;
@Override
public void addTestRealms(List<RealmRepresentation> testRealms) {
@ -86,18 +87,7 @@ public class AuthorizationTest extends AbstractAuthzTest {
public void configureAuthorization() throws Exception {
ClientResource client = getClient();
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Grant Policy");
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
policy = new JSPolicyRepresentation();
policy.setName("Deny Policy");
policy.setType("script-scripts/always-deny-policy.js");
grantPolicy = createAlwaysGrantPolicy(authorization);
}
@After
@ -114,11 +104,11 @@ public class AuthorizationTest extends AbstractAuthzTest {
public void testResourceWithSameNameDifferentOwner() throws JWSInputException {
ResourceRepresentation koloResource = createResource("Resource A", "kolo", "Scope A", "Scope B");
createResourcePermission(koloResource, "Grant Policy");
createResourcePermission(koloResource, grantPolicy.getName());
ResourceRepresentation martaResource = createResource("Resource A", "marta", "Scope A", "Scope B");
createResourcePermission(martaResource, "Grant Policy");
createResourcePermission(martaResource, grantPolicy.getName());
assertNotEquals(koloResource.getId(), martaResource.getId());
@ -149,11 +139,11 @@ public class AuthorizationTest extends AbstractAuthzTest {
public void testResourceServerWithSameNameDifferentOwner() {
ResourceRepresentation koloResource = createResource("Resource A", "kolo", "Scope A", "Scope B");
createResourcePermission(koloResource, "Grant Policy");
createResourcePermission(koloResource, grantPolicy.getName());
ResourceRepresentation serverResource = createResource("Resource A", null, "Scope A", "Scope B");
createResourcePermission(serverResource, "Grant Policy");
createResourcePermission(serverResource, grantPolicy.getName());
AuthorizationRequest request = new AuthorizationRequest();

View file

@ -63,11 +63,11 @@ import org.keycloak.representations.idm.authorization.AuthorizationRequest;
import org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata;
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Permission;
import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.PermissionResponse;
import org.keycloak.representations.idm.authorization.PermissionTicketRepresentation;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
@ -90,7 +90,6 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.hamcrest.Matchers;
import org.jboss.arquillian.container.test.api.ContainerController;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -423,11 +422,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testResolveResourcesWithSameUri() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Resource A");
@ -524,14 +519,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlements() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Only Owner Policy");
policy.setType("script-scripts/only-owner-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createOnlyOwnerPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Marta Resource");
@ -663,13 +651,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsInvalidResource() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
@ -717,12 +699,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
@ -772,13 +749,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsForScope() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
Set<String> resourceIds = new HashSet<>();
ResourceRepresentation resource = new ResourceRepresentation();
@ -871,13 +842,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsForScopeWithDeny() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
authorization.scopes().create(new ScopeRepresentation("sensors:view")).close();
@ -911,13 +876,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsForResourceWithResourcePermission() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
@ -993,13 +952,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsForResourceWithScopePermission() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resourceWithoutType = new ResourceRepresentation();
@ -1084,20 +1037,8 @@ public class EntitlementAPITest extends AbstractAuthzTest {
resource = response.readEntity(ResourceRepresentation.class);
}
JSPolicyRepresentation grantPolicy = new JSPolicyRepresentation();
grantPolicy.setName(KeycloakModelUtils.generateId());
grantPolicy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(grantPolicy).close();
JSPolicyRepresentation denyPolicy = new JSPolicyRepresentation();
denyPolicy.setName(KeycloakModelUtils.generateId());
denyPolicy.setType("script-scripts/always-deny-policy.js");
authorization.policies().js().create(denyPolicy).close();
PolicyRepresentation grantPolicy = createAlwaysGrantPolicy(authorization);
PolicyRepresentation denyPolicy = createAlwaysDenyPolicy(authorization);
ResourcePermissionRepresentation resourcePermission = new ResourcePermissionRepresentation();
resourcePermission.setName(KeycloakModelUtils.generateId());
@ -1219,13 +1160,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testObtainAllEntitlementsForResourceType() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
for (int i = 0; i < 10; i++) {
ResourceRepresentation resource = new ResourceRepresentation();
@ -1452,9 +1387,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testOverridePermission() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy();
authorization.policies().js().create(onlyOwnerPolicy).close();
PolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy(authorization);
ResourceRepresentation typedResource = new ResourceRepresentation();
@ -1653,10 +1586,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testOverrideParentScopePermission() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy();
authorization.policies().js().create(onlyOwnerPolicy).close();
PolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy(authorization);
ResourceRepresentation typedResource = new ResourceRepresentation();
typedResource.setType("resource");
@ -1831,30 +1761,17 @@ public class EntitlementAPITest extends AbstractAuthzTest {
}
}
@NotNull
private JSPolicyRepresentation createOnlyOwnerPolicy() {
JSPolicyRepresentation onlyOwnerPolicy = new JSPolicyRepresentation();
onlyOwnerPolicy.setName(KeycloakModelUtils.generateId());
onlyOwnerPolicy.setType("script-scripts/only-owner-policy.js");
return onlyOwnerPolicy;
}
@Test
public void testPermissionsWithResourceAttributes() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation onlyPublicResourcesPolicy = new JSPolicyRepresentation();
PolicyRepresentation onlyPublicResourcesPolicy = new PolicyRepresentation();
onlyPublicResourcesPolicy.setName(KeycloakModelUtils.generateId());
onlyPublicResourcesPolicy.setType("script-scripts/resource-visibility-attribute-policy.js");
onlyPublicResourcesPolicy.setType("resource-visibility-attribute-policy");
authorization.policies().js().create(onlyPublicResourcesPolicy).close();
JSPolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy();
authorization.policies().js().create(onlyOwnerPolicy).close();
authorization.policies().create(onlyPublicResourcesPolicy).close();
PolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy(authorization);
ResourceRepresentation typedResource = new ResourceRepresentation();
@ -2010,14 +1927,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testOfflineRequestingPartyToken() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2078,14 +1988,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
client.getProtocolMappers().createMapper(customClaimMapper);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2152,14 +2055,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
client.getProtocolMappers().createMapper(customClaimMapper);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2252,14 +2148,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testUsingExpiredToken() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2308,14 +2197,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2356,14 +2238,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testDenyScopeNotManagedByScopePolicy() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName(KeycloakModelUtils.generateId());
@ -2410,24 +2285,17 @@ public class EntitlementAPITest extends AbstractAuthzTest {
@Test
public void testPermissionsAcrossResourceServers() throws Exception {
String rsAId;
try (Response response = getRealm().clients().create(ClientBuilder.create().clientId("rs-a").secret("secret").serviceAccount().authorizationServicesEnabled(true).build())) {
rsAId = ApiUtil.getCreatedId(response);
}
ClientRepresentation rsA = ClientBuilder.create().clientId("rs-a").secret("secret").serviceAccount().authorizationServicesEnabled(true).build();
getRealm().clients().create(rsA).close();
String rsBId;
try (Response response = getRealm().clients().create(ClientBuilder.create().clientId("rs-b").secret("secret").serviceAccount().authorizationServicesEnabled(true).build())) {
rsBId = ApiUtil.getCreatedId(response);
}
ClientResource rsB = getRealm().clients().get(rsBId);
rsB.authorization().resources().create(new ResourceRepresentation("Resource A"));
rsB.authorization().resources().create(new ResourceRepresentation("Resource A")).close();
JSPolicyRepresentation grantPolicy = new JSPolicyRepresentation();
grantPolicy.setName("Grant Policy");
grantPolicy.setType("script-scripts/default-policy.js");
rsB.authorization().policies().js().create(grantPolicy);
PolicyRepresentation grantPolicy = createAlwaysGrantPolicy(rsB.authorization());
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
@ -2435,7 +2303,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
permission.addResource("Resource A");
permission.addPolicy(grantPolicy.getName());
rsB.authorization().permissions().resource().create(permission);
rsB.authorization().permissions().resource().create(permission).close();
AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
Configuration config = authzClient.getConfiguration();
@ -2444,7 +2312,6 @@ public class EntitlementAPITest extends AbstractAuthzTest {
authzClient = AuthzClient.create(config);
AccessTokenResponse accessTokenResponse = authzClient.obtainAccessToken();
AccessToken accessToken = toAccessToken(accessTokenResponse.getToken());
config.setResource("rs-b");
@ -2464,14 +2331,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testClientToClientPermissionRequest() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("Sensors");
@ -2520,13 +2380,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
public void testPermissionOrder() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName("my_resource");
@ -2802,12 +2656,7 @@ public class EntitlementAPITest extends AbstractAuthzTest {
ClientResource client = getClient(getRealm(), clientId);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Default Policy");
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
PolicyRepresentation policy = createAlwaysGrantPolicy(authorization);
for (int i = 1; i <= 20; i++) {
ResourceRepresentation resource = new ResourceRepresentation("Resource " + i);

View file

@ -32,6 +32,7 @@ import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.authorization.client.util.HttpResponseException;
import org.keycloak.common.Profile.Feature;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AccessToken.Authorization;
@ -45,6 +46,7 @@ import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.RoleBuilder;
@ -65,6 +67,7 @@ import static org.junit.Assert.fail;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(Feature.SCRIPTS)
public class PermissionClaimTest extends AbstractAuthzTest {
private JSPolicyRepresentation claimAPolicy;

View file

@ -48,6 +48,7 @@ import org.keycloak.authorization.permission.evaluator.PermissionEvaluator;
import org.keycloak.authorization.policy.evaluation.DefaultEvaluation;
import org.keycloak.authorization.policy.provider.PolicyProvider;
import org.keycloak.authorization.store.StoreFactory;
import org.keycloak.common.Profile.Feature;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@ -62,15 +63,16 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.representations.idm.authorization.Permission;
import org.keycloak.representations.idm.authorization.PolicyEvaluationRequest;
import org.keycloak.representations.idm.authorization.PolicyEvaluationResponse;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.GroupBuilder;
import org.keycloak.testsuite.util.RealmBuilder;
@ -88,6 +90,7 @@ import static org.junit.Assert.assertNotNull;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(Feature.SCRIPTS)
public class PolicyEvaluationTest extends AbstractAuthzTest {
@Override
@ -617,11 +620,10 @@ public class PolicyEvaluationTest extends AbstractAuthzTest {
Scope readScope = storeFactory.getScopeStore().create(resourceServer, "read");
Scope writeScope = storeFactory.getScopeStore().create(resourceServer, "write");
JSPolicyRepresentation policy = new JSPolicyRepresentation();
PolicyRepresentation policy = new PolicyRepresentation();
policy.setName(KeycloakModelUtils.generateId());
policy.setType("script-scripts/default-policy.js");
policy.setLogic(Logic.NEGATIVE);
policy.setType("always-deny");
storeFactory.getPolicyStore().create(resourceServer, policy);

View file

@ -46,9 +46,9 @@ import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
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.PermissionRequest;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
@ -84,34 +84,25 @@ import static org.junit.Assert.fail;
public class UmaGrantTypeTest extends AbstractResourceServerTest {
private ResourceRepresentation resourceA;
private PolicyRepresentation grantPolicy;
private PolicyRepresentation denyPolicy;
@Before
public void configureAuthorization() throws Exception {
ClientResource client = getClient(getRealm());
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Default Policy");
policy.setType("script-scripts/default-policy.js");
authorization.policies().js().create(policy).close();
grantPolicy = createAlwaysGrantPolicy(authorization);
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
resourceA = addResource("Resource A", null, Collections.singleton("/resource"), false, "ScopeA", "ScopeB", "ScopeC");
permission.setName(resourceA.getName() + " Permission");
permission.addResource(resourceA.getName());
permission.addPolicy(policy.getName());
permission.addPolicy(grantPolicy.getName());
authorization.permissions().resource().create(permission).close();
policy = new JSPolicyRepresentation();
policy.setName("Deny Policy");
policy.setType("script-scripts/always-deny-policy.js");
authorization.policies().js().create(policy).close();
denyPolicy = createAlwaysDenyPolicy(authorization);
}
@Test
@ -188,7 +179,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permission.setName(resourceB.getName() + " Permission");
permission.addResource(resourceB.getName());
permission.addPolicy("Deny Policy");
permission.addPolicy(denyPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -207,7 +198,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permissionA.setName(resourceA.getName() + " Permission");
permissionA.addResource(resourceA.getName());
permissionA.addPolicy("Default Policy");
permissionA.addPolicy(grantPolicy.getName());
AuthorizationResource authzResource = getClient(getRealm()).authorization();
@ -227,7 +218,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permissionB.setName(resourceB.getName() + " Permission");
permissionB.addResource(resourceB.getName());
permissionB.addPolicy("Default Policy");
permissionB.addPolicy(grantPolicy.getName());
authzResource.permissions().resource().create(permissionB).close();
response = authorize("marta", "password", resourceB.getId(), new String[] {"ScopeC"}, rpt);
@ -242,8 +233,8 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
assertTrue(permissions.isEmpty());
permissionB = authzResource.permissions().resource().findByName(permissionB.getName());
permissionB.removePolicy("Default Policy");
permissionB.addPolicy("Deny Policy");
permissionB.removePolicy(grantPolicy.getName());
permissionB.addPolicy(denyPolicy.getName());
authzResource.permissions().resource().findById(permissionB.getId()).update(permissionB);
@ -265,7 +256,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permissionA.setName(KeycloakModelUtils.generateId());
permissionA.addScope("READ");
permissionA.addPolicy("Default Policy");
permissionA.addPolicy(grantPolicy.getName());
AuthorizationResource authzResource = getClient(getRealm()).authorization();
@ -275,7 +266,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permissionB.setName(KeycloakModelUtils.generateId());
permissionB.addScope("WRITE");
permissionB.addPolicy("Deny Policy");
permissionB.addPolicy(denyPolicy.getName());
authzResource.permissions().scope().create(permissionB).close();
@ -307,7 +298,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permission.setName(resourceA.getName() + " Permission");
permission.addResource(resourceA.getId());
permission.addPolicy("Default Policy");
permission.addPolicy(grantPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -315,7 +306,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permission.setName(resourceB.getName() + " Permission");
permission.addResource(resourceB.getId());
permission.addPolicy("Default Policy");
permission.addPolicy(grantPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -402,7 +393,7 @@ public class UmaGrantTypeTest extends AbstractResourceServerTest {
permission.setName(resourceB.getName() + " Permission");
permission.addResource(resourceB.getName());
permission.addPolicy("Default Policy");
permission.addPolicy(grantPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();

View file

@ -22,6 +22,7 @@ import java.util.Set;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.common.Profile.Feature;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
@ -31,6 +32,7 @@ import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.PermissionResponse;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.hamcrest.Matchers;
import org.junit.Test;
@ -43,6 +45,7 @@ import static org.junit.Assert.fail;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(Feature.SCRIPTS)
public class UmaPermissionTicketPushedClaimsTest extends AbstractResourceServerTest {
@Test

View file

@ -31,10 +31,10 @@ import org.keycloak.events.EventType;
import org.keycloak.representations.AccessToken;
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.PermissionTicketRepresentation;
import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
@ -60,18 +60,13 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
@Rule
public AssertEvents events = new AssertEvents(this);
private PolicyRepresentation onlyOwnerPolicy;
@Before
public void configureAuthorization() throws Exception {
ClientResource client = getClient(getRealm());
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation policy = new JSPolicyRepresentation();
policy.setName("Only Owner Policy");
policy.setType("script-scripts/only-owner-policy.js");
authorization.policies().js().create(policy).close();
onlyOwnerPolicy = createOnlyOwnerPolicy(authorization);
}
@Test
@ -81,7 +76,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getId());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -117,7 +112,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Scope A Permission");
permission.addScope("ScopeA");
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().scope().create(permission).close();
@ -125,7 +120,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Scope B Permission");
permission.addScope("ScopeB");
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().scope().create(permission).close();
@ -215,7 +210,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getType() + " Permission");
permission.setResourceType(resource.getType());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -285,7 +280,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getId());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
ClientResource client = getClient(getRealm());
@ -397,7 +392,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getId());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -477,7 +472,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getId());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();
@ -587,7 +582,7 @@ public class UserManagedAccessTest extends AbstractResourceServerTest {
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getId());
permission.addPolicy("Only Owner Policy");
permission.addPolicy(onlyOwnerPolicy.getName());
getClient(getRealm()).authorization().permissions().resource().create(permission).close();

View file

@ -37,6 +37,7 @@ import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.Resource;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.authorization.store.PolicyStore;
import org.keycloak.common.Profile.Feature;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@ -53,6 +54,7 @@ import org.keycloak.representations.idm.authorization.PermissionTicketRepresenta
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.UmaPermissionRepresentation;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.arquillian.annotation.UncaughtServerErrorExpected;
import org.keycloak.testsuite.runonserver.RunOnServer;
import org.keycloak.testsuite.util.ClientBuilder;
@ -75,6 +77,7 @@ import static org.junit.Assert.fail;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(Feature.SCRIPTS)
public class UserManagedPermissionServiceTest extends AbstractResourceServerTest {
@Override

View file

@ -24,9 +24,11 @@ import jakarta.ws.rs.core.Response;
import org.keycloak.admin.client.resource.AuthorizationResource;
import org.keycloak.admin.client.resource.JSPoliciesResource;
import org.keycloak.admin.client.resource.JSPolicyResource;
import org.keycloak.common.Profile.Feature;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.Logic;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.junit.Test;
@ -36,6 +38,7 @@ import static org.junit.Assert.fail;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(Feature.SCRIPTS)
public class JSPolicyManagementTest extends AbstractPolicyManagementTest {
@Test
@ -114,7 +117,7 @@ public class JSPolicyManagementTest extends AbstractPolicyManagementTest {
private void assertRepresentation(JSPolicyRepresentation representation, JSPolicyResource permission) {
JSPolicyRepresentation actual = permission.toRepresentation();
assertRepresentation(representation, actual, () -> permission.resources(), () -> Collections.emptyList(), () -> permission.associatedPolicies());
assertRepresentation(representation, actual, permission::resources, Collections::emptyList, permission::associatedPolicies);
assertEquals(representation.getType(), actual.getType());
}
}

View file

@ -36,6 +36,7 @@ import org.keycloak.representations.idm.authorization.PolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.provider.ScriptProviderDescriptor;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.arquillian.annotation.UncaughtServerErrorExpected;
import org.keycloak.testsuite.authz.AbstractAuthzTest;
import org.keycloak.testsuite.util.ClientBuilder;
@ -55,6 +56,7 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.keycloak.common.Profile.Feature.SCRIPTS;
import static org.keycloak.testsuite.arquillian.DeploymentTargetModifier.AUTH_SERVER_CURRENT;
import static org.junit.Assert.assertEquals;
@ -63,6 +65,7 @@ import static org.junit.Assert.assertFalse;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@EnableFeature(value = SCRIPTS, skipRestart = true)
public class DeployedScriptPolicyTest extends AbstractAuthzTest {
private static final String SCRIPT_DEPLOYMENT_NAME = "scripts.jar";

View file

@ -54,7 +54,7 @@
{
"name": "Only Owner Policy",
"description": "Defines that only the resource owner is allowed to do something",
"type": "script-scripts/only-owner-policy.js",
"type": "allow-resource-owner",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS"
},
@ -71,7 +71,7 @@
{
"name": "Only From a Specific Client Address",
"description": "Defines that only clients from a specific address can do something",
"type": "script-scripts/only-from-specific-address-policy.js",
"type": "only-from-specific-address-policy",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS"
},
@ -143,7 +143,7 @@
{
"name": "Only From @keycloak.org or Admin",
"description": "Defines that only users from @keycloak.org",
"type": "script-scripts/only-from-specific-domain-or-admin-policy.js",
"type": "only-from-specific-domain-or-admin-policy",
"logic": "POSITIVE",
"decisionStrategy": "UNANIMOUS"
},

View file

@ -26,7 +26,7 @@
{
"name": "Default Policy",
"description": "A policy that grants access only for users within this realm",
"type": "script-scripts/default-policy.js",
"type": "always-grant",
"logic": "POSITIVE",
"decisionStrategy": "AFFIRMATIVE"
},