Search in sources :

Example 31 with PermissionTicket

use of org.keycloak.authorization.model.PermissionTicket 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 32 with PermissionTicket

use of org.keycloak.authorization.model.PermissionTicket in project keycloak by keycloak.

the class PermissionTicketService method create.

@POST
@Consumes("application/json")
@Produces("application/json")
public Response create(PermissionTicketRepresentation representation) {
    PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore();
    if (representation == null)
        throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "invalid_permission", Response.Status.BAD_REQUEST);
    if (representation.getId() != null)
        throw new ErrorResponseException("invalid_permission", "created permissions should not have id", Response.Status.BAD_REQUEST);
    if (representation.getResource() == null)
        throw new ErrorResponseException("invalid_permission", "created permissions should have resource", Response.Status.BAD_REQUEST);
    if (representation.getScope() == null && representation.getScopeName() == null)
        throw new ErrorResponseException("invalid_permission", "created permissions should have scope or scopeName", Response.Status.BAD_REQUEST);
    if (representation.getRequester() == null && representation.getRequesterName() == null)
        throw new ErrorResponseException("invalid_permission", "created permissions should have requester or requesterName", Response.Status.BAD_REQUEST);
    ResourceStore rstore = this.authorization.getStoreFactory().getResourceStore();
    Resource resource = rstore.findById(representation.getResource(), resourceServer.getId());
    if (resource == null)
        throw new ErrorResponseException("invalid_resource_id", "Resource set with id [" + representation.getResource() + "] does not exists in this server.", Response.Status.BAD_REQUEST);
    if (!resource.getOwner().equals(this.identity.getId()))
        throw new ErrorResponseException("not_authorised", "permissions for [" + representation.getResource() + "] can be only created by the owner", Response.Status.FORBIDDEN);
    UserModel user = null;
    if (representation.getRequester() != null)
        user = this.authorization.getKeycloakSession().userStorageManager().getUserById(this.authorization.getRealm(), representation.getRequester());
    else
        user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(this.authorization.getRealm(), representation.getRequesterName());
    if (user == null)
        throw new ErrorResponseException("invalid_permission", "Requester does not exists in this server as user.", Response.Status.BAD_REQUEST);
    Scope scope = null;
    ScopeStore sstore = this.authorization.getStoreFactory().getScopeStore();
    if (representation.getScopeName() != null)
        scope = sstore.findByName(representation.getScopeName(), resourceServer.getId());
    else
        scope = sstore.findById(representation.getScope(), resourceServer.getId());
    if (scope == null && representation.getScope() != null)
        throw new ErrorResponseException("invalid_scope", "Scope [" + representation.getScope() + "] is invalid", Response.Status.BAD_REQUEST);
    if (scope == null && representation.getScopeName() != null)
        throw new ErrorResponseException("invalid_scope", "Scope [" + representation.getScopeName() + "] is invalid", Response.Status.BAD_REQUEST);
    boolean match = resource.getScopes().contains(scope);
    if (!match)
        throw new ErrorResponseException("invalid_resource_id", "Resource set with id [" + representation.getResource() + "] does not have Scope [" + scope.getName() + "]", Response.Status.BAD_REQUEST);
    Map<PermissionTicket.FilterOption, String> attributes = new EnumMap<>(PermissionTicket.FilterOption.class);
    attributes.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId());
    attributes.put(PermissionTicket.FilterOption.SCOPE_ID, scope.getId());
    attributes.put(PermissionTicket.FilterOption.REQUESTER, user.getId());
    if (!ticketStore.find(attributes, resourceServer.getId(), -1, -1).isEmpty())
        throw new ErrorResponseException("invalid_permission", "Permission already exists", Response.Status.BAD_REQUEST);
    PermissionTicket ticket = ticketStore.create(resource.getId(), scope.getId(), user.getId(), resourceServer);
    if (representation.isGranted())
        ticket.setGrantedTimestamp(java.lang.System.currentTimeMillis());
    representation = ModelToRepresentation.toRepresentation(ticket, authorization);
    return Response.ok(representation).build();
}
Also used : PermissionTicket(org.keycloak.authorization.model.PermissionTicket) Resource(org.keycloak.authorization.model.Resource) ScopeStore(org.keycloak.authorization.store.ScopeStore) ResourceStore(org.keycloak.authorization.store.ResourceStore) UserModel(org.keycloak.models.UserModel) Scope(org.keycloak.authorization.model.Scope) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) ErrorResponseException(org.keycloak.services.ErrorResponseException) EnumMap(java.util.EnumMap) POST(javax.ws.rs.POST) Consumes(javax.ws.rs.Consumes) Produces(javax.ws.rs.Produces)

Example 33 with PermissionTicket

use of org.keycloak.authorization.model.PermissionTicket in project keycloak by keycloak.

the class PermissionTicketService method find.

