Skip to content
This repository has been archived by the owner on Feb 11, 2023. It is now read-only.

Commit

Permalink
Generate and validate nonce with openid-connect
Browse files Browse the repository at this point in the history
  • Loading branch information
payton committed Dec 17, 2018
1 parent ca086dd commit 5841de7
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 80 deletions.
112 changes: 73 additions & 39 deletions authn/openid.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const jwt = require('jsonwebtoken');
const cookie = require('cookie');
const jwkToPem = require('jwk-to-pem');
const auth = require('./auth.js');
const nonce = require('./nonce.js');
const axios = require('axios');
var discoveryDocument;
var jwks;
Expand Down Expand Up @@ -95,33 +96,46 @@ function mainProcess(event, context, callback) {
unauthorized('Unauthorized. User ' + decodedData.payload.email + ' is not permitted.', callback);
}
} else {
console.log("Setting cookie and redirecting.");
// Once verified, create new JWT for this server
const response = {
"status": "302",
"statusDescription": "Found",
"body": "ID token retrieved.",
"headers": {
"location" : [{
"key": "Location",
"value": event.Records[0].cf.config.hasOwnProperty('test') ? (config.AUTH_REQUEST.redirect_uri + queryDict.state) : queryDict.state
}],
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', jwt.sign(
{ },
config.PRIVATE_KEY.trim(),
{
"audience": headers.host[0].value,
"subject": auth.getSubject(decodedData),
"expiresIn": config.SESSION_DURATION,
"algorithm": "RS256"
} // Options
))
}],
},
};
callback(null, response);
if ("cookie" in headers
&& "NONCE" in cookie.parse(headers["cookie"][0].value)
&& nonce.validateNonce(decoded.nonce, cookie.parse(headers["cookie"][0].value).NONCE)) {
console.log("Setting cookie and redirecting.");
// Once verified, create new JWT for this server
const response = {
"status": "302",
"statusDescription": "Found",
"body": "ID token retrieved.",
"headers": {
"location" : [{
"key": "Location",
"value": event.Records[0].cf.config.hasOwnProperty('test') ? (config.AUTH_REQUEST.redirect_uri + queryDict.state) : queryDict.state
}],
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', jwt.sign(
{ },
config.PRIVATE_KEY.trim(),
{
"audience": headers.host[0].value,
"subject": auth.getSubject(decodedData),
"expiresIn": config.SESSION_DURATION,
"algorithm": "RS256"
} // Options
))
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
})
}],
},
};
callback(null, response);
} else {
unauthorized('Nonce verification failed.', callback);
}
}
});
} catch (error) {
Expand Down Expand Up @@ -162,8 +176,8 @@ function mainProcess(event, context, callback) {
}

function redirect(request, headers, callback) {
var n = require('nonce')();
config.AUTH_REQUEST.nonce = n();
const n = nonce.getNonce();
config.AUTH_REQUEST.nonce = n[0];
config.AUTH_REQUEST.state = request.uri;
// Redirect to Authorization Server
var querystring = qs.stringify(config.AUTH_REQUEST);
Expand All @@ -174,13 +188,23 @@ function redirect(request, headers, callback) {
"body": "Redirecting to OIDC provider",
"headers": {
"location" : [{
"key": "Location",
"value": discoveryDocument.authorization_endpoint + '?' + querystring
}],
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', { path: '/', expires: new Date(1970, 1, 1, 0, 0, 0, 0) })
"key": "Location",
"value": discoveryDocument.authorization_endpoint + '?' + querystring
}],
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
})
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', n[1], {
path: '/',
httpOnly: true
})
}],
},
};
callback(null, response);
Expand All @@ -192,10 +216,20 @@ function unauthorized(body, callback) {
"statusDescription": "Unauthorized",
"body": body,
"headers": {
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', { path: '/', expires: new Date(1970, 1, 1, 0, 0, 0, 0) })
}],
"set-cookie" : [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
})
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
})
}],
},
};
callback(null, response);
Expand Down
5 changes: 4 additions & 1 deletion build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ function microsoftConfiguration() {

shell.cp('./authz/microsoft.js', './distributions/' + config.DISTRIBUTION + '/auth.js');
shell.cp('./authn/openid.index.js', './distributions/' + config.DISTRIBUTION + '/index.js');
shell.cp('./nonce.js', './distributions/' + config.DISTRIBUTION + '/nonce.js');

fs.writeFileSync('distributions/' + config.DISTRIBUTION + '/config.json', JSON.stringify(result, null, 4));

Expand Down Expand Up @@ -213,13 +214,14 @@ function googleConfiguration() {
config.AUTHZ = result.AUTHZ;

shell.cp('./authn/openid.index.js', './distributions/' + config.DISTRIBUTION + '/index.js');
shell.cp('./nonce.js', './distributions/' + config.DISTRIBUTION + '/nonce.js');

fs.writeFileSync('distributions/' + config.DISTRIBUTION + '/config.json', JSON.stringify(result, null, 4));

switch (result.AUTHZ) {
case '1':
shell.cp('./authz/google.hosted-domain.js', './distributions/' + config.DISTRIBUTION + '/auth.js');
writeConfig(config, zip, ['config.json', 'index.js', 'auth.js']);
writeConfig(config, zip, ['config.json', 'index.js', 'auth.js', 'nonce.js']);
break;
case '2':
shell.cp('./authz/google.json-email-lookup.js', './distributions/' + config.DISTRIBUTION + '/auth.js');
Expand Down Expand Up @@ -338,6 +340,7 @@ function oktaConfiguration() {
config.AUTHZ = "OKTA";

shell.cp('./authn/openid.index.js', './distributions/' + config.DISTRIBUTION + '/index.js');
shell.cp('./nonce.js', './distributions/' + config.DISTRIBUTION + '/nonce.js');

fs.writeFileSync('distributions/' + config.DISTRIBUTION + '/config.json', JSON.stringify(result, null, 4));

Expand Down
80 changes: 40 additions & 40 deletions build/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions nonce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const crypto = require('crypto');

module.exports.getNonce = function () {
const nonce = crypto.randomBytes(32)
.toString('hex');
const hash = crypto.createHmac('sha256', nonce)
.digest('hex');
return [nonce, hash];
}

module.exports.validateNonce = function (nonce, hash) {
const other = crypto.createHmac('sha256', nonce)
.digest('hex');
return (other == hash);
}
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5841de7

Please sign in to comment.