use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.
the class AuthorizationTokenService method resolvePreviousGrantedPermissions.
private void resolvePreviousGrantedPermissions(PermissionTicketToken ticket, KeycloakAuthorizationRequest request, ResourceServer resourceServer, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, ScopeStore scopeStore, AtomicInteger limit) {
AccessToken rpt = request.getRpt();
if (rpt != null && rpt.isActive()) {
Authorization authorizationData = rpt.getAuthorization();
if (authorizationData != null) {
Collection<Permission> permissions = authorizationData.getPermissions();
if (permissions != null) {
for (Permission grantedPermission : permissions) {
if (limit != null && limit.get() <= 0) {
break;
}
Resource resource = resourceStore.findById(grantedPermission.getResourceId(), ticket.getIssuedFor());
if (resource != null) {
ResourcePermission permission = permissionsToEvaluate.get(resource.getId());
if (permission == null) {
permission = new ResourcePermission(resource, new ArrayList<>(), resourceServer, grantedPermission.getClaims());
permissionsToEvaluate.put(resource.getId(), permission);
if (limit != null) {
limit.decrementAndGet();
}
} else {
if (grantedPermission.getClaims() != null) {
for (Entry<String, Set<String>> entry : grantedPermission.getClaims().entrySet()) {
Set<String> claims = permission.getClaims().get(entry.getKey());
if (claims != null) {
claims.addAll(entry.getValue());
}
}
}
}
for (String scopeName : grantedPermission.getScopes()) {
Scope scope = scopeStore.findByName(scopeName, resourceServer.getId());
if (scope != null) {
if (!permission.getScopes().contains(scope)) {
permission.getScopes().add(scope);
}
}
}
}
}
}
}
}
}
use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.
the class PolicyEvaluationTest method testCheckReadOnlyInstances.
public static void testCheckReadOnlyInstances(KeycloakSession session) {
session.getContext().setRealm(session.realms().getRealmByName("authz-test"));
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
ClientModel clientModel = session.clients().getClientByClientId(session.getContext().getRealm(), "resource-server-test");
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel);
JSPolicyRepresentation policyRepresentation = new JSPolicyRepresentation();
policyRepresentation.setName("testCheckReadOnlyInstances");
StringBuilder builder = new StringBuilder();
builder.append("$evaluation.getPermission().getResource().setName('test')");
policyRepresentation.setCode(builder.toString());
Policy policy = storeFactory.getPolicyStore().create(policyRepresentation, resourceServer);
Resource resource = storeFactory.getResourceStore().create("Resource A", resourceServer, resourceServer.getId());
Scope scope = storeFactory.getScopeStore().create("Scope A", resourceServer);
resource.updateScopes(new HashSet<>(Arrays.asList(scope)));
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName("testCheckReadOnlyInstances permission");
permission.addPolicy(policy.getId());
permission.addResource(resource.getId());
storeFactory.getPolicyStore().create(permission, resourceServer);
session.getTransactionManager().commit();
PermissionEvaluator evaluator = authorization.evaluators().from(Arrays.asList(new ResourcePermission(resource, Arrays.asList(scope), resourceServer)), createEvaluationContext(session, Collections.emptyMap()));
try {
evaluator.evaluate(resourceServer, null);
Assert.fail("Instances should be marked as read-only");
} catch (Exception ignore) {
}
}
use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.
the class DecisionPermissionCollector method onComplete.
@Override
public void onComplete(Result result) {
ResourcePermission permission = result.getPermission();
Resource resource = permission.getResource();
Collection<Scope> requestedScopes = permission.getScopes();
if (Effect.PERMIT.equals(result.getEffect())) {
if (permission.getScopes().isEmpty() && !resource.getScopes().isEmpty()) {
return;
}
grantPermission(authorizationProvider, permissions, permission, requestedScopes, resourceServer, request, result);
} else {
Set<Scope> grantedScopes = new HashSet<>();
Set<Scope> deniedScopes = new HashSet<>();
List<Result.PolicyResult> userManagedPermissions = new ArrayList<>();
boolean resourceGranted = false;
boolean anyDeny = false;
for (Result.PolicyResult policyResult : result.getResults()) {
Policy policy = policyResult.getPolicy();
Set<Scope> policyScopes = policy.getScopes();
Set<Resource> policyResources = policy.getResources();
boolean containsResource = policyResources.contains(resource);
if (isGranted(policyResult)) {
if (isScopePermission(policy)) {
for (Scope scope : requestedScopes) {
if (policyScopes.contains(scope)) {
grantedScopes.add(scope);
// associated with the resource. For instance, resources inheriting scopes from parent resources.
if (resource != null && !resource.getScopes().contains(scope)) {
deniedScopes.remove(scope);
}
}
}
} else if (isResourcePermission(policy)) {
grantedScopes.addAll(requestedScopes);
} else if (resource != null && resource.isOwnerManagedAccess() && "uma".equals(policy.getType())) {
userManagedPermissions.add(policyResult);
}
if (!resourceGranted) {
resourceGranted = isGrantingAccessToResource(resource, policy) && containsResource;
}
} else {
if (isResourcePermission(policy)) {
// resource was not granted by any other permission
if (containsResource || !resourceGranted) {
deniedScopes.addAll(requestedScopes);
}
} else {
// resource or if the permission applies to any resource associated with the scopes
if (containsResource || policyResources.isEmpty()) {
deniedScopes.addAll(policyScopes);
}
}
if (!anyDeny) {
anyDeny = true;
}
}
}
if (DecisionStrategy.AFFIRMATIVE.equals(resourceServer.getDecisionStrategy())) {
// remove any scope that was granted from the list of denied scopes if the decision strategy is affirmative
deniedScopes.removeAll(grantedScopes);
}
grantedScopes.removeAll(deniedScopes);
if (userManagedPermissions.isEmpty()) {
if (!resourceGranted && (grantedScopes.isEmpty() && !requestedScopes.isEmpty())) {
return;
}
} else {
for (Result.PolicyResult userManagedPermission : userManagedPermissions) {
Set<Scope> scopes = new HashSet<>(userManagedPermission.getPolicy().getScopes());
if (!requestedScopes.isEmpty()) {
scopes.retainAll(requestedScopes);
}
grantedScopes.addAll(scopes);
}
if (grantedScopes.isEmpty() && !resource.getScopes().isEmpty()) {
return;
}
anyDeny = false;
}
if (anyDeny && grantedScopes.isEmpty()) {
return;
}
grantPermission(authorizationProvider, permissions, permission, grantedScopes, resourceServer, request, result);
}
}
use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.
the class DecisionPermissionCollector method grantPermission.
protected void grantPermission(AuthorizationProvider authorizationProvider, Set<Permission> permissions, ResourcePermission permission, Collection<Scope> grantedScopes, ResourceServer resourceServer, AuthorizationRequest request, Result result) {
Set<String> scopeNames = grantedScopes.stream().map(Scope::getName).collect(Collectors.toSet());
Resource resource = permission.getResource();
if (resource != null) {
permissions.add(createPermission(resource, scopeNames, permission.getClaims(), request));
} else if (!grantedScopes.isEmpty()) {
ResourceStore resourceStore = authorizationProvider.getStoreFactory().getResourceStore();
resourceStore.findByScope(grantedScopes.stream().map(Scope::getId).collect(Collectors.toList()), resourceServer.getId(), resource1 -> permissions.add(createPermission(resource, scopeNames, permission.getClaims(), request)));
permissions.add(createPermission(null, scopeNames, permission.getClaims(), request));
}
}
use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.
the class AuthorizationTokenService method resolveScopePermissions.
private void resolveScopePermissions(KeycloakAuthorizationRequest request, ResourceServer resourceServer, AuthorizationProvider authorization, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, AtomicInteger limit, Set<Scope> requestedScopesModel) {
AtomicBoolean processed = new AtomicBoolean();
resourceStore.findByScope(requestedScopesModel.stream().map(Scope::getId).collect(Collectors.toList()), resourceServer.getId(), resource -> {
if (limit != null && limit.get() <= 0) {
return;
}
ResourcePermission perm = permissionsToEvaluate.get(resource.getId());
if (perm == null) {
perm = Permissions.createResourcePermissions(resource, resourceServer, requestedScopesModel, authorization, request);
permissionsToEvaluate.put(resource.getId(), perm);
if (limit != null) {
limit.decrementAndGet();
}
} else {
for (Scope scope : requestedScopesModel) {
perm.addScope(scope);
}
}
processed.compareAndSet(false, true);
});
if (!processed.get()) {
for (Scope scope : requestedScopesModel) {
if (limit != null && limit.getAndDecrement() <= 0) {
break;
}
permissionsToEvaluate.computeIfAbsent(scope.getId(), s -> new ResourcePermission(null, new ArrayList<>(Arrays.asList(scope)), resourceServer, request.getClaims()));
}
}
}
Aggregations