Search code examples
xacmlabacauthzforce

Authzforce ABAC - Fail to Enable a Result Postprocessor extension on a domain


I follow the instructions on link

1- Created the extension jar package from 'TestCombinedDecisionXacmlJaxbResultPostprocessor' class by replacing the type to 'urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default'

2- Placed the jar under /opt/authzforce-ce-server/webapp/WEB-INF/lib directory

3- Tried to enable the extension with:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pdpPropertiesUpdate xmlns="http://authzforce.github.io/rest-api-model/xmlns/authz/5">
 <feature 
 type="urn:ow2:authzforce:feature-type:pdp:result-postproc" 
 enabled="true">urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default</feature>
 <rootPolicyRefExpression>root</rootPolicyRefExpression>
</pdpPropertiesUpdate>

and got response:

<!doctype html><html lang="en"><head><title>HTTP Status 405 – Method Not Allowed</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;
} h1, h2, h3, b {color:white;background-color:#525D76;
} h1 {font-size: 22px;
} h2 {font-size: 16px;
} h3 {font-size: 14px;
} p {font-size: 12px;
} a {color:black;
} .line {height: 1px;background-color:#525D76;border:none;
}</style></head><body><h1>HTTP Status 405 – Method Not Allowed</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The method received in the request-line is known by the origin server but not supported by the target resource.</p><hr class="line" /><h3>Apache Tomcat/8.5.54 (Debian)</h3></body></html>

After this, I receive HTTP-404 for all the requests on domain. Can you suggest what I am missing? What is the rootcause for that issue?

Sharing the source code for the extension package:

public class PostprocessorLoader extends BaseXacmlJaxbResultPostprocessor  {
    private static final Set<String> FEATURES = ImmutableSet.of(DecisionResultPostprocessor.Features.XACML_MULTIPLE_DECISION_PROFILE_COMBINED_DECISION);
    private static final Response SIMPLE_INDETERMINATE_RESPONSE = new Response(
            Collections.singletonList(new Result(DecisionType.INDETERMINATE, new StatusHelper(XacmlStatusCode.PROCESSING_ERROR.value(), Optional.<String>empty()), null, null, null, null)));
    // private static final List<Result> INDETERMINATE_RESULT_SINGLETON_LIST_BECAUSE_NO_INDIVIDUAL = Collections.singletonList(new Result(DecisionType.INDETERMINATE, new StatusHelper(
    // StatusHelper.STATUS_PROCESSING_ERROR, "No <Result> to combine!"), null, null, null, null));
    private static final Response SIMPLE_PERMIT_RESPONSE = new Response(Collections.singletonList(new Result(DecisionType.PERMIT, StatusHelper.OK, null, null, null, null)));
    private static final Response SIMPLE_DENY_RESPONSE = new Response(Collections.singletonList(new Result(DecisionType.DENY, StatusHelper.OK, null, null, null, null)));
    private static final Response SIMPLE_NOT_APPLICABLE_RESPONSE = new Response(Collections.singletonList(new Result(DecisionType.NOT_APPLICABLE, StatusHelper.OK, null, null, null, null)));

    private PostprocessorLoader(final int clientRequestErrorVerbosityLevel) throws IllegalArgumentException {
        super(clientRequestErrorVerbosityLevel);
    }

    @Override
    public Set<String> getFeatures()
    {
        return FEATURES;
    }

    @Override
    public Response process(final Collection<Map.Entry<IndividualXacmlJaxbRequest, ? extends DecisionResult>> resultsByRequest)
    {
        System.out.println("#####################Inside process");
        if (resultsByRequest!=null){
            System.out.println(resultsByRequest.size());
        }else{
            System.out.println("#####################resultsByRequest is null!");
        }
        DecisionType combinedDecision = DecisionType.INDETERMINATE;
        for (final Map.Entry<? extends IndividualXacmlJaxbRequest, ? extends DecisionResult> resultEntry : resultsByRequest)
        {
            System.out.println("#####################resultEntry:"+resultEntry.getValue());
            final DecisionResult result = resultEntry.getValue();
            System.out.println("#####################getDecision:"+result.getDecision());
            if (result.getDecision() == DecisionType.INDETERMINATE)
            {
                // either all result must be indeterminate or we return Indeterminate as final result anyway
                return SIMPLE_INDETERMINATE_RESPONSE;
            }

            final ImmutableList<PepAction> pepActions = result.getPepActions();
            assert pepActions != null;

            if (!pepActions.isEmpty())
            {
                return SIMPLE_INDETERMINATE_RESPONSE;
            }

            final DecisionType individualDecision = result.getDecision();
            // if combinedDecision not initialized yet (indeterminate), set it to the result's decision
            if (combinedDecision == DecisionType.INDETERMINATE)
            {
                combinedDecision = individualDecision;
            } else
                // combinedDecision != Indeterminate
                if (individualDecision != combinedDecision)
                {
                    return SIMPLE_INDETERMINATE_RESPONSE;
                }
        }
        System.out.println("#####################Before CombinedDecision switch");
        try {
            System.out.printf("#####################process method!");
            //System.out.println(documentService.getIndividualHealthRoleByName("").toString());
        }catch(Exception ex){
            System.out.println("#####################process method err:"+ex.getCause());
        }

        switch (combinedDecision)
        {
            case PERMIT:
                return SIMPLE_PERMIT_RESPONSE;
            case DENY:
                return SIMPLE_DENY_RESPONSE;
            case NOT_APPLICABLE:
                return SIMPLE_NOT_APPLICABLE_RESPONSE;
            default:
                return SIMPLE_INDETERMINATE_RESPONSE;
        }
    }

    /**
     *
     * Factory for this type of result postprocessor filter that allows duplicate &lt;Attribute&gt; with same meta-data in the same &lt;Attributes&gt; element of a Request (complying with XACML 3.0
     * core spec, §7.3.3).
     *
     */
    public static final class Factory extends BaseXacmlJaxbResultPostprocessor.Factory
    {
        /**
         * ID of this {@link PdpExtension}
         */
        public static final String ID = "urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default";

        /**
         * Constructor
         */
        public Factory()
        {
            super(ID);
        }

        @Override
        public DecisionResultPostprocessor<IndividualXacmlJaxbRequest, Response> getInstance(final int clientRequestErrorVerbosityLevel)
        {
            return new PostprocessorLoader(clientRequestErrorVerbosityLevel);
        }

    }
}

NOTE: Same thing happened when I placed jar file from maven artifactId=authzforce-ce-core-pdp-testutils to lib folder and tried to enable with recommended request body in above-mentioned link.


Solution

  • You are trying to enable the postprocessor with ID urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default which is already reserved and provided by AuthzForce (for processing JSON response according to JSON Profile of XACML). Therefore, you can't use the same ID for your own implementation!

    So change the ID in your code (just an example here, choose your own):

    /**
      * ID of this {@link PdpExtension}
      */
    public static final String ID = "my-own-postproc-id";
    

    FYI, if all you need is the CombinedDecision feature for XACML/XML, as it seems so (but I may be wrong about what you are trying to achieve), this is already implemented by the class TestCombinedDecisionXacmlJaxbResultPostprocessor. You just have to deploy the authzforce-ce-core-pdp-testutils JAR in WEB-INF/lib (in same version as the authzforce-ce-core-pdp-engine JAR there), restart, and enable it like you did in step 3 but with the feature ID urn:ow2:authzforce:feature:pdp:result-postproc:xacml-xml:multiple:test-combined-decision.