use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.
the class PermissionClaimTest method testClaimsFromDifferentResourcePermissions.
@Test
public void testClaimsFromDifferentResourcePermissions() throws Exception {
ClientResource client = getClient(getRealm());
AuthorizationResource authorization = client.authorization();
ResourceRepresentation resourceA = new ResourceRepresentation(KeycloakModelUtils.generateId());
resourceA.setType("typed-resource");
authorization.resources().create(resourceA).close();
ResourcePermissionRepresentation allScopesPermission = new ResourcePermissionRepresentation();
allScopesPermission.setName(KeycloakModelUtils.generateId());
allScopesPermission.addResource(resourceA.getName());
allScopesPermission.addPolicy(claimAPolicy.getName(), claimBPolicy.getName());
authorization.permissions().resource().create(allScopesPermission).close();
ResourcePermissionRepresentation updatePermission = new ResourcePermissionRepresentation();
updatePermission.setName(KeycloakModelUtils.generateId());
updatePermission.addResource(resourceA.getName());
updatePermission.addPolicy(claimCPolicy.getName());
try (Response response = authorization.permissions().resource().create(updatePermission)) {
updatePermission = response.readEntity(ResourcePermissionRepresentation.class);
}
AuthzClient authzClient = getAuthzClient();
AuthorizationResponse response = authzClient.authorization("marta", "password").authorize();
assertNotNull(response.getToken());
AccessToken rpt = toAccessToken(response.getToken());
Authorization authorizationClaim = rpt.getAuthorization();
List<Permission> permissions = new ArrayList<>(authorizationClaim.getPermissions());
assertEquals(1, permissions.size());
for (Permission permission : permissions) {
Map<String, Set<String>> claims = permission.getClaims();
assertNotNull(claims);
assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
}
updatePermission.addPolicy(denyPolicy.getName());
authorization.permissions().resource().findById(updatePermission.getId()).update(updatePermission);
try {
authzClient.authorization("marta", "password").authorize();
fail("can not access resource");
} catch (RuntimeException expected) {
assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
}
ResourceRepresentation resourceInstance = new ResourceRepresentation(KeycloakModelUtils.generateId(), "create", "update");
resourceInstance.setType(resourceA.getType());
resourceInstance.setOwner("marta");
try (Response response1 = authorization.resources().create(resourceInstance)) {
resourceInstance = response1.readEntity(ResourceRepresentation.class);
}
AuthorizationRequest request = new AuthorizationRequest();
request.addPermission(null, "create", "update");
try {
authzClient.authorization("marta", "password").authorize(request);
fail("can not access resource");
} catch (RuntimeException expected) {
assertEquals(403, HttpResponseException.class.cast(expected.getCause()).getStatusCode());
assertTrue(HttpResponseException.class.cast(expected.getCause()).toString().contains("access_denied"));
}
ResourcePermissionRepresentation resourceInstancePermission = new ResourcePermissionRepresentation();
resourceInstancePermission.setName(KeycloakModelUtils.generateId());
resourceInstancePermission.addResource(resourceInstance.getId());
resourceInstancePermission.addPolicy(claimCPolicy.getName());
try (Response response1 = authorization.permissions().resource().create(resourceInstancePermission)) {
resourceInstancePermission = response1.readEntity(ResourcePermissionRepresentation.class);
}
response = authzClient.authorization("marta", "password").authorize(request);
assertNotNull(response.getToken());
rpt = toAccessToken(response.getToken());
authorizationClaim = rpt.getAuthorization();
permissions = new ArrayList<>(authorizationClaim.getPermissions());
assertEquals(1, permissions.size());
for (Permission permission : permissions) {
Map<String, Set<String>> claims = permission.getClaims();
assertNotNull(claims);
assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
assertThat(claims.get("deny-policy"), Matchers.containsInAnyOrder("deny-policy"));
}
response = authzClient.authorization("marta", "password").authorize();
assertNotNull(response.getToken());
rpt = toAccessToken(response.getToken());
authorizationClaim = rpt.getAuthorization();
permissions = new ArrayList<>(authorizationClaim.getPermissions());
assertEquals(1, permissions.size());
for (Permission permission : permissions) {
Map<String, Set<String>> claims = permission.getClaims();
assertNotNull(claims);
assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
assertThat(claims.get("deny-policy"), Matchers.containsInAnyOrder("deny-policy"));
assertThat(permission.getScopes(), Matchers.containsInAnyOrder("create", "update"));
}
updatePermission.setPolicies(new HashSet<>());
updatePermission.addPolicy(claimCPolicy.getName());
authorization.permissions().resource().findById(updatePermission.getId()).update(updatePermission);
response = authzClient.authorization("marta", "password").authorize();
assertNotNull(response.getToken());
rpt = toAccessToken(response.getToken());
authorizationClaim = rpt.getAuthorization();
permissions = new ArrayList<>(authorizationClaim.getPermissions());
assertEquals(2, permissions.size());
for (Permission permission : permissions) {
Map<String, Set<String>> claims = permission.getClaims();
assertNotNull(claims);
assertThat(claims.get("claim-a"), Matchers.containsInAnyOrder("claim-a", "claim-a1"));
assertThat(claims.get("claim-b"), Matchers.containsInAnyOrder("claim-b"));
assertThat(claims.get("claim-c"), Matchers.containsInAnyOrder("claim-c"));
}
}
use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.
the class AuthorizationTest method authorize.
private List<Permission> authorize(String userName, String password, AuthorizationRequest request) {
AuthorizationResponse response = getAuthzClient().authorization(userName, password).authorize(request);
AccessToken token = toAccessToken(response.getToken());
Authorization authorization = token.getAuthorization();
return new ArrayList<>(authorization.getPermissions());
}
use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.
the class AbstractPolicyEnforcer method isAuthorized.
protected boolean isAuthorized(PathConfig actualPathConfig, MethodConfig methodConfig, AccessToken accessToken, OIDCHttpFacade httpFacade, Map<String, List<String>> claims) {
Request request = httpFacade.getRequest();
if (isDefaultAccessDeniedUri(request)) {
return true;
}
Authorization authorization = accessToken.getAuthorization();
if (authorization == null) {
return false;
}
boolean hasPermission = false;
Collection<Permission> grantedPermissions = authorization.getPermissions();
for (Permission permission : grantedPermissions) {
if (permission.getResourceId() != null) {
if (isResourcePermission(actualPathConfig, permission)) {
hasPermission = true;
if (actualPathConfig.isInstance() && !matchResourcePermission(actualPathConfig, permission)) {
continue;
}
if (hasResourceScopePermission(methodConfig, permission)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debugf("Authorization GRANTED for path [%s]. Permissions [%s].", actualPathConfig, grantedPermissions);
}
if (HTTP_METHOD_DELETE.equalsIgnoreCase(request.getMethod()) && actualPathConfig.isInstance()) {
policyEnforcer.getPathMatcher().removeFromCache(getPath(request));
}
return hasValidClaims(permission, claims);
}
}
} else {
if (hasResourceScopePermission(methodConfig, permission)) {
hasPermission = true;
return true;
}
}
}
if (!hasPermission && EnforcementMode.PERMISSIVE.equals(actualPathConfig.getEnforcementMode())) {
return true;
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debugf("Authorization FAILED for path [%s]. Not enough permissions [%s].", actualPathConfig, grantedPermissions);
}
return false;
}
use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.
the class AuthorizationTokenService method isUpgraded.
private boolean isUpgraded(AuthorizationRequest request, Authorization authorization) {
AccessToken previousRpt = request.getRpt();
if (previousRpt == null) {
return false;
}
Authorization previousAuthorization = previousRpt.getAuthorization();
if (previousAuthorization != null) {
Collection<Permission> previousPermissions = previousAuthorization.getPermissions();
if (previousPermissions != null) {
for (Permission previousPermission : previousPermissions) {
if (!authorization.getPermissions().contains(previousPermission)) {
return false;
}
}
}
}
return true;
}
use of org.keycloak.representations.AccessToken.Authorization in project keycloak by keycloak.
the class AuthorizationTokenService method resolveResourcePermission.
private void resolveResourcePermission(KeycloakAuthorizationRequest request, ResourceServer resourceServer, KeycloakIdentity identity, AuthorizationProvider authorization, StoreFactory storeFactory, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, AtomicInteger limit, Permission permission, Set<Scope> requestedScopesModel, String resourceId) {
Resource resource;
if (resourceId.indexOf('-') != -1) {
resource = resourceStore.findById(resourceId, resourceServer.getId());
} else {
resource = null;
}
if (resource != null) {
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource);
} else if (resourceId.startsWith("resource-type:")) {
// only resource types, no resource instances. resource types are owned by the resource server
String resourceType = resourceId.substring("resource-type:".length());
resourceStore.findByType(resourceType, resourceServer.getId(), resourceServer.getId(), resource1 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource1));
} else if (resourceId.startsWith("resource-type-any:")) {
// any resource with a given type
String resourceType = resourceId.substring("resource-type-any:".length());
resourceStore.findByType(resourceType, null, resourceServer.getId(), resource12 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource12));
} else if (resourceId.startsWith("resource-type-instance:")) {
// only resource instances with a given type
String resourceType = resourceId.substring("resource-type-instance:".length());
resourceStore.findByTypeInstance(resourceType, resourceServer.getId(), resource13 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource13));
} else if (resourceId.startsWith("resource-type-owner:")) {
// only resources where the current identity is the owner
String resourceType = resourceId.substring("resource-type-owner:".length());
resourceStore.findByType(resourceType, identity.getId(), resourceServer.getId(), resource14 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource14));
} else {
Resource ownerResource = resourceStore.findByName(resourceId, identity.getId(), resourceServer.getId());
if (ownerResource != null) {
permission.setResourceId(ownerResource.getId());
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, ownerResource);
}
if (!identity.isResourceServer() || !identity.getId().equals(resourceServer.getId())) {
List<PermissionTicket> tickets = storeFactory.getPermissionTicketStore().findGranted(resourceId, identity.getId(), resourceServer.getId());
if (!tickets.isEmpty()) {
List<Scope> scopes = new ArrayList<>();
Resource grantedResource = null;
for (PermissionTicket permissionTicket : tickets) {
if (grantedResource == null) {
grantedResource = permissionTicket.getResource();
}
scopes.add(permissionTicket.getScope());
}
requestedScopesModel.retainAll(scopes);
ResourcePermission resourcePermission = addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, grantedResource);
// the permission is explicitly granted by the owner, mark this permission as granted so that we don't run the evaluation engine on it
resourcePermission.setGranted(true);
}
Resource serverResource = resourceStore.findByName(resourceId, resourceServer.getId());
if (serverResource != null) {
permission.setResourceId(serverResource.getId());
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, serverResource);
}
}
}
if (permissionsToEvaluate.isEmpty()) {
CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(request.getCors(), "invalid_resource", "Resource with id [" + resourceId + "] does not exist.", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
throw invalidResourceException;
}
}
Aggregations