Monday, January 27, 2014

node.js + XACML

Following is one possible approach to carryout XACML authorization in node.js.

1.) Wrap WSO2 Balana PDP implementation to expose a simple interface to process incoming XACML requests.
package edu.purdue.cs.endtoendsoa;

public class AccessController {

 public String evaluate(String policy, String request) {
  PDP pdp = this.getPDPInstance(policy);
  return this.evaluate(request, pdp);
 }
 
 private String evaluate(String request, PDP pdp) {
  String res = pdp.evaluate(request);
  ByteArrayInputStream in = new ByteArrayInputStream(res.getBytes());
  OMElement elem = OMXMLBuilderFactory.createOMBuilder(in).getDocumentElement();
  
  OMElement tmp = elem.getFirstChildWithName(new QName("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17", "Result"));
  tmp = tmp.getFirstChildWithName(new QName("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17", "Decision"));
  return tmp.getText();
 }
 
 private PDP getPDPInstance(String policyLocation) {
    PolicyFinder finder= new PolicyFinder();
    Set policyLocations = new HashSet();
    policyLocations.add(policyLocation);
    FileBasedPolicyFinderModule testPolicyFinderModule = new FileBasedPolicyFinderModule(policyLocations);
    Set policyModules = new HashSet();
    policyModules.add(testPolicyFinderModule);
    finder.setModules(policyModules);

    Balana balana = Balana.getInstance();
    PDPConfig pdpConfig = balana.getPdpConfig();
    pdpConfig = new PDPConfig(pdpConfig.getAttributeFinder(), finder,
                              pdpConfig.getResourceFinder(), true);
    return new PDP(pdpConfig);
 }
}
The objective of this wrapper class is only to make things easy when integrating with node.js. Source code is available here: https://code.google.com/p/end-to-end-soa/source/browse/policy. When building this project with maven it collects all the dependencies into 'target/lib' directory.

2.) Import the above implementation into Javascript and try it out.
var java = require('java');
var xml2js = require('xml2js');
var fs = require('fs');


var jars_dir = process.cwd() + '/lib/';
java.classpath.push(jars_dir + "apache-mime4j-core-0.7.2.jar");
java.classpath.push(jars_dir + "balana-distribution-1.0.0-wso2v7.jar");
java.classpath.push(jars_dir + "geronimo-activation_1.1_spec-1.1.jar");
java.classpath.push(jars_dir + "jaxen-1.1.3.jar");
java.classpath.push(jars_dir + "wstx-asl-3.2.9.jar");
java.classpath.push(jars_dir + "axiom-api-1.2.13.jar");
java.classpath.push(jars_dir + "commons-io-1.3.2.jar");
java.classpath.push(jars_dir + "geronimo-javamail_1.4_spec-1.7.1.jar");
java.classpath.push(jars_dir + "junit-3.8.1.jar");
java.classpath.push(jars_dir + "axiom-impl-1.2.13.jar");
java.classpath.push(jars_dir + "commons-logging-1.1.1.jar");
java.classpath.push(jars_dir + "geronimo-stax-api_1.0_spec-1.0.1.jar");
java.classpath.push(jars_dir + "org.wso2.balana-1.0.0-wso2v7.jar");
java.classpath.push(jars_dir + "policy-1.0-SNAPSHOT.jar");

var req_text = fs.readFileSync('./req_1.json','utf8');

var req = JSON.parse(req_text);

//Update request template with values
for(var i in req.Request.Attributes) {
 var attr = req.Request.Attributes[i];
 var attr_id = attr.Attribute[0].$.AttributeId;
 if(attr_id == 'urn:oasis:names:tc:xacml:1.0:resource:resource-id') {
  attr.Attribute[0].AttributeValue[0]._='localhost:6102';
 } else if(attr_id == 'http://endtoendsoa.cs.purdue.edu/policy/service_uri') {
  attr.Attribute[0].AttributeValue[0]._='localhost:6101';
 } else if(attr_id == 'urn:oasis:names:tc:xacml:1.0:action:action-id') {
  attr.Attribute[0].AttributeValue[0]._='READ';
 } else if(attr_id == 'http://test.org/trust_level') {
  attr.Attribute[0].AttributeValue[0]._=10;
 }
}

//Convert populated request template to XML
var builder = new xml2js.Builder();
var req_xml = builder.buildObject(req);


var AccessController = java.import('edu.purdue.cs.endtoendsoa.AccessController');
var ac = new AccessController();
ac.evaluate(process.cwd() + '/policy_1.xml', req_xml, function(err, result) {
 if(err) {
  console.log(err);
 } else {
  console.log('Response from access controller : ' + result);
 }
});
Note that the a template was used in the above code to create a XACML request. This template was generated using a regular XML XACML request. The original XACML request was simply converted into JSON. This was loaded as a JSON object, which is very convenient to traverse in Javascript. The policy file used in the above example is available here. Request template is available here.

3 comments:

Unknown said...

Hi, This is Chandrika from Chennai. I have read your blog and I got some knowledgeable information through this blog. Really useful blog. Keep update your blog.

Regards...
Java Training Chennai

IT said...

Useful & Great Article for NodeJS Development


Node.js Training | Node js Online Course | Node.js Essential Training | Node.js Online Training | Node.js Training in Chennai

Rekha said...

It is so good to read a new article.
java interview questions and answers
selenium interview questions and answers
digital marketing interview questions and answers
hadoop interview questions and answers
oracle interview questions
data science interview questions and answers