Search in sources :

Example 16 with ResourcePermission

use of org.keycloak.authorization.permission.ResourcePermission 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;
    }
}
Also used : ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Arrays(java.util.Arrays) Tokens(org.keycloak.authorization.util.Tokens) UserSessionProvider(org.keycloak.models.UserSessionProvider) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) BiFunction(java.util.function.BiFunction) Permissions(org.keycloak.authorization.permission.Permissions) PermissionTicketAwareDecisionResultCollector(org.keycloak.authorization.policy.evaluation.PermissionTicketAwareDecisionResultCollector) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Metadata(org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata) MediaType(javax.ws.rs.core.MediaType) OAuthErrorException(org.keycloak.OAuthErrorException) AuthenticationManager(org.keycloak.services.managers.AuthenticationManager) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AccessToken(org.keycloak.representations.AccessToken) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) Map(java.util.Map) ClientConnection(org.keycloak.common.ClientConnection) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) Collection(java.util.Collection) AuthorizationRequest(org.keycloak.representations.idm.authorization.AuthorizationRequest) Set(java.util.Set) ResourceStore(org.keycloak.authorization.store.ResourceStore) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) Collectors(java.util.stream.Collectors) IDToken(org.keycloak.representations.IDToken) KeycloakIdentity(org.keycloak.authorization.common.KeycloakIdentity) Objects(java.util.Objects) List(java.util.List) ScopeStore(org.keycloak.authorization.store.ScopeStore) ServiceAccountConstants(org.keycloak.common.constants.ServiceAccountConstants) Response(javax.ws.rs.core.Response) Details(org.keycloak.events.Details) DefaultEvaluationContext(org.keycloak.authorization.common.DefaultEvaluationContext) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) Entry(java.util.Map.Entry) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) ClientModel(org.keycloak.models.ClientModel) Scope(org.keycloak.authorization.model.Scope) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Permission(org.keycloak.representations.idm.authorization.Permission) Logger(org.jboss.logging.Logger) StoreFactory(org.keycloak.authorization.store.StoreFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) RefreshToken(org.keycloak.representations.RefreshToken) TokenManager(org.keycloak.protocol.oidc.TokenManager) HttpMethod(javax.ws.rs.HttpMethod) ArrayList(java.util.ArrayList) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) UserModel(org.keycloak.models.UserModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) EventBuilder(org.keycloak.events.EventBuilder) OIDCAdvancedConfigWrapper(org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper) PermissionTicketToken(org.keycloak.representations.idm.authorization.PermissionTicketToken) Cors(org.keycloak.services.resources.Cors) Status(javax.ws.rs.core.Response.Status) Base64Url(org.keycloak.common.util.Base64Url) ResourceServer(org.keycloak.authorization.model.ResourceServer) Errors(org.keycloak.events.Errors) Authorization(org.keycloak.representations.AccessToken.Authorization) KeycloakSession(org.keycloak.models.KeycloakSession) HttpRequest(org.jboss.resteasy.spi.HttpRequest) UserSessionModel(org.keycloak.models.UserSessionModel) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) JsonSerialization(org.keycloak.util.JsonSerialization) EvaluationContext(org.keycloak.authorization.policy.evaluation.EvaluationContext) ResourceServerStore(org.keycloak.authorization.store.ResourceServerStore) Urls(org.keycloak.services.Urls) AccessTokenResponseBuilder(org.keycloak.protocol.oidc.TokenManager.AccessTokenResponseBuilder) Resource(org.keycloak.authorization.model.Resource) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) Scope(org.keycloak.authorization.model.Scope) Resource(org.keycloak.authorization.model.Resource) ArrayList(java.util.ArrayList) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Example 17 with ResourcePermission

use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.

the class AuthorizationTokenService method createPermissions.

