So, I am writing a small program to read an XACML request, validate if it is valid XACML, and then subsequently check the code towards a policy.
In this endeavor I found the lxml parser, which can validate .xml files towards a .xsd file. Therefore I wget'ed the relevant schemas and tried them both in the validator (http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-policy-schema-os.xsd, and http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-context-schema-os.xsd), to compare to my request.xml files containing an XACML request. The problem that I am encountering is that my program returns false for the validation, meaning that it is not valid, althoug by all accounts it SHOULD be. The code in question is listed below, as well as the input command, and the error.
import os
import sys
from ndg import *
from lxml import etree
def checkCorrectXACML(xml_path: str, xsd_path: str) -> bool:
input_schema = etree.parse(xsd_path)
schema = etree.XMLSchema(input_schema)
request = etree.parse(xml_path)
result = schema.validate(request)
return result
def checkPolicy(request):
status: bool
return status
def readRequest():
request = str(sys.argv[1])
if(checkCorrectXACML(request, '/home/foo/Documents/xacml.xsd') == True):
return request
else:
raise Exception('Invalid XACML')
def evaluateRequest():
request = readRequest()
status = checkPolicy(request)
return status
def main():
if(len(sys.argv) == 2):
returnResponse = evaluateRequest()
return returnResponse
else:
raise Exception('You need to provide a request path')
if __name__ == '__main__':
main()
Error:
File "/home/foo/Documents/XACXML.py", line 22, in readRequest raise Exception('Invalid XACML') Exception: Invalid XACML
Command:
python3 XACML.py /home/foo/Desktop/Request1.xml
Request1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Request
xmlns="urn:oasis:names:tc:xacml:1.0:context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:1.0:context
cs-xacml-schema-context-01.xsd">
<Subject>
<Attribute
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>External user</AttributeValue>
</Attribute>
</Subject>
<Resource>
<Attribute
AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
DataType="http://www.w3.org/2001/XMLSchema#anyURI">
<AttributeValue>http://some.url/foo</AttributeValue>
</Attribute>
</Resource>
<Action>
<Attribute
AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>read</AttributeValue>
</Attribute>
</Action>
</Request>
Thanks to Martin Honnen that pointed out that the namespace of the XACML didn't match the namespace for the schema. Using a request with a similar namespace solved the issue. Here is an example of an X(AC)ML sample that did in fact work, both with xmllint and in the script.
The problem was therefore the xmlns
<?xml version="1.0" encoding="UTF-8"?>
<Request
xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" urn:oasis:names:tc:xacml:2.0:context:schema:os
http://docs.oasis-open.org/xacml/access_control-xacml-2.0-context-schema-os.xsd">
<Subject
SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject">
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
<AttributeValue>000000</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:subject:user-name"
DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
<AttributeValue>Some name</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-num-shares"
DataType="http://www.w3.org/2001/XMLSchema#integer"
Issuer="xacml20.interop.com">
<AttributeValue>0000</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:subject:buy-offer-price"
DataType="http://www.w3.org/2001/XMLSchema#integer"
Issuer="xacml20.interop.com">
<AttributeValue>1</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-credit-ext-approval"
DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
<AttributeValue>false</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:subject:req-trade-approval"
DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="xacml20.interop.com">
<AttributeValue>false</AttributeValue>
</Attribute>
</Subject>
<Resource>
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>Astring</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-id"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>000000</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:owner-name"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>Somename</AttributeValue>
</Attribute>
<!-- WE GET THIS VIA THE ATTRIBUTE LOCATOR
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:account-status"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>Active</AttributeValue>
</Attribute>
-->
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:credit-line"
DataType="http://www.w3.org/2001/XMLSchema#integer">
<AttributeValue>15000</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:current-credit"
DataType="http://www.w3.org/2001/XMLSchema#integer">
<AttributeValue>10000</AttributeValue>
</Attribute>
<Attribute AttributeId="urn:xacml:2.0:interop:example:resource:trade-limit"
DataType="http://www.w3.org/2001/XMLSchema#integer">
<AttributeValue>10000</AttributeValue>
</Attribute>
</Resource>
<Action>
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"
DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>Buy</AttributeValue>
</Attribute>
</Action>
<Environment/>
</Request>