Example usage for org.springframework.security.core GrantedAuthority getClass

List of usage examples for org.springframework.security.core GrantedAuthority getClass

Introduction

In this page you can find the example usage for org.springframework.security.core GrantedAuthority getClass.

Prototype

@HotSpotIntrinsicCandidate
public final native Class<?> getClass();

Source Link

Document

Returns the runtime class of this Object .

Usage

From source file:com.evolveum.midpoint.security.impl.SecurityEnforcerImpl.java

@Override
public <O extends ObjectType> ObjectSecurityConstraints compileSecurityConstraints(PrismObject<O> object,
        OwnerResolver ownerResolver) throws SchemaException {
    MidPointPrincipal principal = getMidPointPrincipal();
    if (object == null) {
        throw new IllegalArgumentException("Cannot compile security constraints of null object");
    }//from   w  w w  .  j a  v a  2s  . c  o  m
    if (principal == null) {
        // No need to log, the getMidPointPrincipal() already logs the reason
        return null;
    }
    LOGGER.trace("AUTZ: evaluating security constraints principal={}, object={}", principal, object);
    ObjectSecurityConstraintsImpl objectSecurityConstraints = new ObjectSecurityConstraintsImpl();
    Collection<Authorization> authorities = principal.getAuthorities();
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                String autzHumanReadableDesc = autz.getHumanReadableDesc();
                LOGGER.trace("Evaluating {}", autzHumanReadableDesc);

                // skip action applicability evaluation. We are interested in all actions

                // object
                if (isApplicable(autz.getObject(), object, principal, ownerResolver, "object",
                        autzHumanReadableDesc)) {
                    LOGGER.trace("  {} applicable for object {} (continuing evaluation)", autzHumanReadableDesc,
                            object);
                } else {
                    LOGGER.trace(
                            "  {} not applicable for object {}, none of the object specifications match (breaking evaluation)",
                            autzHumanReadableDesc, object);
                    continue;
                }

                // skip target applicability evaluation. We do not have a target here

                List<String> actions = autz.getAction();
                AuthorizationPhaseType phase = autz.getPhase();
                AuthorizationDecisionType decision = autz.getDecision();
                if (decision == null || decision == AuthorizationDecisionType.ALLOW) {
                    Collection<ItemPath> items = getItems(autz);
                    if (items == null || items.isEmpty()) {
                        applyDecision(objectSecurityConstraints.getActionDecisionMap(), actions, phase,
                                AuthorizationDecisionType.ALLOW);
                    } else {
                        for (ItemPath item : items) {
                            applyItemDecision(objectSecurityConstraints.getItemConstraintMap(), item, actions,
                                    phase, AuthorizationDecisionType.ALLOW);
                        }
                    }
                } else {
                    Collection<ItemPath> items = getItems(autz);
                    if (items == null || items.isEmpty()) {
                        applyDecision(objectSecurityConstraints.getActionDecisionMap(), actions, phase,
                                AuthorizationDecisionType.DENY);
                    } else {
                        for (ItemPath item : items) {
                            applyItemDecision(objectSecurityConstraints.getItemConstraintMap(), item, actions,
                                    phase, AuthorizationDecisionType.DENY);
                        }
                    }
                }

            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(),
                        principal.getUsername());
            }
        }
    }

    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ: evaluated security constraints principal={}, object={}:\n{}", principal, object,
                objectSecurityConstraints.debugDump());
    }

    return objectSecurityConstraints;
}

From source file:com.evolveum.midpoint.security.impl.SecurityEnforcerImpl.java

private <O extends ObjectType, T extends ObjectType> boolean isAuthorizedInternal(
        MidPointPrincipal midPointPrincipal, String operationUrl, AuthorizationPhaseType phase,
        PrismObject<O> object, ObjectDelta<O> delta, PrismObject<T> target, OwnerResolver ownerResolver)
        throws SchemaException {

    if (AuthorizationConstants.AUTZ_NO_ACCESS_URL.equals(operationUrl)) {
        return false;
    }/* w ww. j a  v a 2s  .  com*/

    if (phase == null) {
        throw new IllegalArgumentException("No phase");
    }
    boolean allow = false;
    LOGGER.trace("AUTZ: evaluating authorization principal={}, op={}, phase={}, object={}, delta={}, target={}",
            new Object[] { midPointPrincipal, operationUrl, phase, object, delta, target });
    final Collection<ItemPath> allowedItems = new ArrayList<>();
    Collection<Authorization> authorities = midPointPrincipal.getAuthorities();
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                String autzHumanReadableDesc = autz.getHumanReadableDesc();
                LOGGER.trace("Evaluating {}", autzHumanReadableDesc);

                // First check if the authorization is applicable.

                // action
                if (!autz.getAction().contains(operationUrl)
                        && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
                    LOGGER.trace("  {} not applicable for operation {}", autzHumanReadableDesc, operationUrl);
                    continue;
                }

                // phase
                if (autz.getPhase() == null) {
                    LOGGER.trace("  {} is applicable for all phases (continuing evaluation)",
                            autzHumanReadableDesc);
                } else {
                    if (autz.getPhase() != phase) {
                        LOGGER.trace("  {} is not applicable for phases {} (breaking evaluation)",
                                autzHumanReadableDesc, phase);
                        continue;
                    } else {
                        LOGGER.trace("  {} is applicable for phases {} (continuing evaluation)",
                                autzHumanReadableDesc, phase);
                    }
                }

                // object
                if (isApplicable(autz.getObject(), object, midPointPrincipal, ownerResolver, "object",
                        autzHumanReadableDesc)) {
                    LOGGER.trace("  {} applicable for object {} (continuing evaluation)", autzHumanReadableDesc,
                            object);
                } else {
                    LOGGER.trace(
                            "  {} not applicable for object {}, none of the object specifications match (breaking evaluation)",
                            autzHumanReadableDesc, object);
                    continue;
                }

                // target
                if (isApplicable(autz.getTarget(), target, midPointPrincipal, ownerResolver, "target",
                        autzHumanReadableDesc)) {
                    LOGGER.trace("  {} applicable for target {} (continuing evaluation)", autzHumanReadableDesc,
                            object);
                } else {
                    LOGGER.trace(
                            "  {} not applicable for target {}, none of the target specifications match (breaking evaluation)",
                            autzHumanReadableDesc, object);
                    continue;
                }

                // authority is applicable to this situation. now we can process the decision.
                AuthorizationDecisionType decision = autz.getDecision();
                if (decision == null || decision == AuthorizationDecisionType.ALLOW) {
                    // if there is more than one role which specify
                    // different authz (e.g one role specify allow for whole
                    // objet, the other role specify allow only for some
                    // attributes. this ended with allow for whole object (MID-2018)
                    Collection<ItemPath> allowed = getItems(autz);
                    if (allow && allowedItems.isEmpty()) {
                        LOGGER.trace("  {}: ALLOW operation {} (but continue evaluation)",
                                autzHumanReadableDesc, operationUrl);
                    } else if (allow && allowed.isEmpty()) {
                        allowedItems.clear();
                    } else {
                        allowedItems.addAll(allowed);
                    }
                    LOGGER.trace("  {}: ALLOW operation {} (but continue evaluation)", autzHumanReadableDesc,
                            operationUrl);
                    allow = true;
                    // Do NOT break here. Other authorization statements may still deny the operation
                } else {
                    // item
                    if (isApplicableItem(autz, object, delta)) {
                        LOGGER.trace("  {}: Deny authorization applicable for items (continuing evaluation)",
                                autzHumanReadableDesc);
                    } else {
                        LOGGER.trace("  {} not applicable for items (breaking evaluation)",
                                autzHumanReadableDesc);
                        continue;
                    }
                    LOGGER.trace("  {}: DENY operation {}", autzHumanReadableDesc, operationUrl);
                    allow = false;
                    // Break right here. Deny cannot be overridden by allow. This decision cannot be changed. 
                    break;
                }

            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(),
                        midPointPrincipal.getUsername());
            }
        }
    }

    if (allow) {
        // Still check allowedItems. We may still deny the operation.
        if (allowedItems.isEmpty()) {
            // This means all items are allowed. No need to check anything
            LOGGER.trace("  Empty list of allowed items, operation allowed");
        } else {
            // all items in the object and delta must be allowed
            final MutableBoolean itemDecision = new MutableBoolean(true);
            if (delta != null) {
                // If there is delta then consider only the delta.
                Visitor visitor = new Visitor() {
                    @Override
                    public void visit(Visitable visitable) {
                        ItemPath itemPath = getPath(visitable);
                        if (itemPath != null && !itemPath.isEmpty()) {
                            if (!isInList(itemPath, allowedItems)) {
                                LOGGER.trace("  DENY operation because item {} in the delta is not allowed",
                                        itemPath);
                                itemDecision.setValue(false);
                            }
                        }
                    }
                };
                delta.accept(visitor);
            } else if (object != null) {
                Visitor visitor = new Visitor() {
                    @Override
                    public void visit(Visitable visitable) {
                        ItemPath itemPath = getPath(visitable);
                        if (itemPath != null && !itemPath.isEmpty()) {
                            if (!isInList(itemPath, allowedItems)) {
                                LOGGER.trace("  DENY operation because item {} in the object is not allowed",
                                        itemPath);
                                itemDecision.setValue(false);
                            }
                        }
                    }
                };
                object.accept(visitor);
            }
            allow = itemDecision.booleanValue();
        }
    }

    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ result: principal={}, operation={}: {}",
                new Object[] { midPointPrincipal, operationUrl, allow });
    }
    return allow;
}

From source file:com.evolveum.midpoint.security.enforcer.impl.SecurityEnforcerImpl.java

private <O extends ObjectType, T extends ObjectType> AccessDecision isAuthorizedPhase(
        MidPointPrincipal midPointPrincipal, String operationUrl, AuthorizationPhaseType phase,
        AuthorizationParameters<O, T> params, OwnerResolver ownerResolver,
        Consumer<Authorization> applicableAutzConsumer, Task task, OperationResult result)
        throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException,
        ConfigurationException, SecurityViolationException {

    if (AuthorizationConstants.AUTZ_NO_ACCESS_URL.equals(operationUrl)) {
        return AccessDecision.DENY;
    }//  ww  w  .  jav a 2 s  . c o m

    if (phase == null) {
        throw new IllegalArgumentException("No phase");
    }
    AccessDecision decision = AccessDecision.DEFAULT;
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ: evaluating authorization principal={}, op={}, phase={}, {}",
                getUsername(midPointPrincipal), operationUrl, phase, params.shortDump());
    }
    final AutzItemPaths allowedItems = new AutzItemPaths();
    Collection<Authorization> authorities = getAuthorities(midPointPrincipal);
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                String autzHumanReadableDesc = autz.getHumanReadableDesc();
                LOGGER.trace("  Evaluating {}", autzHumanReadableDesc);

                // First check if the authorization is applicable.

                // action
                if (!autz.getAction().contains(operationUrl)
                        && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
                    LOGGER.trace("    {} not applicable for operation {}", autzHumanReadableDesc, operationUrl);
                    continue;
                }

                // phase
                if (autz.getPhase() == null) {
                    LOGGER.trace("    {} is applicable for all phases (continuing evaluation)",
                            autzHumanReadableDesc);
                } else {
                    if (autz.getPhase() != phase) {
                        LOGGER.trace("    {} is not applicable for phases {} (breaking evaluation)",
                                autzHumanReadableDesc, phase);
                        continue;
                    } else {
                        LOGGER.trace("    {} is applicable for phases {} (continuing evaluation)",
                                autzHumanReadableDesc, phase);
                    }
                }

                // relation
                if (!isApplicableRelation(autz, params.getRelation())) {
                    LOGGER.trace("    {} not applicable for relation {}", autzHumanReadableDesc,
                            params.getRelation());
                    continue;
                }

                // object
                if (isApplicable(autz.getObject(), params.getObject(), midPointPrincipal, ownerResolver,
                        "object", autzHumanReadableDesc, task, result)) {
                    LOGGER.trace("    {} applicable for object {} (continuing evaluation)",
                            autzHumanReadableDesc, params.getObject());
                } else {
                    LOGGER.trace(
                            "    {} not applicable for object {}, none of the object specifications match (breaking evaluation)",
                            autzHumanReadableDesc, params.getObject());
                    continue;
                }

                // target
                if (isApplicable(autz.getTarget(), params.getTarget(), midPointPrincipal, ownerResolver,
                        "target", autzHumanReadableDesc, task, result)) {
                    LOGGER.trace("    {} applicable for target {} (continuing evaluation)",
                            autzHumanReadableDesc, params.getObject());
                } else {
                    LOGGER.trace(
                            "    {} not applicable for target {}, none of the target specifications match (breaking evaluation)",
                            autzHumanReadableDesc, params.getObject());
                    continue;
                }

                if (applicableAutzConsumer != null) {
                    applicableAutzConsumer.accept(autz);
                }

                // authority is applicable to this situation. now we can process the decision.
                AuthorizationDecisionType autzDecision = autz.getDecision();
                if (autzDecision == null || autzDecision.equals(AuthorizationDecisionType.ALLOW)) {
                    allowedItems.collectItems(autz);
                    LOGGER.trace("    {}: ALLOW operation {} (but continue evaluation)", autzHumanReadableDesc,
                            operationUrl);
                    decision = AccessDecision.ALLOW;
                    // Do NOT break here. Other authorization statements may still deny the operation
                } else {
                    // item
                    if (isApplicableItem(autz, params.getObject(), params.getDelta())) {
                        LOGGER.trace("    {}: Deny authorization applicable for items (continuing evaluation)",
                                autzHumanReadableDesc);
                    } else {
                        LOGGER.trace("    {} not applicable for items (breaking evaluation)",
                                autzHumanReadableDesc);
                        continue;
                    }
                    LOGGER.trace("    {}: DENY operation {}", autzHumanReadableDesc, operationUrl);
                    decision = AccessDecision.DENY;
                    // Break right here. Deny cannot be overridden by allow. This decision cannot be changed.
                    break;
                }

            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(),
                        getUsername(midPointPrincipal));
            }
        }
    }

    if (decision.equals(AccessDecision.ALLOW)) {
        // Still check allowedItems. We may still deny the operation.
        if (allowedItems.isAllItems()) {
            // This means all items are allowed. No need to check anything
            LOGGER.trace("  Empty list of allowed items, operation allowed");
        } else {
            // all items in the object and delta must be allowed
            LOGGER.trace("  Checking for allowed items: {}", allowedItems);

            ItemDecisionFunction itemDecisionFunction = (itemPath,
                    removingContainer) -> decideAllowedItems(itemPath, allowedItems, phase, removingContainer);
            AccessDecision itemsDecision = null;
            if (params.hasDelta()) {
                itemsDecision = determineDeltaDecision(params.getDelta(), params.getObject(),
                        itemDecisionFunction);
            } else if (params.hasObject()) {
                itemsDecision = determineObjectDecision(params.getObject(), itemDecisionFunction);
            }
            if (itemsDecision != AccessDecision.ALLOW) {
                LOGGER.trace("    NOT ALLOWED operation because the item decision is {}", itemsDecision);
                decision = AccessDecision.DEFAULT;
            }
        }
    }

    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ result: principal={}, operation={}: {}", getUsername(midPointPrincipal),
                prettyActionUrl(operationUrl), decision);
    }
    return decision;
}

From source file:com.evolveum.midpoint.security.impl.SecurityEnforcerImpl.java

private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilterInternal(
        MidPointPrincipal principal, String operationUrl, AuthorizationPhaseType phase,
        boolean includeNullPhase, Class<T> objectType, PrismObject<O> object, ObjectFilter origFilter)
        throws SchemaException {
    Collection<Authorization> authorities = principal.getAuthorities();
    ObjectFilter securityFilterAllow = null;
    ObjectFilter securityFilterDeny = null;
    boolean hasAllowAll = false;
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                LOGGER.trace("Evaluating authorization {}", autz);

                // action
                if (!autz.getAction().contains(operationUrl)
                        && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
                    LOGGER.trace("  Authorization not applicable for operation {}", operationUrl);
                    continue;
                }/* w w w  . ja v a 2s. c o m*/

                // phase
                if (autz.getPhase() == phase || (includeNullPhase && autz.getPhase() == null)) {
                    LOGGER.trace("  Authorization is applicable for phases {} (continuing evaluation)", phase);
                } else {
                    LOGGER.trace("  Authorization is not applicable for phase {}", phase);
                    continue;
                }

                // object or target
                ObjectFilter autzObjSecurityFilter = null;
                List<OwnedObjectSpecificationType> objectSpecTypes;
                if (object == null) {
                    // object not present. Therefore we are looking for object here
                    objectSpecTypes = autz.getObject();
                } else {
                    // object present. Therefore we are looking for target
                    objectSpecTypes = autz.getTarget();

                    // .. but we need to decide whether this authorization is applicable to the object
                    if (!isApplicableItem(autz, object, null)) {
                        LOGGER.trace("  Authorization is not applicable for object {}", object);
                    }
                }

                boolean applicable = true;
                if (objectSpecTypes != null && !objectSpecTypes.isEmpty()) {
                    applicable = false;
                    for (OwnedObjectSpecificationType objectSpecType : objectSpecTypes) {
                        ObjectFilter objSpecSecurityFilter = null;
                        TypeFilter objSpecTypeFilter = null;
                        SearchFilterType specFilterType = objectSpecType.getFilter();
                        ObjectReferenceType specOrgRef = objectSpecType.getOrgRef();
                        QName specTypeQName = objectSpecType.getType();
                        PrismObjectDefinition<T> objectDefinition = null;

                        // Type
                        if (specTypeQName != null) {
                            specTypeQName = prismContext.getSchemaRegistry().qualifyTypeName(specTypeQName);
                            PrismObjectDefinition<?> specObjectDef = prismContext.getSchemaRegistry()
                                    .findObjectDefinitionByType(specTypeQName);
                            Class<?> specObjectClass = specObjectDef.getCompileTimeClass();
                            if (!objectType.isAssignableFrom(specObjectClass)) {
                                LOGGER.trace(
                                        "  Authorization not applicable for object because of type mismatch, authorization {}, query {}",
                                        new Object[] { specObjectClass, objectType });
                                continue;
                            } else {
                                LOGGER.trace(
                                        "  Authorization is applicable for object because of type match, authorization {}, query {}",
                                        new Object[] { specObjectClass, objectType });
                                // The spec type is a subclass of requested type. So it might be returned from the search.
                                // We need to use type filter.
                                objSpecTypeFilter = TypeFilter.createType(specTypeQName, null);
                                // and now we have a more specific object definition to use later in filter processing
                                objectDefinition = (PrismObjectDefinition<T>) specObjectDef;
                            }
                        }

                        // Owner
                        if (objectSpecType.getOwner() != null) {
                            LOGGER.trace(
                                    "  Authorization not applicable for object because it has owner specification (this is not applicable for search)");
                            continue;
                        }

                        applicable = true;

                        // Special
                        List<SpecialObjectSpecificationType> specSpecial = objectSpecType.getSpecial();
                        if (specSpecial != null && !specSpecial.isEmpty()) {
                            if (specFilterType != null || specOrgRef != null) {
                                throw new SchemaException(
                                        "Both filter/org and special object specification specified in authorization");
                            }
                            ObjectFilter specialFilter = null;
                            for (SpecialObjectSpecificationType special : specSpecial) {
                                if (special == SpecialObjectSpecificationType.SELF) {
                                    String principalOid = principal.getOid();
                                    specialFilter = ObjectQueryUtil.filterOr(specialFilter,
                                            InOidFilter.createInOid(principalOid));
                                } else {
                                    throw new SchemaException(
                                            "Unsupported special object specification specified in authorization: "
                                                    + special);
                                }
                            }
                            objSpecSecurityFilter = specTypeQName != null
                                    ? TypeFilter.createType(specTypeQName, specialFilter)
                                    : specialFilter;
                        } else {
                            LOGGER.trace("  specials empty: {}", specSpecial);
                        }

                        // Filter
                        if (specFilterType != null) {
                            if (objectDefinition == null) {
                                objectDefinition = prismContext.getSchemaRegistry()
                                        .findObjectDefinitionByCompileTimeClass(objectType);
                            }
                            ObjectFilter specFilter = QueryJaxbConvertor.createObjectFilter(objectDefinition,
                                    specFilterType, prismContext);
                            if (specFilter != null) {
                                ObjectQueryUtil.assertNotRaw(specFilter,
                                        "Filter in authorization object has undefined items. Maybe a 'type' specification is missing in the authorization?");
                                ObjectQueryUtil.assertPropertyOnly(specFilter,
                                        "Filter in authorization object is not property-only filter");
                            }
                            LOGGER.trace("  applying property filter " + specFilter);
                            objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter,
                                    specFilter);
                        } else {
                            LOGGER.trace("  filter empty");
                        }

                        // Org
                        if (specOrgRef != null) {
                            OrgFilter orgFilter = OrgFilter.createOrg(specOrgRef.getOid());
                            objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, orgFilter);
                            LOGGER.trace("  applying org filter " + orgFilter);
                        } else {
                            LOGGER.trace("  org empty");
                        }

                        if (objSpecTypeFilter != null) {
                            objSpecTypeFilter.setFilter(objSpecSecurityFilter);
                            objSpecSecurityFilter = objSpecTypeFilter;
                        }

                        autzObjSecurityFilter = ObjectQueryUtil.filterOr(autzObjSecurityFilter,
                                objSpecSecurityFilter);
                    }
                } else {
                    LOGGER.trace(
                            "  No object specification in authorization (authorization is universaly applicable)");
                    autzObjSecurityFilter = AllFilter.createAll();
                }

                if (applicable) {
                    // authority is applicable to this situation. now we can process the decision.
                    AuthorizationDecisionType decision = autz.getDecision();
                    if (decision == null || decision == AuthorizationDecisionType.ALLOW) {
                        // allow
                        if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
                            // this is "allow all" authorization.
                            hasAllowAll = true;
                        } else {
                            securityFilterAllow = ObjectQueryUtil.filterOr(securityFilterAllow,
                                    autzObjSecurityFilter);
                        }
                    } else {
                        // deny
                        if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
                            // This is "deny all". We cannot have anything stronger than that.
                            // There is no point in continuing the evaluation.
                            LOGGER.trace("AUTZ search pre-process: principal={}, operation={}: deny all",
                                    new Object[] { principal.getUsername(), operationUrl });
                            return NoneFilter.createNone();
                        }
                        securityFilterDeny = ObjectQueryUtil.filterOr(securityFilterDeny,
                                autzObjSecurityFilter);
                    }
                }

            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(),
                        principal.getUsername());
            }
        }
    }

    ObjectFilter origWithAllowFilter;
    if (hasAllowAll) {
        origWithAllowFilter = origFilter;
    } else if (securityFilterAllow == null) {
        // Nothing has been allowed. This means default deny.
        LOGGER.trace("AUTZ search pre-process: principal={}, operation={}: default deny",
                new Object[] { principal.getUsername(), operationUrl });
        return NoneFilter.createNone();
    } else {
        origWithAllowFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilterAllow);
    }

    if (securityFilterDeny == null) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("AUTZ search pre-process: principal={}, operation={}: allow:\n{}",
                    new Object[] { principal.getUsername(), operationUrl,
                            origWithAllowFilter == null ? "null" : origWithAllowFilter.debugDump() });
        }
        return origWithAllowFilter;
    } else {
        ObjectFilter secFilter = ObjectQueryUtil.filterAnd(origWithAllowFilter,
                NotFilter.createNot(securityFilterDeny));
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("AUTZ search pre-process: principal={}, operation={}: allow (with deny clauses):\n{}",
                    new Object[] { principal.getUsername(), operationUrl,
                            secFilter == null ? "null" : secFilter.debugDump() });
        }
        return secFilter;
    }
}