private Collection<ResourcePermission> createPermissions(PermissionTicketToken ticket, KeycloakAuthorizationRequest request, ResourceServer resourceServer, AuthorizationProvider authorization, EvaluationContext context) {
    KeycloakIdentity identity = (KeycloakIdentity) context.getIdentity();
    StoreFactory storeFactory = authorization.getStoreFactory();
    Map<String, ResourcePermission> permissionsToEvaluate = new LinkedHashMap<>();
    ResourceStore resourceStore = storeFactory.getResourceStore();
    ScopeStore scopeStore = storeFactory.getScopeStore();
    Metadata metadata = request.getMetadata();
    final AtomicInteger limit = metadata != null && metadata.getLimit() != null ? new AtomicInteger(metadata.getLimit()) : null;
    for (Permission permission : ticket.getPermissions()) {
        if (limit != null && limit.get() <= 0) {
            break;
        }
        Set<Scope> requestedScopesModel = resolveRequestedScopes(request, resourceServer, scopeStore, permission);
        String resourceId = permission.getResourceId();
        if (resourceId != null) {
            resolveResourcePermission(request, resourceServer, identity, authorization, storeFactory, permissionsToEvaluate, resourceStore, limit, permission, requestedScopesModel, resourceId);
        } else {
            resolveScopePermissions(request, resourceServer, authorization, permissionsToEvaluate, resourceStore, limit, requestedScopesModel);
        }
    }
    resolvePreviousGrantedPermissions(ticket, request, resourceServer, permissionsToEvaluate, resourceStore, scopeStore, limit);
    return permissionsToEvaluate.values();
}
Also used : Metadata(org.keycloak.representations.idm.authorization.AuthorizationRequest.Metadata) ScopeStore(org.keycloak.authorization.store.ScopeStore) ResourceStore(org.keycloak.authorization.store.ResourceStore) StoreFactory(org.keycloak.authorization.store.StoreFactory) LinkedHashMap(java.util.LinkedHashMap) Scope(org.keycloak.authorization.model.Scope) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) KeycloakIdentity(org.keycloak.authorization.common.KeycloakIdentity) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Permission(org.keycloak.representations.idm.authorization.Permission) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission)

Example 18 with ResourcePermission

use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.

the class PolicyEvaluationTest method testCachedDecisionsWithNegativePolicies.

public static void testCachedDecisionsWithNegativePolicies(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);
    Scope readScope = storeFactory.getScopeStore().create("read", resourceServer);
    Scope writeScope = storeFactory.getScopeStore().create("write", resourceServer);
    JSPolicyRepresentation policy = new JSPolicyRepresentation();
    policy.setName(KeycloakModelUtils.generateId());
    policy.setCode("$evaluation.grant()");
    policy.setLogic(Logic.NEGATIVE);
    storeFactory.getPolicyStore().create(policy, resourceServer);
    ScopePermissionRepresentation readPermission = new ScopePermissionRepresentation();
    readPermission.setName(KeycloakModelUtils.generateId());
    readPermission.addScope(readScope.getId());
    readPermission.addPolicy(policy.getName());
    storeFactory.getPolicyStore().create(readPermission, resourceServer);
    ScopePermissionRepresentation writePermission = new ScopePermissionRepresentation();
    writePermission.setName(KeycloakModelUtils.generateId());
    writePermission.addScope(writeScope.getId());
    writePermission.addPolicy(policy.getName());
    storeFactory.getPolicyStore().create(writePermission, resourceServer);
    Resource resource = storeFactory.getResourceStore().create(KeycloakModelUtils.generateId(), resourceServer, resourceServer.getId());
    PermissionEvaluator evaluator = authorization.evaluators().from(Arrays.asList(new ResourcePermission(resource, Arrays.asList(readScope, writeScope), resourceServer)), createEvaluationContext(session, Collections.emptyMap()));
    Collection<Permission> permissions = evaluator.evaluate(resourceServer, null);
    Assert.assertEquals(0, permissions.size());
}
Also used : ClientModel(org.keycloak.models.ClientModel) PermissionEvaluator(org.keycloak.authorization.permission.evaluator.PermissionEvaluator) Scope(org.keycloak.authorization.model.Scope) JSPolicyRepresentation(org.keycloak.representations.idm.authorization.JSPolicyRepresentation) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) Resource(org.keycloak.authorization.model.Resource) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Permission(org.keycloak.representations.idm.authorization.Permission) StoreFactory(org.keycloak.authorization.store.StoreFactory) ResourceServer(org.keycloak.authorization.model.ResourceServer) ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) ScopePermissionRepresentation(org.keycloak.representations.idm.authorization.ScopePermissionRepresentation)

Example 19 with ResourcePermission

use of org.keycloak.authorization.permission.ResourcePermission in project keycloak by keycloak.

the class GroupPermissions method hasPermission.

private boolean hasPermission(Resource resource, EvaluationContext context, String... scopes) {
    ResourceServer server = root.realmResourceServer();
    Collection<Permission> permissions;
    if (context == null) {
        permissions = root.evaluatePermission(new ResourcePermission(resource, resource.getScopes(), server), server);
    } else {
        permissions = root.evaluatePermission(new ResourcePermission(resource, resource.getScopes(), server), server, context);
    }
    List<String> expectedScopes = Arrays.asList(scopes);
    for (Permission permission : permissions) {
        for (String scope : permission.getScopes()) {
            if (expectedScopes.contains(scope)) {
                return true;
            }
        }
    }
    return false;
}
Also used : ResourcePermission(org.keycloak.authorization.permission.ResourcePermission) Permission(org.keycloak.representations.idm.authorization.Permission) ResourceServer(org.keycloak.authorization.model.ResourceServer) 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