Skip to content

Commit

Permalink
Merge pull request #47 from ziluvatar/add-x-forwarded-host-support
Browse files Browse the repository at this point in the history
Add X-Forwarded-Host support
  • Loading branch information
glena authored Feb 26, 2018
2 parents 6b91af4 + 5e24f5f commit b69d568
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ app.get('/samlp', samlp.auth({
issuer: 'the-issuer',
cert: fs.readFileSync(path.join(__dirname, 'some-cert.pem')),
key: fs.readFileSync(path.join(__dirname, 'some-cert.key')),
getPostURL: function (wtrealm, wreply, req, callback) {
getPostURL: function (wtrealm, wreply, req, callback) {
return callback( null, 'http://someurl.com')
}
}));
Expand All @@ -65,6 +65,8 @@ It also accept two optionals parameters:
- profileMapper: a class implementing the profile mapper. This is used to render the claims type information (using the metadata property). See [PassportProfileMapper](https://github.com/auth0/node-samlp/blob/master/lib/claims/PassportProfileMapper.js) for more information.
- endpointPath: this is the full path in your server to the auth route. By default the metadata handler uses the metadata request route without ```/FederationMetadata/2007..blabla.```

*Note:* If `x-forwarded-host` or `x-forwarded-proto` are received during the HTTP request to the metadata endpoint the urls contained in the metadata will use those them as host or protocol respectively instead of the original ones from `request.headers.host` and `request.protocol`.

## Logout - SLO (Single Logout)
Starting on version `v2.0` Single Logout is supported (SAML 2.0 Single Logout Profile). General support for SLO among Session Participants is varies a lot. This module supports the following flows:

Expand Down
14 changes: 7 additions & 7 deletions lib/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ function getEndpointAddress (req, endpointPath) {
var protocol = req.headers['x-iisnode-https'] && req.headers['x-iisnode-https'] == 'on' ?
'https' :
(req.headers['x-forwarded-proto'] || req.protocol);

return protocol + '://' + req.headers['host'] + endpointPath;
var host = req.headers['x-forwarded-host'] || req.headers['host'];
return protocol + '://' + host + endpointPath;
}

/**
* SAML metadata endpoint
*
* This endpoint returns a SAML metadata document.
*
*
* You should expose this endpoint in an address like:
*
* 'https://your-saml-server.com/FederationMetadata/2007-06/FederationMetadata.xml
*
*
* options:
* - issuer string
* - cert the public certificate
Expand All @@ -32,7 +32,7 @@ function getEndpointAddress (req, endpointPath) {
* - postEndpointPath optional, location value for HTTP-POST binding (SingleSignOnService)
* - logoutEndpointPaths.redirect optional, location value for HTTP-Redirect binding (SingleLogoutService)
* - logoutEndpointPaths.post optional, location value for HTTP-POST binding (SingleLogoutService)
*
*
* @param {[type]} options [description]
* @return {[type]} [description]
*/
Expand All @@ -54,7 +54,7 @@ function metadataMiddleware (options) {
return function (req, res) {
var redirectEndpoint = getEndpointAddress(req, options.redirectEndpointPath);
var postEndpoint = getEndpointAddress(req, options.postEndpointPath);

options.logoutEndpointPaths = options.logoutEndpointPaths || { redirect: '/logout' };

var logoutEndpoints = {};
Expand All @@ -63,7 +63,7 @@ function metadataMiddleware (options) {
logoutEndpoints[binding] = getEndpointAddress(req, options.logoutEndpointPaths[binding]);
}
});

res.set('Content-Type', 'application/xml');

res.send(templates.metadata({
Expand Down
51 changes: 42 additions & 9 deletions test/metadata.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('samlp metadata', function () {
before(function (done) {
server.start(done);
});

after(function (done) {
server.close(done);
});
Expand All @@ -24,7 +24,7 @@ describe('samlp metadata', function () {
var doc, content;
before(function (done) {
request.get({
jar: request.jar(),
jar: request.jar(),
uri: 'http://localhost:5050/samlp/FederationMetadata/2007-06/FederationMetadata.xml'
}, function (err, response, b){
if(err) return done(err);
Expand All @@ -34,41 +34,41 @@ describe('samlp metadata', function () {
});
});

it('sholud have the redirect endpoint url', function(){
it('should have the redirect endpoint url', function(){
expect(doc.getElementsByTagName('SingleSignOnService')[0].getAttribute('Binding'))
.to.equal('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect');

expect(doc.getElementsByTagName('SingleSignOnService')[0].getAttribute('Location'))
.to.equal('http://localhost:5050/samlp/123');
});

it('sholud have the POST endpoint url', function(){
it('should have the POST endpoint url', function(){
expect(doc.getElementsByTagName('SingleSignOnService')[1].getAttribute('Binding'))
.to.equal('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST');

expect(doc.getElementsByTagName('SingleSignOnService')[1].getAttribute('Location'))
.to.equal('http://localhost:5050/login/callback');
});

it('sholud have the logout endpoint url', function(){
it('should have the logout endpoint url', function(){
expect(doc.getElementsByTagName('SingleSignOnService')[0].getAttribute('Binding'))
.to.equal('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect');

expect(doc.getElementsByTagName('SingleLogoutService')[0].getAttribute('Location'))
.to.equal('http://localhost:5050/logout');
});

it('sholud have the claim types', function(){
it('should have the claim types', function(){
expect(doc.getElementsByTagName('Attribute'))
.to.not.be.empty;
});

it('sholud have the issuer', function(){
it('should have the issuer', function(){
expect(doc.getAttribute('entityID'))
.to.equal('urn:fixture-test');
});

it('sholud have the pem', function(){
it('should have the pem', function(){
expect(doc.getElementsByTagName('X509Certificate')[0].textContent)
.to.equal(certToPem(server.credentials.cert));
});
Expand All @@ -79,4 +79,37 @@ describe('samlp metadata', function () {
});

});

describe('request to metadata with proxy', function () {
var doc;
before(function (done) {
request.get({
jar: request.jar(),
uri: 'http://localhost:5050/samlp/FederationMetadata/2007-06/FederationMetadata.xml',
headers: {
'X-Forwarded-Host': 'myserver.com'
}
}, function (err, response, b) {
if (err) return done(err);
doc = new xmldom.DOMParser().parseFromString(b).documentElement;
done();
});
});

it('should have the redirect endpoint url with the forwarded host', function () {
expect(doc.getElementsByTagName('SingleSignOnService')[0].getAttribute('Location'))
.to.equal('http://myserver.com/samlp/123');
});

it('should have the POST endpoint url with the forwarded host', function () {
expect(doc.getElementsByTagName('SingleSignOnService')[1].getAttribute('Location'))
.to.equal('http://myserver.com/login/callback');
});

it('should have the logout endpoint url with the forwarded host', function () {
expect(doc.getElementsByTagName('SingleLogoutService')[0].getAttribute('Location'))
.to.equal('http://myserver.com/logout');
});

});
});

0 comments on commit b69d568

Please sign in to comment.