Commit 5f9c3bec authored by cdanger's avatar cdanger

Improved Getting started section

parent 62c595fc
......@@ -63,16 +63,24 @@ See the [change log](CHANGELOG.md) following the *Keep a CHANGELOG* [conventions
## License
See the [license file](LICENSE).
## System requirements
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`
## Usage
### Getting started
#### CLI
Get the latest executable jar from Maven Central: groupId/artifactId = `org.ow2.authzforce`/`authzforce-ce-core-pdp-cli`.
Copy the content of [that folder](pdp-cli/src/test/resources/conformance/xacml-3.0-core/mandatory) to the same directory, and run the executable as follows:
```
$ ./authzforce-ce-core-pdp-cli-10.0.0.jar pdp.xml request.xml
```
* `pdp.xml`: PDP configuration file;
* `pdp.xml`: PDP configuration file, that defines the location(s) of XACML policy(ies), among other PDP engine parameters; this content of this file is a XML document compliant with the PDP configuration [XML schema](pdp-engine/src/main/resources/pdp.xsd), so you can read the documentation of every configuration parameter in that schema file;
* `request.xml`: XACML request in XACML 3.0/XML (core specification) format.
If you want to test the JSON Profile of XACML 3.0, run it with extra option `-t XACML_JSON`:
......@@ -84,19 +92,27 @@ $ ./authzforce-ce-core-pdp-cli-10.0.0.jar -t XACML_JSON pdp.xml request.json
For more info, run it without parameters and you'll get detailed information on usage.
#### Java API
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:
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:
* groupId: `org.ow2.authzforce`;
* artifactId: `authzforce-ce-core-pdp-engine`;
* packaging: `jar`.
If you want to use the experimental features (see previous section) as well, you need to use an extra Maven dependency:
* groupId: `org.ow2.authzforce`;
* artifactId: `authzforce-ce-core-pdp-testutils`;
* packaging: `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`
```xml
...
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>10.2.0</version>
</dependency>
...
```
To get started using a PDP to evaluate XACML requests, instantiate a new PDP engine configuration with one of the methods: `PdpEngineConfiguration#getInstance(...)`. The parameters are:
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](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html) for the syntax. For a basic example, see [this one](pdp-testutils/src/test/resources/conformance/xacml-3.0-from-2.0-ct/mandatory/IIA001/IIA001Policy.xml).
1. *confLocation*: location of the configuration file (mandatory): this file must be an XML document compliant with the PDP configuration [XML schema](pdp-engine/src/main/resources/pdp.xsd). You can read the documentation of every configuration parameter in that file. If you don't use any XML-schema-defined PDP extension (AttributeProviders, PolicyProviders...), this is the only parameter you need. Here is an example of configuration:
Then instantiate a PDP engine configuration with method [PdpEngineConfiguration#getInstance(String)](pdp-engine/src/main/java/org/ow2/authzforce/core/pdp/impl/PdpEngineConfiguration.java#L663). 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](pdp-engine/src/main/resources/pdp.xsd). This schema defines every configuration parameter with associated documentation. Here is a minimal example of configuration:
```xml
<?xml version="1.0" encoding="UTF-8"?>
......@@ -104,15 +120,74 @@ To get started using a PDP to evaluate XACML requests, instantiate a new PDP eng
<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 Policy document) loaded from a file `policy.xml` (see [this one](pdp-testutils/src/test/resources/conformance/xacml-3.0-from-2.0-ct/mandatory/IIA001/IIA001Policy.xml) for an example) located in the same directory as this PDP configuration file.
1. *catalogLocation*: location of the XML catalog (optional, required only if using one or more XML-schema-defined PDP extensions): used to resolve the PDP configuration schema and other imported schemas/DTDs, and schemas of any PDP extension namespace used in the configuration file. You may use the [catalog](pdp-engine/src/main/resources/catalog.xml) in the sources as an example. This is the one used by default if none specified.
1. *extensionXsdLocation*: location of the PDP extensions schema file (optional, required only if using one or more XML-schema-defined PDP extensions): contains imports of namespaces corresponding to XML schemas of all XML-schema-defined PDP extensions to be used in the configuration file. Used for validation of PDP extensions configuration. The actual schema locations are resolved by the XML catalog parameter. You may use the [pdp-ext.xsd](pdp-testutils/src/test/resources/pdp-ext.xsd) in the sources as an example.
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 `getInstance(...)`, you get an instance of `PdpEngineConfiguration`. Then the next step depends on the kind of decision request you want to evaluate. The various alternatives are detailed in the next sections.
As a result of calling method `getInstance(...)`, you get a `PdpEngineConfiguration` object. Basic example of Java code using a PDP configuration file at the root of the classpath:
```java
final PdpEngineConfiguration pdpEngineConf = PdpEngineConfiguration.getInstance("classpath: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.
##### Evaluating Requests in AuthzForce native API (most efficient)
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(...)`. Please look at the Javadoc for more information.
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):
```java
...
/*
* Create the PDP engine. You can reuse the same for all requests, so do it only once and for all.
*/
final BasePdpEngine pdp = new BasePdpEngine(pdpEngineConf);
...
// For every request...
// 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, 7 total attributes
*/
// final DecisionRequestBuilder<?> requestBuilder = pdp.newRequestBuilder(3, 7);
// 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)
...s
}
```
See [EmbeddedPdpBasedAuthzInterceptor#createRequest(...) method](pdp-testutils/src/test/java/org/ow2/authzforce/core/pdp/testutil/test/pep/cxf/EmbeddedPdpBasedAuthzInterceptor.java#L158) for a more detailed example. Please look at the Javadoc for the full details.
##### Evaluating Requests in XACML/XML format
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.
......@@ -127,16 +202,23 @@ You will need an extra dependency as well, available from Maven Central:
##### Logging
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](pdp-testutils/src/test/resources/logback.xml), for configuring loggers, appenders, etc.
##### Java 8+ external schema access restriction (workaround)
If you are using **Java 8** or later, make sure the following JVM argument is set before execution:
`-Djavax.xml.accessExternalSchema=http`
### Example of usage in a web service PEP
For an example of using an AuthzForce PDP engine in a real-life use case, please refer to the JUnit test class [EmbeddedPdpBasedAuthzInterceptorTest](pdp-testutils/src/test/java/org/ow2/authzforce/core/pdp/testutil/test/pep/cxf/EmbeddedPdpBasedAuthzInterceptorTest.java) and the Apache CXF authorization interceptor [EmbeddedPdpBasedAuthzInterceptor](pdp-testutils/src/test/java/org/ow2/authzforce/core/pdp/testutil/test/pep/cxf/EmbeddedPdpBasedAuthzInterceptor.java). The test class runs a test similar to @coheigea's [XACML 3.0 Authorization Interceptor test](https://github.com/coheigea/testcases/blob/master/apache/cxf/cxf-sts-xacml/src/test/java/org/apache/coheigea/cxf/sts/xacml/authorization/xacml3/XACML3AuthorizationTest.java) 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](pdp-testutils/src/test/java/org/ow2/authzforce/core/pdp/testutil/test/pep/cxf/EmbeddedPdpBasedAuthzInterceptor.java) 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](pdp-testutils/src/test/java/org/ow2/authzforce/core/pdp/testutil/test/pep/cxf/EmbeddedPdpBasedAuthzInterceptorTest.java).
## Extensions
If you are missing features in AuthzForce, you can extend it with various types of plugins (without changing the existing code), as described on the [wiki](../../wiki/Extensions).
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:
* groupId: `org.ow2.authzforce`;
* artifactId: `authzforce-ce-core-pdp-testutils`;
* packaging: `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](../../wiki/Extensions).
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:
1. *catalogLocation*: location of the XML catalog: used to resolve the PDP configuration schema and other imported schemas/DTDs, and schemas of any PDP extension namespace used in the configuration file. You may use the [catalog](pdp-engine/src/main/resources/catalog.xml) in the sources as an example. This is the one used by default if none specified.
1. *extensionXsdLocation*: location of the PDP extensions schema file: contains imports of namespaces corresponding to XML schemas of all XML-schema-defined PDP extensions to be used in the configuration file. Used for validation of PDP extensions configuration. The actual schema locations are resolved by the XML catalog parameter. You may use the [pdp-ext.xsd](pdp-testutils/src/test/resources/pdp-ext.xsd) in the sources as an example.
## Support
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment