authzforce/core

Dynamic PDP Configuration and Policy XML files using MongoDB

ihsanhaikalz opened this issue · 4 comments

I would like to implement a PDP engine using the authzforce-ce-core-pdp-engine jar file like you mentioned in the README, but with exception of the policy files in XML should be dynamic. The main idea is similar to file sharing system as one user could share multiple files to other user with each file may have different policy. I was thinking to store the policy files in some sort of DB like MySQL or MongoDB and PDP will refer to it and make a decision to grant or deny the access based on the request.

I found that the pdp core engine supports MongoDB as mentioned here.

Here is my pdp configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Testing parameter 'maxPolicySetRefDepth' -->
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0" xmlns:ext="http://authzforce.github.io/core/xmlns/test/3" version="6.0.0">
   <refPolicyProvider id="refPolicyProvider" xsi:type="ext:MongoDBBasedPolicyProvider" serverHost="localhost" serverPort="27017" dbName="testXACML" collectionName="policies" />
   <rootPolicyProvider id="rootPolicyProvider" xsi:type="StaticRefBasedRootPolicyProvider">
      <policyRef>root-rbac-policyset</policyRef>
   </rootPolicyProvider>
</pdp>

Here is the pdp extension scheme (pdp-ext.xsd):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
	<xs:annotation>
		<xs:documentation xml:lang="en">
			Import here the schema(s) of any XSD-defined PDP extension that you want to use in a PDP configuration: attribute finders, policy finders, etc.
			Indicate only the namespace here and use the XML catalog to resolve the schema location.
		</xs:documentation>
	</xs:annotation>
	<!-- Do not specify schema locations here. Define the schema locations in the XML catalog instead (see file 'catalog.xml'). -->
	<!--  Adding TestAttributeProvider extension -->
	<xs:import namespace="http://authzforce.github.io/core/xmlns/test/3" />
</xs:schema>

and the catalog file:

<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
	<!-- For AuthZForce SchemaHandler -->
	<system systemId="http://www.w3.org/2001/xml.xsd" uri="classpath:xml.xsd" />
	<uri name="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" uri="classpath:xacml-core-v3-schema-wd-17.xsd" />
	<uri name="http://authzforce.github.io/xmlns/pdp/ext/3" uri="classpath:pdp-ext-base.xsd" />

	<!-- PDP Extensions (<uri>'s 'name' attribute value must match the namespace indicated for the schema import 
		in the PDP extensions schema (pdp-ext.xsd), do not specify any schemaLocation in this schema, only the namespace. 
		-->
	<uri name="http://authzforce.github.io/core/xmlns/test/3" uri="classpath:org.ow2.authzforce.core.pdp.testutil.ext.xsd" />
</catalog>

My pom.xml looks like this:

		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.14.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.jongo/jongo -->
		<dependency>
			<groupId>org.jongo</groupId>
			<artifactId>jongo</artifactId>
			<version>1.3.0</version>
		</dependency>
		<dependency>
			<groupId>org.ow2.authzforce</groupId>
			<artifactId>authzforce-ce-core-pdp-engine</artifactId>
			<version>13.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.ow2.authzforce/authzforce-ce-core-pdp-io-xacml-json -->
		<dependency>
			<groupId>org.ow2.authzforce</groupId>
			<artifactId>authzforce-ce-core-pdp-io-xacml-json</artifactId>
			<version>13.0.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/de.undercouch/bson4jackson -->
		<dependency>
			<groupId>de.undercouch</groupId>
			<artifactId>bson4jackson</artifactId>
			<version>2.7.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.9.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.9.5</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.9.5</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.ow2.authzforce/authzforce-ce-core-pdp-testutils -->
		<dependency>
			<groupId>org.ow2.authzforce</groupId>
			<artifactId>authzforce-ce-core-pdp-testutils</artifactId>
			<version>13.0.0</version>
		</dependency>

All three configurations are then used to instantiate PdPEngineConfiguration as follow:

		File pdp2 = new File("pdp2.xml");
		File catalog = new File("catalog.xml");
		File xsd = new File("pdp-ext2.xsd");
		
		PdpEngineConfiguration pdpEngineConf = PdpEngineConfiguration.getInstance(pdp2.toURI().toString(), catalog.toURI().toString(), xsd.toURI().toString());
		final BasePdpEngine pdp = new BasePdpEngine(pdpEngineConf);

But this gave me error something like this:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.IllegalArgumentException: Invalid PDP configuration file
	at org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration.getInstance(PdpEngineConfiguration.java:469)
	at org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration.getInstance(PdpEngineConfiguration.java:516)
	at org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration.getInstance(PdpEngineConfiguration.java:548)
	at org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration.getInstance(PdpEngineConfiguration.java:682)
	at TestPDP.main(TestPDP.java:70)
Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of org.ow2.authzforce.xmlns.pdp.ext.AbstractPolicyProvider
 - with linked exception:
[java.lang.InstantiationException]
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:690)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:171)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:65)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:87)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
	at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:351)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:221)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:276)
	at org.ow2.authzforce.core.pdp.impl.PdpModelHandler.unmarshal(PdpModelHandler.java:185)
	at org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration.getInstance(PdpEngineConfiguration.java:466)
	... 4 more
Caused by: java.lang.InstantiationException
	at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.sun.xml.internal.bind.v2.ClassFactory.create0(ClassFactory.java:118)
	at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:270)
	at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:684)
	... 27 more

Did I do something wrong with this?

Also how can I store the policy XML files as it needs to be stored in JSON with MongoDB? I tried to convert XML to JSON using JSON maven dependency, but I have a problem of converting back to XML. For example with the policy XML file like this it will create the JSON file something like this:

{"Policy": {
    "xmlns": "urn:oasis:names:tc:xacml:3.0:core:schema:wd-17",
    "Target": "",
    "Description": "Policy for Conformance Test IIA001.",
    "Version": 1,
    "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
    "RuleCombiningAlgId": "urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides",
    "Rule": {
        "Target": {"AnyOf": [
            {"AllOf": {"Match": {
                "AttributeValue": {
                    "DataType": "http://www.w3.org/2001/XMLSchema#string",
                    "content": "Julius Hibbert"
                },
                "AttributeDesignator": {
                    "Category": "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject",
                    "AttributeId": "urn:oasis:names:tc:xacml:1.0:subject:subject-id",
                    "MustBePresent": false,
                    "DataType": "http://www.w3.org/2001/XMLSchema#string"
                },
                "MatchId": "urn:oasis:names:tc:xacml:1.0:function:string-equal"
            }}},
            {"AllOf": {"Match": {
                "AttributeValue": {
                    "DataType": "http://www.w3.org/2001/XMLSchema#anyURI",
                    "content": "http://medico.com/record/patient/BartSimpson"
                },
                "AttributeDesignator": {
                    "Category": "urn:oasis:names:tc:xacml:3.0:attribute-category:resource",
                    "AttributeId": "urn:oasis:names:tc:xacml:1.0:resource:resource-id",
                    "MustBePresent": false,
                    "DataType": "http://www.w3.org/2001/XMLSchema#anyURI"
                },
                "MatchId": "urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"
            }}},
            {"AllOf": [
                {"Match": {
                    "AttributeValue": {
                        "DataType": "http://www.w3.org/2001/XMLSchema#string",
                        "content": "read"
                    },
                    "AttributeDesignator": {
                        "Category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action",
                        "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id",
                        "MustBePresent": false,
                        "DataType": "http://www.w3.org/2001/XMLSchema#string"
                    },
                    "MatchId": "urn:oasis:names:tc:xacml:1.0:function:string-equal"
                }},
                {"Match": {
                    "AttributeValue": {
                        "DataType": "http://www.w3.org/2001/XMLSchema#string",
                        "content": "write"
                    },
                    "AttributeDesignator": {
                        "Category": "urn:oasis:names:tc:xacml:3.0:attribute-category:action",
                        "AttributeId": "urn:oasis:names:tc:xacml:1.0:action:action-id",
                        "MustBePresent": false,
                        "DataType": "http://www.w3.org/2001/XMLSchema#string"
                    },
                    "MatchId": "urn:oasis:names:tc:xacml:1.0:function:string-equal"
                }}
            ]}
        ]},
        "Description": "Julius Hibbert can read or write Bart Simpson's medical record.",
        "RuleId": "urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:rule",
        "Effect": "Permit"
    },
    "PolicyId": "urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:policy"
}}

but when I try to convert it back to XML it becomes entirely different XML file like this:

<Policy><xmlns>urn:oasis:names:tc:xacml:3.0:core:schema:wd-17</xmlns><Target/><Description>Policy for Conformance Test IIA001.</Description><Version>1</Version><xmlns:xsi>http://www.w3.org/2001/XMLSchema-instance</xmlns:xsi><RuleCombiningAlgId>urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides</RuleCombiningAlgId><Rule><Target><AnyOf><AllOf><Match><AttributeValue><DataType>http://www.w3.org/2001/XMLSchema#string</DataType>Julius Hibbert</AttributeValue><AttributeDesignator><Category>urn:oasis:names:tc:xacml:1.0:subject-category:access-subject</Category><AttributeId>urn:oasis:names:tc:xacml:1.0:subject:subject-id</AttributeId><MustBePresent>false</MustBePresent><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></AttributeDesignator><MatchId>urn:oasis:names:tc:xacml:1.0:function:string-equal</MatchId></Match></AllOf></AnyOf><AnyOf><AllOf><Match><AttributeValue><DataType>http://www.w3.org/2001/XMLSchema#anyURI</DataType>http://medico.com/record/patient/BartSimpson</AttributeValue><AttributeDesignator><Category>urn:oasis:names:tc:xacml:3.0:attribute-category:resource</Category><AttributeId>urn:oasis:names:tc:xacml:1.0:resource:resource-id</AttributeId><MustBePresent>false</MustBePresent><DataType>http://www.w3.org/2001/XMLSchema#anyURI</DataType></AttributeDesignator><MatchId>urn:oasis:names:tc:xacml:1.0:function:anyURI-equal</MatchId></Match></AllOf></AnyOf><AnyOf><AllOf><Match><AttributeValue><DataType>http://www.w3.org/2001/XMLSchema#string</DataType>read</AttributeValue><AttributeDesignator><Category>urn:oasis:names:tc:xacml:3.0:attribute-category:action</Category><AttributeId>urn:oasis:names:tc:xacml:1.0:action:action-id</AttributeId><MustBePresent>false</MustBePresent><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></AttributeDesignator><MatchId>urn:oasis:names:tc:xacml:1.0:function:string-equal</MatchId></Match></AllOf><AllOf><Match><AttributeValue><DataType>http://www.w3.org/2001/XMLSchema#string</DataType>write</AttributeValue><AttributeDesignator><Category>urn:oasis:names:tc:xacml:3.0:attribute-category:action</Category><AttributeId>urn:oasis:names:tc:xacml:1.0:action:action-id</AttributeId><MustBePresent>false</MustBePresent><DataType>http://www.w3.org/2001/XMLSchema#string</DataType></AttributeDesignator><MatchId>urn:oasis:names:tc:xacml:1.0:function:string-equal</MatchId></Match></AllOf></AnyOf></Target><Description>Julius Hibbert can read or write Bart Simpson&apos;s medical record.</Description><RuleId>urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:rule</RuleId><Effect>Permit</Effect></Rule><PolicyId>urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:policy</PolicyId></Policy>

So now how can I store the XML file in MongoDB? Also how to ensure that pdp engine core could find the correct policy to be compared? I saw there is a mentioned about the json adapter in README like this but I am not sure how to implement it normally.

Similar question on the restful-pdp project. Please check it out. Basically, in the code we use the jongo library which relies on Jackson to map the PolicyPojo class to JSON. The XML content of the policy corresponds to the PolicyPojo's content string field, therefore simply mapped to JSON string.

Quote:

At the moment, the best way to understand how to use the MongoDbRefPolicyProvider - and how policies must be set up in MongoDB for this - is to look at the corresponding test class, esp. the setupBeforeClass method. As the code shows in Java, each policy should be inserted as a PolicyPojo in the Mongo collection specified by your policy provider's configuration (pdp.xml). So if you reused the example of pdp.xml blindly, this is the collection policies in the database Test. The code shows how to create the PolicyPojo from a XACML Policy(Set) document.

From the PolicyPOJO class, you can pretty much guess the storage format of policies in JSON: it is a JSON object with the following fields (key-value pairs):

  • "id" (string): the Policy(Set) ID
  • "version" (string): the Policy(Set) version
  • "type" (string): the Policy(Set) type, i.e. '{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}Policy' (resp. '{urn:oasis:names:tc:xacml:3.0:core:schema:wd-17}PolicySet') for XACML 3.0 Policy (resp. PolicySet)
  • "content" (string): the actual Policy(Set)'s XML document as string (plain text)

The xml content is automatically escaped properly by the Java library (Jongo/Jackson) to fit in a JSON string. But if you use another library/language, make sure it is the case as well.

No further comment from OP for 15 days. Closing.