Search in sources :

Example 1 with AttributeFqn

use of org.ow2.authzforce.core.pdp.api.AttributeFqn in project core by authzforce.

the class SingleDecisionXacmlJsonRequestPreprocessor method process.

@Override
public List<IndividualXacmlJsonRequest> process(final JSONArray jsonArrayOfRequestAttributeCategoryObjects, final SingleCategoryXacmlAttributesParser<JSONObject> xacmlAttrsParser, final boolean isApplicablePolicyIdListReturned, final boolean combinedDecision, final Optional<XPathCompilerProxy> xPathCompiler, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException {
    final Map<AttributeFqn, AttributeBag<?>> namedAttributes = HashCollections.newUpdatableMap(jsonArrayOfRequestAttributeCategoryObjects.length());
    /*
		 * TODO: Content object not supported yet (optional in XACML)
		 */
    final Map<String, XdmNode> extraContentsByCategory = Collections.emptyMap();
    /*
		 * requestAttributeCategoryObjectsIncludedInResult.size() <= jsonArrayOfRequestAttributeCategoryObjects.size()
		 */
    final List<JSONObject> requestAttributeCategoryObjectsIncludedInResult = new ArrayList<>(jsonArrayOfRequestAttributeCategoryObjects.length());
    for (final Object requestAttributeCategoryObject : jsonArrayOfRequestAttributeCategoryObjects) {
        if (!(requestAttributeCategoryObject instanceof JSONObject)) {
            throw INVALID_REQUEST_CATEGORY_ARRAY_ELEMENT_TYPE_EXCEPTION;
        }
        final JSONObject requestAttCatJsonObj = (JSONObject) requestAttributeCategoryObject;
        final SingleCategoryAttributes<?, JSONObject> categorySpecificAttributes = xacmlAttrsParser.parseAttributes(requestAttCatJsonObj, xPathCompiler);
        if (categorySpecificAttributes == null) {
            // skip this empty Attributes
            continue;
        }
        /*
			 * Convert growable (therefore mutable) bag of attribute values to immutable ones. Indeed, we must guarantee that attribute values remain constant during the evaluation of the request, as
			 * mandated by the XACML spec, section 7.3.5: <p> <i>
			 * "Regardless of any dynamic modifications of the request context during policy evaluation, the PDP SHALL behave as if each bag of attribute values is fully populated in the context before it is first tested, and is thereafter immutable during evaluation. (That is, every subsequent test of that attribute shall use the same bag of values that was initially tested.)"
			 * </i></p>
			 */
        for (final Entry<AttributeFqn, AttributeBag<?>> attrEntry : categorySpecificAttributes) {
            namedAttributes.put(attrEntry.getKey(), attrEntry.getValue());
        }
        final JSONObject catSpecificAttrsToIncludeInResult = categorySpecificAttributes.getAttributesToIncludeInResult();
        if (catSpecificAttrsToIncludeInResult != null) {
            requestAttributeCategoryObjectsIncludedInResult.add(catSpecificAttrsToIncludeInResult);
        }
    }
    final ImmutableDecisionRequest pdpEngineReq = reqFactory.getInstance(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned);
    return Collections.singletonList(new IndividualXacmlJsonRequest(pdpEngineReq, ImmutableList.copyOf(requestAttributeCategoryObjectsIncludedInResult)));
}
Also used : XdmNode(net.sf.saxon.s9api.XdmNode) JSONObject(org.json.JSONObject) JSONObject(org.json.JSONObject) AttributeBag(org.ow2.authzforce.core.pdp.api.value.AttributeBag)

Example 2 with AttributeFqn

use of org.ow2.authzforce.core.pdp.api.AttributeFqn in project core by authzforce.

the class SingleDecisionXacmlJaxbRequestPreprocessor method process.

@Override
public List<IndividualXacmlJaxbRequest> process(final List<Attributes> attributesList, final SingleCategoryXacmlAttributesParser<Attributes> xacmlAttrsParser, final boolean isApplicablePolicyIdListReturned, final boolean combinedDecision, final Optional<XPathCompilerProxy> xPathCompiler, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException {
    final Map<AttributeFqn, AttributeBag<?>> namedAttributes = HashCollections.newUpdatableMap(attributesList.size());
    final Map<String, XdmNode> extraContentsByCategory = HashCollections.newUpdatableMap(attributesList.size());
    /*
		 * attributesToIncludeInResult.size() <= attributesList.size()
		 */
    final List<Attributes> attributesToIncludeInResult = new ArrayList<>(attributesList.size());
    for (final Attributes jaxbAttributes : attributesList) {
        final SingleCategoryAttributes<?, Attributes> categorySpecificAttributes = xacmlAttrsParser.parseAttributes(jaxbAttributes, xPathCompiler);
        if (categorySpecificAttributes == null) {
            // skip this empty Attributes
            continue;
        }
        final String categoryId = categorySpecificAttributes.getCategoryId();
        final XdmNode newContentNode = categorySpecificAttributes.getExtraContent();
        if (newContentNode != null) {
            final XdmNode duplicate = extraContentsByCategory.putIfAbsent(categoryId, newContentNode);
            /*
				 * No support for Multiple Decision Profile -> no support for repeated categories as specified in Multiple Decision Profile. So we must check duplicate attribute categories.
				 */
            if (duplicate != null) {
                throw new IndeterminateEvaluationException("Unsupported repetition of Attributes[@Category='" + categoryId + "'] (feature 'urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories' is not supported)", XacmlStatusCode.SYNTAX_ERROR.value());
            }
        }
        /*
			 * Convert growable (therefore mutable) bag of attribute values to immutable ones. Indeed, we must guarantee that attribute values remain constant during the evaluation of the request, as
			 * mandated by the XACML spec, section 7.3.5: <p> <i>
			 * "Regardless of any dynamic modifications of the request context during policy evaluation, the PDP SHALL behave as if each bag of attribute values is fully populated in the context before it is first tested, and is thereafter immutable during evaluation. (That is, every subsequent test of that attribute shall use the same bag of values that was initially tested.)"
			 * </i></p>
			 */
        for (final Entry<AttributeFqn, AttributeBag<?>> attrEntry : categorySpecificAttributes) {
            namedAttributes.put(attrEntry.getKey(), attrEntry.getValue());
        }
        final Attributes catSpecificAttrsToIncludeInResult = categorySpecificAttributes.getAttributesToIncludeInResult();
        if (catSpecificAttrsToIncludeInResult != null) {
            attributesToIncludeInResult.add(catSpecificAttrsToIncludeInResult);
        }
    }
    return Collections.singletonList(new IndividualXacmlJaxbRequest(reqFactory.getInstance(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned), ImmutableList.copyOf(attributesToIncludeInResult)));
}
Also used : SingleCategoryAttributes(org.ow2.authzforce.core.pdp.api.io.SingleCategoryAttributes) Attributes(oasis.names.tc.xacml._3_0.core.schema.wd_17.Attributes) XdmNode(net.sf.saxon.s9api.XdmNode) IndividualXacmlJaxbRequest(org.ow2.authzforce.core.pdp.api.io.IndividualXacmlJaxbRequest) AttributeBag(org.ow2.authzforce.core.pdp.api.value.AttributeBag)

Example 3 with AttributeFqn

use of org.ow2.authzforce.core.pdp.api.AttributeFqn in project core-pdp-api by authzforce.

the class LaxXacmlAttributeParser method updateAttributeMap.

private <AV extends AttributeValue> void updateAttributeMap(final Map<AttributeFqn, MutableAttributeBag<?>> attributeMap, final NamedXacmlAttributeParsingResult<AV> attributeParsingResult) {
    assert attributeMap != null && attributeParsingResult != null;
    /*
		 * Input AttributeValues have now been validated. Let's check any existing values for the same attrGUID (<Attribute> with same meta-data) in the map. As discussed on the xacml-dev mailing
		 * list (see https://lists.oasis-open.org/archives/xacml-dev/201507/msg00001.html), the XACML 3.0 core spec, §7.3.3, indicates that multiple occurrences of the same <Attribute> with same
		 * meta-data but different values should be considered equivalent to a single <Attribute> element with same meta-data and merged values (multi-valued Attribute). Moreover, the conformance
		 * test 'IIIA024' expects this behavior: the multiple subject-id Attributes are expected to result in a multi-value bag during evaluation of the AttributeDesignator.
		 * 
		 * Therefore, we choose to merge the attribute values here if this is a new occurrence of the same Attribute, i.e. attrMap.get(attrGUID) != null. In this case, we can reuse the list
		 * already created for the previous occurrence to store the new values resulting from parsing.
		 */
    final AttributeFqn attributeName = attributeParsingResult.getAttributeName();
    final Datatype<AV> attributeDatatype = attributeParsingResult.getAttributeDatatype();
    final MutableAttributeBag<?> previousAttrVals = attributeMap.get(attributeName);
    final MutableAttributeBag<AV> newAttrVals;
    if (previousAttrVals == null) {
        /*
			 * First occurrence of this attribute ID (attrGUID). Check whether this is not an unsupported resource-scope attribute.
			 */
        newAttrVals = new MutableAttributeBag<>(attributeDatatype, AttributeSources.REQUEST);
        validateResourceScope(attributeName, newAttrVals);
        attributeMap.put(attributeName, newAttrVals);
    } else {
        /*
			 * Collection of values already in the map for this Attribute id, reuse/update it directly
			 */
        if (!(previousAttrVals.getElementType().equals(attributeDatatype))) {
            throw new IllegalArgumentException("Invalid Attribute '" + attributeName + "': Values with different datatypes (" + previousAttrVals.getElementType() + ", " + attributeDatatype + ")");
        }
        newAttrVals = (MutableAttributeBag<AV>) previousAttrVals;
    }
    /*
		 * XACML 3.0, §5.29 says on <AttributeDesignator>: "If the Issuer is not present in the attribute designator, then the matching of the attribute to the named attribute SHALL be governed by
		 * AttributeId and DataType attributes alone." Therefore, if this attribute has an Issuer, we copy its values to the "Issuer- less" version for evaluating later any matching "Issuer-less"
		 * Attribute Designator.
		 */
    final Collection<AV> attParsingResultValues = attributeParsingResult.getAttributeValues();
    newAttrVals.addAll(attParsingResultValues);
    if (copyIssuedAttributeValuesToNonIssued(attributeName)) {
        final MutableAttributeBag<AV> newIssuerLessAttrVals;
        // attribute has an Issuer -> prepare to update the matching Issuer-less attribute values
        final AttributeFqn issuerLessId = AttributeFqns.newInstance(attributeName.getCategory(), Optional.empty(), attributeName.getId());
        final MutableAttributeBag<?> oldIssuerLessAttrVals = attributeMap.get(issuerLessId);
        if (oldIssuerLessAttrVals == null) {
            newIssuerLessAttrVals = new MutableAttributeBag<>(attributeDatatype, AttributeSources.REQUEST);
            attributeMap.put(issuerLessId, newIssuerLessAttrVals);
        } else {
            if (!(oldIssuerLessAttrVals.getElementType().equals(attributeDatatype))) {
                throw new IllegalArgumentException("Invalid Attribute '" + issuerLessId + "': Values with different datatypes (" + oldIssuerLessAttrVals.getElementType() + ", " + attributeDatatype + ")");
            }
            newIssuerLessAttrVals = (MutableAttributeBag<AV>) oldIssuerLessAttrVals;
        }
        newIssuerLessAttrVals.addAll(attParsingResultValues);
    }
}
Also used : AttributeFqn(org.ow2.authzforce.core.pdp.api.AttributeFqn)

Example 4 with AttributeFqn

use of org.ow2.authzforce.core.pdp.api.AttributeFqn in project core-pdp-api by authzforce.

the class NonIssuedLikeIssuedStrictXacmlAttributeParser method parseNamedAttribute.

/**
 * "Strict" parsing method, that parse all the values of a given attribute in one call. In short, this method will reject multiple calls on the same Attribute identifier (same metadata).
 *
 * @param attributeMap
 *            request attribute map to be updated by the result of parsing {@code inputXacmlAttribute}
 * @param inputXacmlAttribute
 *            input attribute object (not yet parsed into AuthzForce internal model), typically from original XACML request
 * @param xPathCompiler
 *            XPath compiler for compiling/evaluating XPath expressions in values, such as XACML xpathExpressions. Undefined if XPath support disabled.
 *
 * @throws IllegalArgumentException
 *             if parsing of the {@code inputXacmlAttribute} because of invalid datatype or mixing of different datatypes; or if there are already existing values for the same attribute
 *             (repetition of same attribute is not allowed in strict mode)
 */
@Override
public void parseNamedAttribute(final String attributeCategoryId, final INPUT_ATTRIBUTE inputXacmlAttribute, final Optional<XPathCompilerProxy> xPathCompiler, final Map<AttributeFqn, AttributeBag<?>> attributeMap) throws IllegalArgumentException {
    final NamedXacmlAttributeParsingResult<?> attParsingResult = parseNamedAttribute(attributeCategoryId, inputXacmlAttribute, xPathCompiler);
    final AttributeBag<?> attBag = newAttributeBag(attParsingResult);
    /*
		 * If there is any existing values for the same attribute name (<Attribute> with same meta-data) in the map, it will be rejected. This behavior is not fully compliant with XACML (see the
		 * Javadoc of this class), however it is faster than the compliant alternative.
		 */
    final AttributeFqn attName = attParsingResult.getAttributeName();
    final Bag<?> duplicate = attributeMap.putIfAbsent(attName, attBag);
    if (duplicate != null) {
        throw new IllegalArgumentException("Illegal syntax in strict mode: duplicate <Attribute> with metadata: " + attParsingResult.getAttributeName());
    }
    /*
		 * Check if it is a resource-scope.
		 */
    validateResourceScope(attName, attBag);
/*
		 * In this implementation, we do not comply fully with XACML 3.0, §5.29, since we handle Attribute(s) without Issuer exactly like the ones with an Issuer. In other words, an undefined issuer
		 * is handled like the special "null" Issuer. Therefore, an AttributeDesignators without Issuer will not match the request attributes with matching Category, AttributeId... but a defined
		 * therefore different Issuer. It will only match the request attribute without Issuer. In a compliant implementation, we would check if the attribute has an Issuer, and if it does, also
		 * update the attribute variant with same meta-data except no Issuer.
		 */
}
Also used : AttributeFqn(org.ow2.authzforce.core.pdp.api.AttributeFqn)

Example 5 with AttributeFqn

use of org.ow2.authzforce.core.pdp.api.AttributeFqn in project core-pdp-api by authzforce.

the class XacmlRequestAttributeParser method validateResourceScope.

/**
 * Validates the 'scope' attribute as defined in Multiple Decision Profile (§2.1 and §5)
 *
 * @param attributeFQN
 *            attribute name
 * @param attributeValues
 *            attribute values
 * @throws IllegalArgumentException
 *             if the values are not actually the singleton string "Immediate" (other values are not supported)
 */
protected static void validateResourceScope(final AttributeFqn attributeFQN, final Iterable<? extends AttributeValue> attributeValues) throws IllegalArgumentException {
    assert attributeFQN != null && attributeValues != null;
    /*
		 * Check whether this is not an unsupported resource-scope attribute. XACML Multiple Decision Profile, § 2.3.3: "... If such a <Attributes> element contains a 'scope' attribute having any
		 * value other than 'Immediate', then the Individual Request SHALL be further processed according to the processing model specified in Section 4." We do not support 'scope' other than
		 * 'Immediate' so throw an error if different.
		 */
    if (!attributeFQN.equals(RESOURCE_SCOPE_ATTRIBUTE_GUID)) {
        return;
    }
    final Iterator<? extends AttributeValue> valIterator = attributeValues.iterator();
    if (!valIterator.hasNext()) {
        throw INVALID_MULTIPLE_SCOPE_VALUE_EXCEPTION;
    }
    final AttributeValue val = valIterator.next();
    if (!IMMEDIATE_RESOURCE_SCOPE_ATTRIBUTE_VALUE.equals(val)) {
        throw UNSUPPORTED_MULTIPLE_SCOPE_VALUE_EXCEPTION;
    }
    if (valIterator.hasNext()) {
        throw INVALID_MULTIPLE_SCOPE_VALUE_EXCEPTION;
    }
}
Also used : AttributeValue(org.ow2.authzforce.core.pdp.api.value.AttributeValue)

Aggregations

XdmNode (net.sf.saxon.s9api.XdmNode)2 AttributeFqn (org.ow2.authzforce.core.pdp.api.AttributeFqn)2 AttributeBag (org.ow2.authzforce.core.pdp.api.value.AttributeBag)2 Attributes (oasis.names.tc.xacml._3_0.core.schema.wd_17.Attributes)1 JSONObject (org.json.JSONObject)1 IndividualXacmlJaxbRequest (org.ow2.authzforce.core.pdp.api.io.IndividualXacmlJaxbRequest)1 SingleCategoryAttributes (org.ow2.authzforce.core.pdp.api.io.SingleCategoryAttributes)1 AttributeValue (org.ow2.authzforce.core.pdp.api.value.AttributeValue)1