@GET
@Produces("application/json")
public Response find(@QueryParam("scopeId") String scopeId, @QueryParam("resourceId") String resourceId, @QueryParam("owner") String owner, @QueryParam("requester") String requester, @QueryParam("granted") Boolean granted, @QueryParam("returnNames") Boolean returnNames, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResult) {
    StoreFactory storeFactory = authorization.getStoreFactory();
    PermissionTicketStore permissionTicketStore = storeFactory.getPermissionTicketStore();
    Map<PermissionTicket.FilterOption, String> filters = getFilters(storeFactory, resourceId, scopeId, owner, requester, granted);
    return Response.ok().entity(permissionTicketStore.find(filters, resourceServer.getId(), firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream().map(permissionTicket -> ModelToRepresentation.toRepresentation(permissionTicket, authorization, returnNames == null ? false : returnNames)).collect(Collectors.toList())).build();
}
Also used : Scope(org.keycloak.authorization.model.Scope) PathParam(javax.ws.rs.PathParam) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) StoreFactory(org.keycloak.authorization.store.StoreFactory) Constants(org.keycloak.models.Constants) Path(javax.ws.rs.Path) PermissionTicket(org.keycloak.authorization.model.PermissionTicket) RepresentationToModel(org.keycloak.models.utils.RepresentationToModel) OAuthErrorException(org.keycloak.OAuthErrorException) UserModel(org.keycloak.models.UserModel) QueryParam(javax.ws.rs.QueryParam) Consumes(javax.ws.rs.Consumes) ErrorResponseException(org.keycloak.services.ErrorResponseException) Map(java.util.Map) AuthorizationProvider(org.keycloak.authorization.AuthorizationProvider) DELETE(javax.ws.rs.DELETE) ResourceServer(org.keycloak.authorization.model.ResourceServer) RealmModel(org.keycloak.models.RealmModel) POST(javax.ws.rs.POST) EnumMap(java.util.EnumMap) ResourceStore(org.keycloak.authorization.store.ResourceStore) Collectors(java.util.stream.Collectors) KeycloakIdentity(org.keycloak.authorization.common.KeycloakIdentity) PermissionTicketRepresentation(org.keycloak.representations.idm.authorization.PermissionTicketRepresentation) UserProvider(org.keycloak.models.UserProvider) ScopeStore(org.keycloak.authorization.store.ScopeStore) ModelToRepresentation(org.keycloak.models.utils.ModelToRepresentation) Response(javax.ws.rs.core.Response) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) PUT(javax.ws.rs.PUT) Resource(org.keycloak.authorization.model.Resource) PermissionTicketStore(org.keycloak.authorization.store.PermissionTicketStore) StoreFactory(org.keycloak.authorization.store.StoreFactory) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 34 with PermissionTicket

use of org.keycloak.authorization.model.PermissionTicket in project keycloak by keycloak.

the class MapPermissionTicketStore method findGrantedResources.

@Override
public List<Resource> findGrantedResources(String requester, String name, int first, int max) {
    DefaultModelCriteria<PermissionTicket> mcb = criteria();
    mcb = mcb.compare(SearchableFields.REQUESTER, Operator.EQ, requester).compare(SearchableFields.GRANTED_TIMESTAMP, Operator.EXISTS);
    Function<MapPermissionTicketEntity, Resource> ticketResourceMapper;
    ResourceStore resourceStore = authorizationProvider.getStoreFactory().getResourceStore();
    if (name != null) {
        ticketResourceMapper = ticket -> {
            Map<Resource.FilterOption, String[]> filterOptionMap = new EnumMap<>(Resource.FilterOption.class);
            filterOptionMap.put(Resource.FilterOption.ID, new String[] { ticket.getResourceId() });
            filterOptionMap.put(Resource.FilterOption.NAME, new String[] { name });
            List<Resource> resource = resourceStore.findByResourceServer(filterOptionMap, ticket.getResourceServerId(), -1, 1);
            return resource.isEmpty() ? null : resource.get(0);
        };
    } else {
        ticketResourceMapper = ticket -> resourceStore.findById(ticket.getResourceId(), ticket.getResourceServerId());
    }
    return paginatedStream(tx.read(withCriteria(mcb).orderBy(SearchableFields.RESOURCE_ID, ASCENDING)).filter(distinctByKey(MapPermissionTicketEntity::getResourceId)).map(ticketResourceMapper).filter(Objects::nonNull), first, max).collect(Collectors.toList());
}
Also used : PermissionTicket(org.keycloak.authorization.model.PermissionTicket) Resource(org.keycloak.authorization.model.Resource) Objects(java.util.Objects) ResourceStore(org.keycloak.authorization.store.ResourceStore) MapPermissionTicketEntity(org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity) EnumMap(java.util.EnumMap)

Aggregations

PermissionTicket (org.keycloak.authorization.model.PermissionTicket)34 PermissionTicketStore (org.keycloak.authorization.store.PermissionTicketStore)20 EnumMap (java.util.EnumMap)17 Resource (org.keycloak.authorization.model.Resource)12 Scope (org.keycloak.authorization.model.Scope)12 UserModel (org.keycloak.models.UserModel)10 ArrayList (java.util.ArrayList)8 Map (java.util.Map)8 Path (javax.ws.rs.Path)8 AuthorizationProvider (org.keycloak.authorization.AuthorizationProvider)8 HashMap (java.util.HashMap)7 List (java.util.List)7 Policy (org.keycloak.authorization.model.Policy)7 ResourceServer (org.keycloak.authorization.model.ResourceServer)7 ResourceStore (org.keycloak.authorization.store.ResourceStore)7 Consumes (javax.ws.rs.Consumes)6 StoreFactory (org.keycloak.authorization.store.StoreFactory)6 Collection (java.util.Collection)5 Collectors (java.util.stream.Collectors)5 POST (javax.ws.rs.POST)5