From source file:com.evolveum.midpoint.security.enforcer.impl.SecurityEnforcerImpl.java

private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilterInternal(
        MidPointPrincipal principal, String operationUrl, AuthorizationPhaseType phase,
        boolean includeNullPhase, Class<T> objectType, PrismObject<O> object, boolean includeSpecial,
        ObjectFilter origFilter, String limitAuthorizationAction, String desc, Task task,
        OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException,
        CommunicationException, ConfigurationException, SecurityViolationException {

    Collection<Authorization> authorities = getAuthorities(principal);

    ObjectFilter securityFilterAllow = null;
    ObjectFilter securityFilterDeny = null;

    QueryAutzItemPaths queryItemsSpec = new QueryAutzItemPaths();
    queryItemsSpec.addRequiredItems(origFilter); // MID-3916
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("  phase={}, initial query items spec {}", phase, queryItemsSpec.shortDump());
    }//from ww w  . j  ava 2 s .  c  o  m

    boolean hasAllowAll = false;
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                String autzHumanReadableDesc = autz.getHumanReadableDesc();
                LOGGER.trace("  Evaluating {}", autzHumanReadableDesc);

                // action
                if (!autz.getAction().contains(operationUrl)
                        && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
                    LOGGER.trace("    Authorization not applicable for operation {}", operationUrl);
                    continue;
                }

                // phase
                if (autz.getPhase() == phase || (includeNullPhase && autz.getPhase() == null)) {
                    LOGGER.trace("    Authorization is applicable for phases {} (continuing evaluation)",
                            phase);
                } else {
                    LOGGER.trace("    Authorization is not applicable for phase {}", phase);
                    continue;
                }

                if (!isApplicableLimitations(autz, limitAuthorizationAction)) {
                    LOGGER.trace(
                            "    Authorization is limited to other action, not applicable for operation {}",
                            operationUrl);
                    continue;
                }

                // object or target
                String objectTargetSpec;
                ObjectFilter autzObjSecurityFilter = null;
                List<OwnedObjectSelectorType> objectSpecTypes;
                if (object == null) {
                    // object not present. Therefore we are looking for object here
                    objectSpecTypes = autz.getObject();
                    objectTargetSpec = "object";
                } else {
                    // object present. Therefore we are looking for target
                    objectSpecTypes = autz.getTarget();
                    objectTargetSpec = "target";

                    // .. but we need to decide whether this authorization is applicable to the object
                    if (isApplicable(autz.getObject(), object, principal, null, "object", autzHumanReadableDesc,
                            task, result)) {
                        LOGGER.trace("    Authorization is applicable for object {}", object);
                    } else {
                        LOGGER.trace("    Authorization is not applicable for object {}", object);
                        continue;
                    }
                }

                boolean applicable = true;
                if (objectSpecTypes == null || objectSpecTypes.isEmpty()) {

                    LOGGER.trace(
                            "    No {} specification in authorization (authorization is universaly applicable)",
                            objectTargetSpec);
                    autzObjSecurityFilter = AllFilter.createAll();

                } else {

                    applicable = false;
                    for (OwnedObjectSelectorType objectSpecType : objectSpecTypes) {
                        ObjectFilter objSpecSecurityFilter = null;
                        TypeFilter objSpecTypeFilter = null;
                        SearchFilterType specFilterType = objectSpecType.getFilter();
                        ObjectReferenceType specOrgRef = objectSpecType.getOrgRef();
                        OrgRelationObjectSpecificationType specOrgRelation = objectSpecType.getOrgRelation();
                        RoleRelationObjectSpecificationType specRoleRelation = objectSpecType.getRoleRelation();
                        QName specTypeQName = objectSpecType.getType();
                        PrismObjectDefinition<T> objectDefinition = null;

                        // Type
                        if (specTypeQName != null) {
                            specTypeQName = prismContext.getSchemaRegistry().qualifyTypeName(specTypeQName);
                            PrismObjectDefinition<?> specObjectDef = prismContext.getSchemaRegistry()
                                    .findObjectDefinitionByType(specTypeQName);
                            if (specObjectDef == null) {
                                throw new SchemaException("Unknown object type " + specTypeQName + " in "
                                        + autzHumanReadableDesc);
                            }
                            Class<?> specObjectClass = specObjectDef.getCompileTimeClass();
                            if (!objectType.isAssignableFrom(specObjectClass)) {
                                LOGGER.trace(
                                        "    Authorization not applicable for object because of type mismatch, authorization {}, query {}",
                                        new Object[] { specObjectClass, objectType });
                                continue;
                            } else {
                                LOGGER.trace(
                                        "    Authorization is applicable for object because of type match, authorization {}, query {}",
                                        new Object[] { specObjectClass, objectType });
                                // The spec type is a subclass of requested type. So it might be returned from the search.
                                // We need to use type filter.
                                objSpecTypeFilter = TypeFilter.createType(specTypeQName, null);
                                // and now we have a more specific object definition to use later in filter processing
                                objectDefinition = (PrismObjectDefinition<T>) specObjectDef;
                            }
                        }

                        // Owner
                        if (objectSpecType.getOwner() != null) {
                            if (objectDefinition == null) {
                                objectDefinition = prismContext.getSchemaRegistry()
                                        .findObjectDefinitionByCompileTimeClass(objectType);
                            }
                            // TODO: MID-3899
                            if (AbstractRoleType.class.isAssignableFrom(objectType)) {
                                objSpecSecurityFilter = applyOwnerFilterOwnerRef(
                                        new ItemPath(AbstractRoleType.F_OWNER_REF), objSpecSecurityFilter,
                                        principal, objectDefinition);
                            } else if (TaskType.class.isAssignableFrom(objectType)) {
                                objSpecSecurityFilter = applyOwnerFilterOwnerRef(
                                        new ItemPath(TaskType.F_OWNER_REF), objSpecSecurityFilter, principal,
                                        objectDefinition);
                            } else {
                                LOGGER.trace(
                                        "    Authorization not applicable for object because it has owner specification (this is not applicable for search)");
                                continue;
                            }
                        }

                        //                     // Delegator
                        //                     if (objectSpecType.getDelegator() != null) {
                        //                        if (objectDefinition == null) {
                        //                           objectDefinition = prismContext.getSchemaRegistry().findObjectDefinitionByCompileTimeClass(objectType);
                        //                        }
                        //                        // TODO: MID-3899
                        //                        if (UserType.class.isAssignableFrom(objectType)) { TODO
                        //                           objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(AbstractRoleType.F_OWNER_REF), objSpecSecurityFilter,  principal, objectDefinition);
                        //                        } else if (TaskType.class.isAssignableFrom(objectType)) {
                        //                           objSpecSecurityFilter = applyOwnerFilterOwnerRef(new ItemPath(TaskType.F_OWNER_REF), objSpecSecurityFilter,  principal, objectDefinition);
                        //                        } else {
                        //                           LOGGER.trace("  Authorization not applicable for object because it has owner specification (this is not applicable for search)");
                        //                           continue;
                        //                        }
                        //                     }

                        applicable = true;

                        // Special
                        List<SpecialObjectSpecificationType> specSpecial = objectSpecType.getSpecial();
                        if (specSpecial != null && !specSpecial.isEmpty()) {
                            if (!includeSpecial) {
                                LOGGER.trace("    Skipping authorization, because specials are present: {}",
                                        specSpecial);
                                applicable = false;
                            }
                            if (specFilterType != null || specOrgRef != null || specOrgRelation != null
                                    || specRoleRelation != null) {
                                throw new SchemaException(
                                        "Both filter/org/role and special object specification specified in authorization");
                            }
                            ObjectFilter specialFilter = null;
                            for (SpecialObjectSpecificationType special : specSpecial) {
                                if (special == SpecialObjectSpecificationType.SELF) {
                                    String principalOid = principal.getOid();
                                    specialFilter = ObjectQueryUtil.filterOr(specialFilter,
                                            InOidFilter.createInOid(principalOid));
                                } else {
                                    throw new SchemaException(
                                            "Unsupported special object specification specified in authorization: "
                                                    + special);
                                }
                            }
                            objSpecSecurityFilter = specTypeQName != null
                                    ? TypeFilter.createType(specTypeQName, specialFilter)
                                    : specialFilter;
                        } else {
                            LOGGER.trace("    specials empty: {}", specSpecial);
                        }

                        // Filter
                        if (specFilterType != null) {
                            if (objectDefinition == null) {
                                objectDefinition = prismContext.getSchemaRegistry()
                                        .findObjectDefinitionByCompileTimeClass(objectType);
                            }
                            ObjectFilter specFilter = parseAndEvaluateFilter(principal, objectDefinition,
                                    specFilterType, objectTargetSpec, autzHumanReadableDesc, task, result);
                            if (specFilter != null) {
                                ObjectQueryUtil.assertNotRaw(specFilter,
                                        "Filter in authorization object has undefined items. Maybe a 'type' specification is missing in the authorization?");
                                ObjectQueryUtil.assertPropertyOnly(specFilter,
                                        "Filter in authorization object is not property-only filter");
                            }
                            LOGGER.trace("    applying property filter {}", specFilter);
                            objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter,
                                    specFilter);
                        } else {
                            LOGGER.trace("    filter empty");
                        }

                        // Org
                        if (specOrgRef != null) {
                            ObjectFilter orgFilter = QueryBuilder.queryFor(ObjectType.class, prismContext)
                                    .isChildOf(specOrgRef.getOid()).buildFilter();
                            objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter, orgFilter);
                            LOGGER.trace("    applying org filter {}", orgFilter);
                        } else {
                            LOGGER.trace("    org empty");
                        }

                        // orgRelation
                        if (specOrgRelation != null) {
                            ObjectFilter objSpecOrgRelationFilter = null;
                            QName subjectRelation = specOrgRelation.getSubjectRelation();
                            for (ObjectReferenceType subjectParentOrgRef : principal.getUser()
                                    .getParentOrgRef()) {
                                if (MiscSchemaUtil.compareRelation(subjectRelation,
                                        subjectParentOrgRef.getRelation())) {
                                    S_FilterEntryOrEmpty q = QueryBuilder.queryFor(ObjectType.class,
                                            prismContext);
                                    S_AtomicFilterExit q2;
                                    if (specOrgRelation.getScope() == null
                                            || specOrgRelation.getScope() == OrgScopeType.ALL_DESCENDANTS) {
                                        q2 = q.isChildOf(subjectParentOrgRef.getOid());
                                    } else if (specOrgRelation.getScope() == OrgScopeType.DIRECT_DESCENDANTS) {
                                        q2 = q.isDirectChildOf(subjectParentOrgRef.getOid());
                                    } else if (specOrgRelation.getScope() == OrgScopeType.ALL_ANCESTORS) {
                                        q2 = q.isParentOf(subjectParentOrgRef.getOid());
                                    } else {
                                        throw new UnsupportedOperationException(
                                                "Unknown orgRelation scope " + specOrgRelation.getScope());
                                    }
                                    if (BooleanUtils.isTrue(specOrgRelation.isIncludeReferenceOrg())) {
                                        q2 = q2.or().id(subjectParentOrgRef.getOid());
                                    }
                                    objSpecOrgRelationFilter = ObjectQueryUtil
                                            .filterOr(objSpecOrgRelationFilter, q2.buildFilter());
                                }
                            }
                            if (objSpecOrgRelationFilter == null) {
                                objSpecOrgRelationFilter = NoneFilter.createNone();
                            }
                            objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter,
                                    objSpecOrgRelationFilter);
                            LOGGER.trace("    applying orgRelation filter {}", objSpecOrgRelationFilter);
                        } else {
                            LOGGER.trace("    orgRelation empty");
                        }

                        // roleRelation
                        if (specRoleRelation != null) {
                            ObjectFilter objSpecRoleRelationFilter = processRoleRelationFilter(principal, autz,
                                    specRoleRelation, queryItemsSpec, origFilter);
                            if (objSpecRoleRelationFilter == null) {
                                if (autz.maySkipOnSearch()) {
                                    LOGGER.trace(
                                            "    not applying roleRelation filter {} because it is not efficient and maySkipOnSearch is set",
                                            objSpecRoleRelationFilter);
                                    applicable = false;
                                } else {
                                    objSpecRoleRelationFilter = NoneFilter.createNone();
                                }
                            }
                            if (objSpecRoleRelationFilter != null) {
                                objSpecSecurityFilter = ObjectQueryUtil.filterAnd(objSpecSecurityFilter,
                                        objSpecRoleRelationFilter);
                                LOGGER.trace("  applying roleRelation filter {}", objSpecRoleRelationFilter);
                            }
                        } else {
                            LOGGER.trace("    roleRelation empty");
                        }

                        if (objSpecTypeFilter != null) {
                            objSpecTypeFilter.setFilter(objSpecSecurityFilter);
                            objSpecSecurityFilter = objSpecTypeFilter;
                        }

                        traceFilter("objSpecSecurityFilter", objectSpecType, objSpecSecurityFilter);
                        autzObjSecurityFilter = ObjectQueryUtil.filterOr(autzObjSecurityFilter,
                                objSpecSecurityFilter);
                    }

                }

                traceFilter("autzObjSecurityFilter", autz, autzObjSecurityFilter);

                if (applicable) {
                    autzObjSecurityFilter = ObjectQueryUtil.simplify(autzObjSecurityFilter);
                    // authority is applicable to this situation. now we can process the decision.
                    AuthorizationDecisionType decision = autz.getDecision();
                    if (decision == null || decision == AuthorizationDecisionType.ALLOW) {
                        // allow
                        if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
                            // this is "allow all" authorization.
                            hasAllowAll = true;
                        } else {
                            securityFilterAllow = ObjectQueryUtil.filterOr(securityFilterAllow,
                                    autzObjSecurityFilter);
                        }
                        if (!ObjectQueryUtil.isNone(autzObjSecurityFilter)) {
                            queryItemsSpec.collectItems(autz);
                        }
                    } else {
                        // deny
                        if (autz.hasItemSpecification()) {
                            // This is a tricky situation. We have deny authorization, but it only denies access to
                            // some items. Therefore we need to find the objects and then filter out the items.
                            // Therefore do not add this authorization into the filter.
                        } else {
                            if (ObjectQueryUtil.isAll(autzObjSecurityFilter)) {
                                // This is "deny all". We cannot have anything stronger than that.
                                // There is no point in continuing the evaluation.
                                if (LOGGER.isTraceEnabled()) {
                                    LOGGER.trace("AUTZ {} done: principal={}, operation={}, phase={}: deny all",
                                            desc, getUsername(principal), prettyActionUrl(operationUrl), phase);
                                }
                                NoneFilter secFilter = NoneFilter.createNone();
                                traceFilter("secFilter", null, secFilter);
                                return secFilter;
                            }
                            securityFilterDeny = ObjectQueryUtil.filterOr(securityFilterDeny,
                                    autzObjSecurityFilter);
                        }
                    }
                }

                traceFilter("securityFilterAllow", autz, securityFilterAllow);
                traceFilter("securityFilterDeny", autz, securityFilterDeny);

            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(),
                        getUsername(principal));
            }
        }
    }

    traceFilter("securityFilterAllow", null, securityFilterAllow);
    traceFilter("securityFilterDeny", null, securityFilterDeny);

    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace(" Final items: {}", queryItemsSpec.shortDump());
    }
    List<ItemPath> unsatisfiedItems = queryItemsSpec.evaluateUnsatisfierItems();
    if (!unsatisfiedItems.isEmpty()) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace(
                    "AUTZ {} done: principal={}, operation={}, phase={}: deny because items {} are not allowed",
                    desc, getUsername(principal), prettyActionUrl(operationUrl), phase, unsatisfiedItems);
        }
        NoneFilter secFilter = NoneFilter.createNone();
        traceFilter("secFilter", null, secFilter);
        return secFilter;
    }

    ObjectFilter origWithAllowFilter;
    if (hasAllowAll) {
        origWithAllowFilter = origFilter;
    } else if (securityFilterAllow == null) {
        // Nothing has been allowed. This means default deny.
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("AUTZ {} done: principal={}, operation={}, phase={}: default deny", desc,
                    getUsername(principal), prettyActionUrl(operationUrl), phase);
        }
        NoneFilter secFilter = NoneFilter.createNone();
        traceFilter("secFilter", null, secFilter);
        return secFilter;
    } else {
        origWithAllowFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilterAllow);
    }

    if (securityFilterDeny == null) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("AUTZ {} done: principal={}, operation={}, phase={}: allow\n  Filter:\n{}", desc,
                    getUsername(principal), prettyActionUrl(operationUrl), phase,
                    origWithAllowFilter == null ? "null" : origWithAllowFilter.debugDump(2));
        }
        traceFilter("origWithAllowFilter", null, origWithAllowFilter);
        return origWithAllowFilter;
    } else {
        ObjectFilter secFilter = ObjectQueryUtil.filterAnd(origWithAllowFilter,
                NotFilter.createNot(securityFilterDeny));
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace(
                    "AUTZ {} done: principal={}, operation={}, phase={}: allow (with deny clauses)\n  Filter:\n{}",
                    desc, getUsername(principal), prettyActionUrl(operationUrl), phase,
                    secFilter == null ? "null" : secFilter.debugDump(2));
        }
        traceFilter("secFilter", null, secFilter);
        return secFilter;
    }
}