Skip to content

Commit

Permalink
Inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Timo Stark committed Mar 23, 2021
0 parents commit 68e83f0
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
soapEnvelope-orig.xml
node_modules
package-lock.json
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:alpine
WORKDIR /tmp
RUN npm install xpath xmldom && \
printf "export default {xp}\nfunction xp(){}\n\n" > nginxify.xpath.js && \
echo "global.xpath = require('xpath');" | npx browserify -d -o browserify.xpath.js - && \
cat nginxify.xpath.js browserify.xpath.js > xpath.js
RUN printf "export default {xd}\nfunction xd(){}\n\n" > nginxify.xmldom.js && \
echo "global.xmldom = require('xmldom');" | npx browserify -d -o browserify.xmldom.js - && \
cat nginxify.xmldom.js browserify.xmldom.js > xmldom.js


47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## NGINX njs XML SAML Parser PoC

This is a working demo on how to parse and manipulate XML-messages (e.g. SAML-Headers) with njs.

## 1. Build npm modules for njs
To build the libraries for njs simply build the Docker-Container and download the files or use them in another NGINX-Container with Docker multistage-build.

`docker build -t nginx:samllibs .`

Do build the libraries on the current system issue the following commands:
Learn more about how to use node-modules with njs (http://nginx.org/en/docs/njs/node_modules.html)

```shell
npm install xpath xmldom

printf "export default {xp}\nfunction xp(){}\n\n" > nginxify.xpath.js

echo "global.xpath = require('xpath');" | npx browserify -d -o browserify.xpath.js -

cat nginxify.xpath.js browserify.xpath.js > xpath.js
```

```shell
printf "export default {xd}\nfunction xd(){}\n\n" > nginxify.xmldom.js

echo "global.xmldom = require('xmldom');" | npx browserify -d -o browserify.xmldom.js -

cat nginxify.xmldom.js browserify.xmldom.js > xmldom.js
```

## Installing

Copy the newly created files `xpath.js` as well as `xmldom.js` into the NGINX configuration directory. I like to have the `libs` directory to seperate the 3rd party libraries from the other njs code I have build on top of it.

## NGINX Configuration

Import the modules (see default.conf in conf.d)

```shell
js_import xp from libs/xpath.js;
js_import xd from libs/xmldom.js;
js_import xml from conf.d/njsxml.js;

```

## Credits
The example SAML SOAP-Envelope comes from the Oracle Documentations website.
13 changes: 13 additions & 0 deletions conf.d/default.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
js_import xp from conf.d.mastercard/js_lib/xpath.js;
js_import xd from conf.d.mastercard/js_lib/xmldom.js;
js_import xml from conf.d.mastercard/njsxml.js;


server {
listen 80;

location / {
js_content xml.readXML;
}

}
40 changes: 40 additions & 0 deletions conf.d/njsxml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export default { readXML }

function readXML(r) {

var xpath = global.xpath;
var dom = global.xmldom.DOMParser;
var xmlSerializer = global.xmldom.XMLSerializer;

if (typeof(r.requestBuffer) != "undefined") {


// Create a DOM Document https://developer.mozilla.org/en-US/docs/Web/API/Document from the XMLString.
var doc = new dom().parseFromString(r.requestBuffer.toString());
// Define the namesapes you want to make use of.
var saml = xpath.useNamespaces({'saml': 'urn:oasis:names:tc:SAML:1.0:assertion'});
// Get a node by its XPATH
var node4XML = saml('//saml:Subject', doc)[0];
// Get the text value of a node by its XPATH
var node = saml('//saml:Subject/saml:NameIdentifier/text()', doc)[0].nodeValue;

// Node Manipulation
// Add Attributes to already existing nodes.
node4XML.setAttribute('test', 'TestAttributeFromNJS');
var newContent = doc.createTextNode("Base64EncodedStuff");

// Create a new Node using NameSpaces.
var newElementNS = doc.createElementNS('http://www.w3.org/1999/xhtml', 'SomeMoreSaml');
// Add a Content-Node.
newElementNS.appendChild(newContent);
// Append the new Node to the currently selected node.
node4XML.appendChild(newElementNS);

// use xmlSerializer to create a String from the DOM Document.
var xmlString = new xmlSerializer().serializeToString(node4XML);

}
r.log(node);
r.log(xmlString.toString());
r.return (200, "OK");
}
Empty file added libs/.gitkeep
Empty file.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"dependencies": {
"xmldom": "^0.5.0",
"xpath": "^0.0.32"
}
}
33 changes: 33 additions & 0 deletions parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Debugging App for the npm modules loaded into NJS

var DOMParser = require('xmldom').DOMParser;
var XPath = require('xpath');
var XMLSerializer = require('xmldom').XMLSerializer;
var DOMImpl = require('xmldom').DOMImplementation;
const fs = require('fs');


var doc = new DOMParser().parseFromString(fs.readFileSync('./soapEnvelope.xml').toString());

var saml = XPath.useNamespaces({'saml': 'urn:oasis:names:tc:SAML:2.0:assertion'});
var node4XML = saml('//saml:Subject', doc)[0];
var node = saml('//saml:Subject/saml:NameID/text()', doc)[0].nodeValue;
node4XML.setAttribute('test', 'TestAttributeFromNJS');


var newDiv = doc.createElement("div");
var newElementNS = doc.createElementNS('http://www.w3.org/1999/xhtml', 'SomeMoreSaml')
var newContent = doc.createTextNode("Base64EncodedStuff");
newDiv.appendChild(newContent);
newElementNS.appendChild(newContent);
doc.insertBefore(newDiv);
doc.insertBefore(newElementNS);
node4XML.appendChild(newElementNS);

var xmlString = new XMLSerializer().serializeToString(doc);

console.log(xmlString);




36 changes: 36 additions & 0 deletions soapEnvelope.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://.../soap/envelope/">
<soap:Header xmlns:wsse="http://.../secext">
<wsse:Security>
<saml:Assertion
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
AssertionID="oracle-1056130475340"
Id="oracle-1056130475340"
IssueInstant="2003-06-20T17:34:35Z"
Issuer="CN=Sample User,...........,C=IE"
MajorVersion="1"
MinorVersion="0">
<saml:Conditions
NotBefore="2003-06-20T16:20:10Z"
NotOnOrAfter="2003-06-20T18:20:10Z"/>
<saml:AuthorizationDecisionStatement
Decision="Permit"
Resource="http://www.oracle.com/service">
<saml:Subject>
<saml:NameIdentifier
Format="urn:oasis:names:tc:SAML:1.0:assertion#X509SubjectName">
sample
</saml:NameIdentifier>
</saml:Subject>
</saml:AuthorizationDecisionStatement>
<dsig:Signature xmlns:dsig="http://.../xmldsig#" id="Sample User">
<!-- XML SIGNATURE INSIDE ASSERTION -->
</dsig:Signature>
</saml:Assertion>
</wsse:Security>
</soap:Header>
<soap:Body>
<ns1:getTime xmlns:ns1="urn:timeservice">
</ns1:getTime>
</soap:Body>
</soap:Envelope>

0 comments on commit 68e83f0

Please sign in to comment.