use of org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation in project keycloak by keycloak.
the class PolicyEnforcerTest method testLazyLoadPaths.
@Test
public void testLazyLoadPaths() {
ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
for (int i = 0; i < 200; i++) {
ResourceRepresentation representation = new ResourceRepresentation();
representation.setType("test");
representation.setName("Resource " + i);
representation.setUri("/api/" + i);
javax.ws.rs.core.Response response = clientResource.authorization().resources().create(representation);
representation.setId(response.readEntity(ResourceRepresentation.class).getId());
response.close();
}
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName("Test Permission");
permission.setResourceType("test");
permission.addPolicy("Only User Policy");
PermissionsResource permissions = clientResource.authorization().permissions();
permissions.resource().create(permission).close();
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-no-lazyload.json"));
PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer();
assertEquals(205, policyEnforcer.getPaths().size());
deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-lazyload.json"));
policyEnforcer = deployment.getPolicyEnforcer();
assertEquals(0, policyEnforcer.getPathMatcher().getPathCache().size());
assertEquals(0, policyEnforcer.getPaths().size());
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();
for (int i = 0; i < 101; i++) {
policyEnforcer.enforce(createHttpFacade("/api/" + i, token));
}
assertEquals(101, policyEnforcer.getPathMatcher().getPathCache().size());
for (int i = 101; i < 200; i++) {
policyEnforcer.enforce(createHttpFacade("/api/" + i, token));
}
assertEquals(200, policyEnforcer.getPathMatcher().getPathCache().size());
assertEquals(0, policyEnforcer.getPaths().size());
ResourceRepresentation resource = clientResource.authorization().resources().findByName("Root").get(0);
clientResource.authorization().resources().resource(resource.getId()).remove();
deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-lazyload-with-paths.json"));
policyEnforcer = deployment.getPolicyEnforcer();
AuthorizationContext context = policyEnforcer.enforce(createHttpFacade("/api/0", token));
assertTrue(context.isGranted());
}
use of org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation in project keycloak by keycloak.
the class PolicyEnforcerTest method testUsingInvalidToken.
@Test
public void testUsingInvalidToken() {
ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
ResourceRepresentation resource = createResource(clientResource, "Resource Subject Invalid Token", "/api/check-subject-token");
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getName());
permission.addPolicy("Only User Policy");
PermissionsResource permissions = clientResource.authorization().permissions();
permissions.resource().create(permission).close();
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only.json"));
PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer();
OIDCHttpFacade httpFacade = createHttpFacade("/api/check-subject-token");
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();
httpFacade = createHttpFacade("/api/check-subject-token", token);
AuthorizationContext context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
oauth.doLogout(response.getRefreshToken(), null);
context = policyEnforcer.enforce(httpFacade);
assertFalse(context.isGranted());
}
use of org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation in project keycloak by keycloak.
the class PolicyEnforcerTest method testMatchHttpVerbsToScopes.
@Test
public void testMatchHttpVerbsToScopes() {
ClientResource clientResource = getClientResource(RESOURCE_SERVER_CLIENT_ID);
ResourceRepresentation resource = createResource(clientResource, "Resource With HTTP Scopes", "/api/resource-with-scope");
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName(resource.getName() + " Permission");
permission.addResource(resource.getName());
permission.addPolicy("Always Grant Policy");
PermissionsResource permissions = clientResource.authorization().permissions();
permissions.resource().create(permission).close();
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-match-http-verbs-scopes.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/resource-with-scope", token);
AuthorizationContext context = policyEnforcer.enforce(httpFacade);
assertFalse("Should fail because resource does not have any scope named GET", context.isGranted());
assertEquals(403, TestResponse.class.cast(httpFacade.getResponse()).getStatus());
resource.addScope("GET", "POST");
clientResource.authorization().resources().resource(resource.getId()).update(resource);
deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-match-http-verbs-scopes.json"));
policyEnforcer = deployment.getPolicyEnforcer();
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST");
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
// create a PATCH scope without associated it with the resource so that a PATCH request is denied accordingly even though
// the scope exists on the server
clientResource.authorization().scopes().create(new ScopeRepresentation("PATCH"));
httpFacade = createHttpFacade("/api/resource-with-scope", token, "PATCH");
context = policyEnforcer.enforce(httpFacade);
assertFalse(context.isGranted());
ScopePermissionRepresentation postPermission = new ScopePermissionRepresentation();
postPermission.setName("GET permission");
postPermission.addScope("GET");
postPermission.addPolicy("Always Deny Policy");
permissions.scope().create(postPermission).close();
httpFacade = createHttpFacade("/api/resource-with-scope", token);
context = policyEnforcer.enforce(httpFacade);
assertFalse(context.isGranted());
postPermission = permissions.scope().findByName(postPermission.getName());
postPermission.addScope("GET");
postPermission.addPolicy("Always Grant Policy");
permissions.scope().findById(postPermission.getId()).update(postPermission);
AuthzClient authzClient = getAuthzClient("default-keycloak.json");
AuthorizationResponse authorize = authzClient.authorization(token).authorize();
token = authorize.getToken();
httpFacade = createHttpFacade("/api/resource-with-scope", token);
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST");
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
postPermission = permissions.scope().findByName(postPermission.getName());
postPermission.addScope("GET");
postPermission.addPolicy("Always Deny Policy");
permissions.scope().findById(postPermission.getId()).update(postPermission);
authorize = authzClient.authorization(token).authorize();
token = authorize.getToken();
httpFacade = createHttpFacade("/api/resource-with-scope", token);
context = policyEnforcer.enforce(httpFacade);
assertFalse(context.isGranted());
httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST");
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
postPermission = permissions.scope().findByName(postPermission.getName());
postPermission.addScope("GET");
postPermission.addPolicy("Always Grant Policy");
permissions.scope().findById(postPermission.getId()).update(postPermission);
authorize = authzClient.authorization(token).authorize();
token = authorize.getToken();
httpFacade = createHttpFacade("/api/resource-with-scope", token);
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST");
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
postPermission = permissions.scope().findByName(postPermission.getName());
postPermission.addScope("POST");
postPermission.addPolicy("Always Deny Policy");
permissions.scope().findById(postPermission.getId()).update(postPermission);
AuthorizationRequest request = new AuthorizationRequest();
request.addPermission(null, "GET");
authorize = authzClient.authorization(token).authorize(request);
token = authorize.getToken();
httpFacade = createHttpFacade("/api/resource-with-scope", token);
context = policyEnforcer.enforce(httpFacade);
assertTrue(context.isGranted());
httpFacade = createHttpFacade("/api/resource-with-scope", token, "POST");
context = policyEnforcer.enforce(httpFacade);
assertFalse(context.isGranted());
}
use of org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation in project keycloak by keycloak.
the class EntitlementAPITest method testPermissionsWithResourceAttributes.
@Test
public void testPermissionsWithResourceAttributes() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
JSPolicyRepresentation onlyPublicResourcesPolicy = new JSPolicyRepresentation();
onlyPublicResourcesPolicy.setName(KeycloakModelUtils.generateId());
onlyPublicResourcesPolicy.setCode("var createPermission = $evaluation.getPermission();\n" + "var resource = createPermission.getResource();\n" + "\n" + "if (resource) {\n" + " var attributes = resource.getAttributes();\n" + " var visibility = attributes.get('visibility');\n" + " \n" + " if (visibility && \"private\".equals(visibility.get(0))) {\n" + " $evaluation.deny();\n" + " } else {\n" + " $evaluation.grant();\n" + " }\n" + "}");
authorization.policies().js().create(onlyPublicResourcesPolicy).close();
JSPolicyRepresentation onlyOwnerPolicy = createOnlyOwnerPolicy();
authorization.policies().js().create(onlyOwnerPolicy).close();
ResourceRepresentation typedResource = new ResourceRepresentation();
typedResource.setType("resource");
typedResource.setName(KeycloakModelUtils.generateId());
try (Response response = authorization.resources().create(typedResource)) {
typedResource = response.readEntity(ResourceRepresentation.class);
}
ResourceRepresentation userResource = new ResourceRepresentation();
userResource.setName(KeycloakModelUtils.generateId());
userResource.setType("resource");
userResource.setOwner("marta");
Map<String, List<String>> attributes = new HashMap<>();
attributes.put("visibility", Arrays.asList("private"));
userResource.setAttributes(attributes);
try (Response response = authorization.resources().create(userResource)) {
userResource = response.readEntity(ResourceRepresentation.class);
}
ResourcePermissionRepresentation typedResourcePermission = new ResourcePermissionRepresentation();
typedResourcePermission.setName(KeycloakModelUtils.generateId());
typedResourcePermission.setResourceType("resource");
typedResourcePermission.addPolicy(onlyPublicResourcesPolicy.getName());
try (Response response = authorization.permissions().resource().create(typedResourcePermission)) {
typedResourcePermission = response.readEntity(ResourcePermissionRepresentation.class);
}
// marta can access any public resource
AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
AuthorizationRequest request = new AuthorizationRequest();
request.addPermission(typedResource.getId());
request.addPermission(userResource.getId());
AuthorizationResponse response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
Collection<Permission> permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
assertEquals(1, permissions.size());
for (Permission grantedPermission : permissions) {
assertEquals(typedResource.getName(), grantedPermission.getResourceName());
}
typedResourcePermission.addPolicy(onlyOwnerPolicy.getName());
typedResourcePermission.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
authorization.permissions().resource().findById(typedResourcePermission.getId()).update(typedResourcePermission);
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
assertEquals(2, permissions.size());
for (Permission grantedPermission : permissions) {
assertThat(Arrays.asList(typedResource.getName(), userResource.getName()), Matchers.hasItem(grantedPermission.getResourceName()));
}
typedResource.setAttributes(attributes);
authorization.resources().resource(typedResource.getId()).update(typedResource);
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
assertEquals(1, permissions.size());
for (Permission grantedPermission : permissions) {
assertThat(userResource.getName(), Matchers.equalTo(grantedPermission.getResourceName()));
}
userResource.addScope("create", "read");
authorization.resources().resource(userResource.getId()).update(userResource);
typedResource.addScope("create", "read");
authorization.resources().resource(typedResource.getId()).update(typedResource);
ScopePermissionRepresentation createPermission = new ScopePermissionRepresentation();
createPermission.setName(KeycloakModelUtils.generateId());
createPermission.addScope("create");
createPermission.addPolicy(onlyPublicResourcesPolicy.getName());
authorization.permissions().scope().create(createPermission).close();
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
assertEquals(1, permissions.size());
for (Permission grantedPermission : permissions) {
assertThat(userResource.getName(), Matchers.equalTo(grantedPermission.getResourceName()));
assertThat(grantedPermission.getScopes(), Matchers.not(Matchers.hasItem("create")));
}
typedResource.setAttributes(new HashMap<>());
authorization.resources().resource(typedResource.getId()).update(typedResource);
response = authzClient.authorization("marta", "password").authorize();
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
for (Permission grantedPermission : permissions) {
if (grantedPermission.getResourceName().equals(userResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.not(Matchers.hasItem("create")));
} else if (grantedPermission.getResourceName().equals(typedResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.containsInAnyOrder("create", "read"));
}
}
request = new AuthorizationRequest();
request.addPermission(typedResource.getId());
request.addPermission(userResource.getId());
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
for (Permission grantedPermission : permissions) {
if (grantedPermission.getResourceName().equals(userResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.not(Matchers.hasItem("create")));
} else if (grantedPermission.getResourceName().equals(typedResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.containsInAnyOrder("create", "read"));
}
}
request = new AuthorizationRequest();
request.addPermission(userResource.getId());
request.addPermission(typedResource.getId());
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
permissions = toAccessToken(response.getToken()).getAuthorization().getPermissions();
for (Permission grantedPermission : permissions) {
if (grantedPermission.getResourceName().equals(userResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.not(Matchers.hasItem("create")));
} else if (grantedPermission.getResourceName().equals(typedResource.getName())) {
assertThat(grantedPermission.getScopes(), Matchers.containsInAnyOrder("create", "read"));
}
}
}
use of org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation in project keycloak by keycloak.
the class EntitlementAPITest method testServerDecisionStrategy.
@Test
public void testServerDecisionStrategy() throws Exception {
ClientResource client = getClient(getRealm(), RESOURCE_SERVER_TEST);
AuthorizationResource authorization = client.authorization();
ResourceRepresentation resource = new ResourceRepresentation();
resource.setName(KeycloakModelUtils.generateId());
resource.addScope("read", "write", "delete");
try (Response response = authorization.resources().create(resource)) {
resource = response.readEntity(ResourceRepresentation.class);
}
JSPolicyRepresentation grantPolicy = new JSPolicyRepresentation();
grantPolicy.setName(KeycloakModelUtils.generateId());
grantPolicy.setCode("$evaluation.grant();");
authorization.policies().js().create(grantPolicy).close();
JSPolicyRepresentation denyPolicy = new JSPolicyRepresentation();
denyPolicy.setName(KeycloakModelUtils.generateId());
denyPolicy.setCode("$evaluation.deny();");
authorization.policies().js().create(denyPolicy).close();
ResourcePermissionRepresentation resourcePermission = new ResourcePermissionRepresentation();
resourcePermission.setName(KeycloakModelUtils.generateId());
resourcePermission.addResource(resource.getId());
resourcePermission.addPolicy(denyPolicy.getName());
authorization.permissions().resource().create(resourcePermission).close();
ScopePermissionRepresentation scopePermission1 = new ScopePermissionRepresentation();
scopePermission1.setName(KeycloakModelUtils.generateId());
scopePermission1.addScope("read");
scopePermission1.addPolicy(grantPolicy.getName());
ScopePermissionsResource scopePermissions = authorization.permissions().scope();
scopePermissions.create(scopePermission1).close();
String accessToken = new OAuthClient().realm("authz-test").clientId(RESOURCE_SERVER_TEST).doGrantAccessTokenRequest("secret", "kolo", "password").getAccessToken();
AuthzClient authzClient = getAuthzClient(AUTHZ_CLIENT_CONFIG);
AuthorizationRequest request = new AuthorizationRequest();
request.addPermission(resource.getName());
try {
authzClient.authorization(accessToken).authorize(request);
fail("kolo can not access the resource");
} catch (RuntimeException expected) {
assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
}
ResourceServerRepresentation settings = authorization.getSettings();
settings.setDecisionStrategy(DecisionStrategy.AFFIRMATIVE);
authorization.update(settings);
assertPermissions(authzClient, accessToken, request, resource, "read");
scopePermission1 = scopePermissions.findByName(scopePermission1.getName());
scopePermission1.addScope("read", "delete");
scopePermissions.findById(scopePermission1.getId()).update(scopePermission1);
assertPermissions(authzClient, accessToken, request, resource, "read", "delete");
ScopePermissionRepresentation scopePermission2 = new ScopePermissionRepresentation();
scopePermission2.setName(KeycloakModelUtils.generateId());
scopePermission2.addScope("write");
scopePermission2.addPolicy(grantPolicy.getName());
scopePermissions.create(scopePermission2).close();
assertPermissions(authzClient, accessToken, request, resource, "read", "delete", "write");
ScopePermissionRepresentation scopePermission3 = new ScopePermissionRepresentation();
scopePermission3.setName(KeycloakModelUtils.generateId());
scopePermission3.addResource(resource.getId());
scopePermission3.addScope("write", "read", "delete");
scopePermission3.addPolicy(grantPolicy.getName());
scopePermissions.create(scopePermission3).close();
assertPermissions(authzClient, accessToken, request, resource, "read", "delete", "write");
scopePermission2 = scopePermissions.findByName(scopePermission2.getName());
scopePermissions.findById(scopePermission2.getId()).remove();
assertPermissions(authzClient, accessToken, request, resource, "read", "delete", "write");
scopePermission1 = scopePermissions.findByName(scopePermission1.getName());
scopePermissions.findById(scopePermission1.getId()).remove();
assertPermissions(authzClient, accessToken, request, resource, "read", "delete", "write");
scopePermission3 = scopePermissions.findByName(scopePermission3.getName());
scopePermission3.addScope("write", "delete");
scopePermissions.findById(scopePermission3.getId()).update(scopePermission3);
assertPermissions(authzClient, accessToken, request, resource, "delete", "write");
scopePermissions.findById(scopePermission3.getId()).remove();
try {
authzClient.authorization(accessToken).authorize(request);
fail("kolo can not access the resource");
} catch (RuntimeException expected) {
assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
}
ResourcePermissionRepresentation grantResourcePermission = new ResourcePermissionRepresentation();
grantResourcePermission.setName(KeycloakModelUtils.generateId());
grantResourcePermission.addResource(resource.getId());
grantResourcePermission.addPolicy(grantPolicy.getName());
authorization.permissions().resource().create(grantResourcePermission).close();
assertPermissions(authzClient, accessToken, request, resource, "read", "delete", "write");
settings.setDecisionStrategy(DecisionStrategy.UNANIMOUS);
authorization.update(settings);
try {
authzClient.authorization(accessToken).authorize(request);
fail("kolo can not access the resource");
} catch (RuntimeException expected) {
assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
}
}
Aggregations