Javadocs: PDP engine , XACML/JSON extension , Test utilities
Authorization PDP (Policy Decision Point) engine implementing the OASIS XACML v3.0.
AuthzForce Core may be used in the following ways:
HTTP/REST API: if you are interested in using a HTTP/REST API compliant with REST Profile of XACML 3.0, check the AuthzForce RESTful PDP project and AuthzForce server project.
Compliance with the following OASIS XACML 3.0 standards:
urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories
).dnsName-value
datatype and dnsName-value-equal
function are supported;on-permit-apply-second
policy combining algorithm;urn:oasis:names:tc:xacml:3.0:profile:multiple:combined-decision
). For further details on what is actually supported with regards to the XACML specifications, please refer to the conformance tests README.
Interfaces:
HTTP/REST API compliant with REST Profile of XACML 3.0 is provided by AuthzForce RESTful PDP project for PDP only, and AuthzForce server project for PDP and PAP with multi-tenancy.
AttributeValue
elements in the same Attribute element (instead of duplicate Attribute elements); this does not fully comply with XACML 3.0 Core specification of Multivalued attributes (§7.3.3), but it usually performs better than the default mode since it simplifies the parsing of attribute values in the request.AttributeDesignators
without Issuer only match request Attributes without Issuer (and same AttributeId, Category...); this option is not fully compliant with XACML 3.0, §5.29, in the case that the Issuer is indeed not present on a AttributeDesignator; but it is the recommended option when all AttributeDesignators have an Issuer (the XACML 3.0 specification (5.29) says: 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.);PolicyIdReference
or PolicySetIdReference
;The following optional features from XACML v3.0 Core standard are not supported:
AttributesReferences
, MultiRequests
and RequestReference
;urn:oasis:names:tc:xacml:3.0:function:xpath-node-equal
, urn:oasis:names:tc:xacml:3.0:function:xpath-node-match
and urn:oasis:names:tc:xacml:3.0:function:access-permitted
;If you are interested in those, you can ask for support.
See the change log following the Keep a CHANGELOG conventions.
See the license file.
Java (JRE) 8 or later.
Make sure the value - comma-separated list - of the system property javax.xml.accessExternalSchema
is set to include http
, to work around Java 8+ external schema access restriction, e.g. with a JVM argument:
-Djavax.xml.accessExternalSchema=http
Get the latest executable jar from Maven Central with groupId/artifactId = org.ow2.authzforce
/authzforce-ce-core-pdp-cli
and make sure you are allowed to run it (it is a fully executable JAR), e.g. with command:
$ chmod a+x authzforce-ce-core-pdp-cli-13.0.0.jar
To give you an example on how to test a XACML Policy (or PolicySet) and Request, you may copy the content of that folder to the same directory as the executable, and run the executable as follows:
$ ./authzforce-ce-core-pdp-cli-13.0.0.jar pdp.xml IIA001/Request.xml
pdp.xml
: PDP configuration file, that defines the location(s) of XACML policy(ies), among other PDP engine parameters; the content of this file is a XML document compliant with the PDP configuration XML schema, so you can read the documentation of every configuration parameter in that schema file; Feel free to change the policy location to point to your own for testing.Request.xml
: XACML request in XACML 3.0/XML (core specification) format. Feel free to replace with your own for testing.If you want to test the JSON Profile of XACML 3.0, run it with extra option -t XACML_JSON
:
$ ./authzforce-ce-core-pdp-cli-13.0.0.jar -t XACML_JSON pdp.xml IIA001/Request.json
Request.json
: XACML request in XACML 3.0/JSON (Profile) format. Feel free to replace with your own for testing.For more info, run it without parameters and you'll get detailed information on usage.
You can either build AuthzForce PDP library from the source code after cloning this git repository, or use the latest release from Maven Central with this information:
org.ow2.authzforce
;authzforce-ce-core-pdp-engine
;jar
.Since this is a Maven artifact and it requires dependencies, you should build your application with a build tool that understands Maven dependencies (e.g. Maven or Gradle), and configure this artifact as a Maven dependency, for instance with Maven in the pom.xml
:
...
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>13.0.0</version>
</dependency>
...
To get started using a PDP to evaluate XACML requests, the first step is to write/get a XACML 3.0 policy. Please refer to XACML v3.0 - Core standard for the syntax. For a basic example, see this one.
Then instantiate a PDP engine configuration with method PdpEngineConfiguration#getInstance(String). The required parameter confLocation must be the location of the PDP configuration file. The content of such file is a XML document compliant with the PDP configuration XML schema. This schema defines every configuration parameter with associated documentation. Here is a minimal example of configuration:
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0" version="6.0.0">
<rootPolicyProvider id="rootPolicyProvider" xsi:type="StaticRootPolicyProvider" policyLocation="${PARENT_DIR}/policy.xml" />
</pdp>
This is a basic PDP configuration with basic settings and the root policy (XACML 3.0 Policy document) loaded from a file policy.xml
located in the same directory as this PDP configuration file (see previous paragraph for an example of policy).
As a result of calling method getInstance(...)
, you get a PdpEngineConfiguration
object. Basic example of Java code using a PDP configuration file in some folder /opt/authzforce
:
final PdpEngineConfiguration pdpEngineConf = PdpEngineConfiguration.getInstance("file:///opt/authzforce/pdp.xml");
Then the next step depends on the kind of decision request you want to evaluate. The various alternatives are detailed in the next sections.
If you are creating decision requests internally, i.e. directly from your Java code (not from any data serialization format), you'd better use AuthzForce native interface.
You can pass the PdpEngineConfiguration
to BasePdpEngine(PdpEngineConfiguration)
constructor in order to instantiate a PDP engine. With this, you can evaluate a decision request (more precisely an equivalent of a Individual Decision Request as defined by the XACML Multiple Decision Profile) in AuthzForce's native model by calling evaluate(DecisionRequest)
or (multiple decision requests with evaluate(List)
). In order to build a DecisionRequest
, you may use the request builder returned by BasePdpEngine#newRequestBuilder(...)
.
Basic example of Java code (based on previous line of code):
...
/*
* Create the PDP engine. You can reuse the same for all requests, so do it only once for all.
*/
final BasePdpEngine pdp = new BasePdpEngine(pdpEngineConf);
...
// Create the XACML request in native model
final DecisionRequestBuilder<?> requestBuilder = pdp.newRequestBuilder(-1, -1);
/*
* If you care about memory optimization (avoid useless memory allocation), make sure you know the (expected) number of XACML attribute categories and (expected) total number of attributes in the request, and use these as arguments to newRequestBuilder(int,int) method, instead of negative values like above.
* e.g. 3 attribute categories, 4 total attributes in this case
*/
// final DecisionRequestBuilder<?> requestBuilder = pdp.newRequestBuilder(3, 4);
// Add subject ID attribute (access-subject category), no issuer, string value "john"
final AttributeFqn subjectIdAttributeId = AttributeFqns.newInstance(XACML_1_0_ACCESS_SUBJECT.value(), Optional.empty(), XacmlAttributeId.XACML_1_0_SUBJECT_ID.value());
final AttributeBag<?> subjectIdAttributeValues = Bags.singletonAttributeBag(StandardDatatypes.STRING, new StringValue("john"));
requestBuilder.putNamedAttributeIfAbsent(subjectIdAttributeId, subjectIdAttributeValues);
// Add subject role(s) attribute to access-subject category, no issuer, string value "boss"
final AttributeFqn subjectRoleAttributeId = AttributeFqns.newInstance(XACML_1_0_ACCESS_SUBJECT.value(), Optional.empty(), XacmlAttributeId.XACML_2_0_SUBJECT_ROLE.value());
final AttributeBag<?> roleAttributeValues = Bags.singletonAttributeBag(StandardDatatypes.STRING, new StringValue("boss"));
requestBuilder.putNamedAttributeIfAbsent(subjectRoleAttributeId, roleAttributeValues);
// Add resource ID attribute (resource category), no issuer, string value "/some/resource/location"
final AttributeFqn resourceIdAttributeId = AttributeFqns.newInstance(XACML_3_0_RESOURCE.value(), Optional.empty(), XacmlAttributeId.XACML_1_0_RESOURCE_ID.value());
final AttributeBag<?> resourceIdAttributeValues = Bags.singletonAttributeBag(StandardDatatypes.STRING, new StringValue("/some/resource/location"));
requestBuilder.putNamedAttributeIfAbsent(resourceIdAttributeId, resourceIdAttributeValues);
// Add action ID attribute (action category), no issuer, string value "GET"
final AttributeFqn actionIdAttributeId = AttributeFqns.newInstance(XACML_3_0_ACTION.value(), Optional.empty(), XacmlAttributeId.XACML_1_0_ACTION_ID.value());
final AttributeBag<?> actionIdAttributeValues = Bags.singletonAttributeBag(StandardDatatypes.STRING, new StringValue("GET"));
requestBuilder.putNamedAttributeIfAbsent(actionIdAttributeId, actionIdAttributeValues);
// No more attribute, let's finalize the request creation
final DecisionRequest request = requestBuilder.build(false);
// Evaluate the request
final DecisionResult result = pdp.evaluate(request);
if(result.getDecision() == DecisionType.PERMIT) {
// This is a Permit :-)
...
} else {
// Not a Permit :-( (maybe Deny, NotApplicable or Indeterminate)
...
}
See EmbeddedPdpBasedAuthzInterceptor#createRequest(...) method for a more detailed example. Please look at the Javadoc for the full details.
You can pass the PdpEngineConfiguration
to PdpEngineAdapters#newXacmlJaxbInoutAdapter(PdpEngineConfiguration)
utility method to instantiate a PDP supporting XACML 3.0/XML (core specification) format. You can evaluate such XACML Request by calling the evaluate(...)
methods.
To instantiate a PDP supporting XACML 3.0/JSON (JSON Profile) format, you may reuse the test code from PdpEngineXacmlJsonAdapters. You will need an extra dependency as well, available from Maven Central:
org.ow2.authzforce
;authzforce-ce-core-pdp-io-xacml-json
;jar
.Our PDP implementation uses SLF4J for logging so you can use any SLF4J implementation to manage logging. The CLI executable includes logback implementation, so you can use logback configuration file, e.g. logback.xml, for configuring loggers, appenders, etc.
For an example of using an AuthzForce PDP engine in a real-life use case, please refer to the JUnit test class EmbeddedPdpBasedAuthzInterceptorTest and the Apache CXF authorization interceptor EmbeddedPdpBasedAuthzInterceptor. The test class runs a test similar to @coheigea's XACML 3.0 Authorization Interceptor test but using AuthzForce as PDP engine instead of OpenAZ. In this test, a web service client requests a Apache-CXF-based web service with a SAML token as credentials (previously issued by a Security Token Service upon successful client authentication) that contains the user ID and roles. Each request is intercepted on the web service side by a EmbeddedPdpBasedAuthzInterceptor that plays the role of PEP (Policy Enforcement Point in XACML jargon), i.e. it extracts the various authorization attributes (user ID and roles, web service name, operation...) and requests a decision from a local PDP with these attributes, then enforces the PDP's decision, i.e. forwards the request to the web service implementation if the decision is Permit, else rejects it. For more information, see the Javadoc of EmbeddedPdpBasedAuthzInterceptorTest.
Experimental features (see Features section) are provided as extensions. If you want to use them, you need to use this Maven dependency (which depends on the authzforce-ce-core-pdp-engine
already) instead:
org.ow2.authzforce
;authzforce-ce-core-pdp-testutils
;jar
If you are still missing features in AuthzForce, you can make your own extensions/plugins (without changing the existing code), as described on the wiki.
If you are using the Java API with extensions configured by XML (Policy Providers, Attribute Providers...), you must use PdpEngineConfiguration#getInstance(String, String, String)
to instantiate the PDP engine, instead of PdpEngineConfiguration#getInstance(String)
mentioned previously. The two last extra parameters are mandatory in this case:
You should use AuthzForce users' mailing list as first contact for any communication about AuthzForce: question, feature request, notification, potential issue (unconfirmed), etc.
If you are experiencing any bug with this project and you indeed confirm this is not an issue with your environment (contact the users mailing list first if you are unsure), please report it on the OW2 Issue Tracker. Please include as much information as possible; the more we know, the better the chance of a quicker resolution:
If you want to report a vulnerability, you must do so on the OW2 Issue Tracker and make sure the checkbox This issue is confidential and should only be visible to team members with at least Reporter access is checked when creating the issue. Then, if the AuthzForce team can confirm it, they will uncheck it to make the issue public.
See CONTRIBUTING.md.