Search in sources :

Example 11 with ResourcePermission

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);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : Authorization(org.keycloak.representations.AccessToken.Authorization) Set(java.util.Set) HashSet(java.util.HashSet) Scope(org.keycloak.authorization.model.Scope) AccessToken(org.keycloak.representations.AccessToken) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Permission(org.keycloak.representations.idm.authorization.Permission) Resource(org.keycloak.authorization.model.Resource) ArrayList(java.util.ArrayList) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Example 12 with ResourcePermission

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) {
    }
}
Also used : Policy(org.keycloak.authorization.model.Policy) PermissionEvaluator(org.keycloak.authorization.permission.evaluator.PermissionEvaluator) JSPolicyRepresentation(org.keycloak.representations.idm.authorization.JSPolicyRepresentation) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) Resource(org.keycloak.authorization.model.Resource) StoreFactory(org.keycloak.authorization.store.StoreFactory) ResourcePermissionRepresentation(org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation) ClientModel(org.keycloak.models.ClientModel) Scope(org.keycloak.authorization.model.Scope) ResourceServer(org.keycloak.authorization.model.ResourceServer) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Example 13 with ResourcePermission

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);
    }
}
Also used : Policy(org.keycloak.authorization.model.Policy) Resource(org.keycloak.authorization.model.Resource) ArrayList(java.util.ArrayList) Scope(org.keycloak.authorization.model.Scope) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 14 with ResourcePermission

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));
    }
}
Also used : ResourceServer(org.keycloak.authorization.model.ResourceServer) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Scope(org.keycloak.authorization.model.Scope) Permission(org.keycloak.representations.idm.authorization.Permission) Collection(java.util.Collection) AuthorizationRequest(org.keycloak.representations.idm.authorization.AuthorizationRequest) Set(java.util.Set) DecisionStrategy(org.keycloak.representations.idm.authorization.DecisionStrategy) ResourceStore(org.keycloak.authorization.store.ResourceStore) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Policy(org.keycloak.authorization.model.Policy) List(java.util.List) Map(java.util.Map) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) LinkedHashSet(java.util.LinkedHashSet) Resource(org.keycloak.authorization.model.Resource) Resource(org.keycloak.authorization.model.Resource) ResourceStore(org.keycloak.authorization.store.ResourceStore)

Example 15 with ResourcePermission

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()));
        }
    }
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Scope(org.keycloak.authorization.model.Scope) ArrayList(java.util.ArrayList) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Aggregations

ResourcePermission (org.keycloak.authorization.permission.ResourcePermission)19 Map (java.util.Map)9 Policy (org.keycloak.authorization.model.Policy)9 Resource (org.keycloak.authorization.model.Resource)9 Scope (org.keycloak.authorization.model.Scope)9 Permission (org.keycloak.representations.idm.authorization.Permission)8 HashMap (java.util.HashMap)7 AuthorizationProvider (org.keycloak.authorization.AuthorizationProvider)7 ResourceServer (org.keycloak.authorization.model.ResourceServer)7 ArrayList (java.util.ArrayList)6 Decision (org.keycloak.authorization.Decision)6 StoreFactory (org.keycloak.authorization.store.StoreFactory)6 HashSet (java.util.HashSet)5 Set (java.util.Set)5 Collection (java.util.Collection)4 DefaultEvaluation (org.keycloak.authorization.policy.evaluation.DefaultEvaluation)4 ClientModel (org.keycloak.models.ClientModel)4 LinkedHashMap (java.util.LinkedHashMap)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3