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

implement sameSite cookie changes #62

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions authn/github.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ function mainProcess(event, context, callback) {
const postData = qs.stringify(config.TOKEN_REQUEST);
console.log("Requesting access token.");
axios.post(config.TOKEN_ENDPOINT, postData)
.then(function(response) {
.then(function (response) {
console.log(response);
var responseQueryString = qs.parse(response.data);
/** Get authenticated user's login */
if (responseQueryString.error) {
internalServerError("Error while getting token: " + responseQueryString.error_description, callback);
} else {
const authorization = responseQueryString.token_type + ' ' + responseQueryString.access_token;
axios.get('https://api.github.com/user', { headers: {'Authorization': authorization}})
.then(function(response) {
axios.get('https://api.github.com/user', { headers: { 'Authorization': authorization } })
.then(function (response) {
console.log(response);
/** Check if authenticated user's login is a member of given org */
if (!response.data.hasOwnProperty('login')) {
Expand All @@ -53,8 +53,8 @@ function mainProcess(event, context, callback) {
var username = response.data.login;
var orgsGet = 'https://api.github.com/orgs/' + config.ORGANIZATION + '/members/' + username;
console.log("Checking ORG membership.");
axios.get(orgsGet, { headers: {'Authorization': authorization} })
.then(function(response) {
axios.get(orgsGet, { headers: { 'Authorization': authorization } })
.then(function (response) {
console.log(response);
/** Set cookie upon verified membership */
if (response.status == 204) {
Expand All @@ -64,22 +64,24 @@ function mainProcess(event, context, callback) {
"statusDescription": "Found",
"body": "ID token retrieved.",
"headers": {
"location" : [{
"location": [{
"key": "Location",
"value": event.Records[0].cf.config.hasOwnProperty('test') ? (config.AUTH_REQUEST.redirect_uri + queryDict.state) : queryDict.state
}],
"set-cookie" : [{
"set-cookie": [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', jwt.sign(
{ },
"value": cookie.serialize('TOKEN', jwt.sign(
{},
config.PRIVATE_KEY.trim(),
{
audience: headers.host[0].value,
subject: auth.getSubject(username),
expiresIn: config.SESSION_DURATION,
algorithm: 'RS256'
} // Options
))
), {
SameSite: 'None; Secure'
})
}],
},
};
Expand All @@ -89,22 +91,22 @@ function mainProcess(event, context, callback) {
unauthorized('Unauthorized. User ' + response.login + ' is not a member of required organization.', callback);
}
})
.catch(function(error) {
.catch(function (error) {
internalServerError('Error checking membership: ' + error.message, callback);
});
})
.catch(function(error) {
.catch(function (error) {
internalServerError('Error getting user: ' + error.message, callback);
});
}
})
.catch(function(error) {
.catch(function (error) {
internalServerError('Error getting token: ' + error.message, callback);
});
} else if ("cookie" in headers
&& "TOKEN" in cookie.parse(headers["cookie"][0].value)) {
&& "TOKEN" in cookie.parse(headers["cookie"][0].value)) {
// Verify the JWT, the payload email, and that the email ends with configured hosted domain
jwt.verify(cookie.parse(headers["cookie"][0].value).TOKEN, config.PUBLIC_KEY.trim(), { algorithms: ['RS256'] }, function(err, decoded) {
jwt.verify(cookie.parse(headers["cookie"][0].value).TOKEN, config.PUBLIC_KEY.trim(), { algorithms: ['RS256'] }, function (err, decoded) {
if (err) {
switch (err.name) {
case 'TokenExpiredError':
Expand Down Expand Up @@ -140,13 +142,13 @@ function redirect(request, headers, callback) {
statusDescription: "Found",
body: "Redirecting to OAuth2 provider",
headers: {
"location" : [{
"location": [{
"key": "Location",
"value": config.AUTHORIZATION_ENDPOINT + '?' + querystring
}],
"set-cookie" : [{
"set-cookie": [{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', { path: '/', expires: new Date(1970, 1, 1, 0, 0, 0, 0) })
"value": cookie.serialize('TOKEN', '', { path: '/', expires: new Date(1970, 1, 1, 0, 0, 0, 0), SameSite: 'None; Secure' })
}],
},
};
Expand All @@ -159,10 +161,10 @@ 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), SameSite: 'None; Secure' })
}],
},
};
callback(null, response);
Expand Down
66 changes: 36 additions & 30 deletions authn/openid.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ exports.handler = (event, context, callback) => {
// Get Discovery Document data
console.log("Get discovery document data");
axios.get(config.DISCOVERY_DOCUMENT)
.then(function(response) {
.then(function (response) {
console.log(response);

// Get jwks from discovery document url
Expand All @@ -27,14 +27,14 @@ exports.handler = (event, context, callback) => {

// Get public key and verify JWT
axios.get(discoveryDocument.jwks_uri)
.then(function(response) {
.then(function (response) {
console.log(response);
jwks = response.data;

// Callback to main function
mainProcess(event, context, callback);
})
.catch(function(error) {
.catch(function (error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
Expand All @@ -43,7 +43,7 @@ exports.handler = (event, context, callback) => {
internalServerError(callback);
}
})
.catch(function(error) {
.catch(function (error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
Expand Down Expand Up @@ -114,9 +114,9 @@ function mainProcess(event, context, callback) {
const postData = qs.stringify(config.TOKEN_REQUEST);
console.log("Requesting access token.");
axios.post(discoveryDocument.token_endpoint, postData)
.then(function(response) {
.then(function (response) {
console.log(response);
const decodedData = jwt.decode(response.data.id_token, {complete: true});
const decodedData = jwt.decode(response.data.id_token, { complete: true });
console.log(decodedData);
try {
console.log("Searching for JWK from discovery document");
Expand All @@ -131,7 +131,7 @@ function mainProcess(event, context, callback) {
console.log("Verifying JWT");

// Verify the JWT, the payload email, and that the email ends with configured hosted domain
jwt.verify(response.data.id_token, pem, { algorithms: ['RS256'] }, function(err, decoded) {
jwt.verify(response.data.id_token, pem, { algorithms: ['RS256'] }, function (err, decoded) {
if (err) {
switch (err.name) {
case 'TokenExpiredError':
Expand All @@ -150,8 +150,8 @@ function mainProcess(event, context, callback) {

// Validate nonce
if ("cookie" in headers
&& "NONCE" in cookie.parse(headers["cookie"][0].value)
&& nonce.validateNonce(decoded.nonce, cookie.parse(headers["cookie"][0].value).NONCE)) {
&& "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
Expand All @@ -160,17 +160,17 @@ function mainProcess(event, context, callback) {
"statusDescription": "Found",
"body": "ID token retrieved.",
"headers": {
"location" : [
"location": [
{
"key": "Location",
"value": event.Records[0].cf.config.hasOwnProperty('test') ? (config.AUTH_REQUEST.redirect_uri + queryDict.state) : queryDict.state
}
],
"set-cookie" : [
"set-cookie": [
{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', jwt.sign(
{ },
"value": cookie.serialize('TOKEN', jwt.sign(
{},
config.PRIVATE_KEY.trim(),
{
"audience": headers.host[0].value,
Expand All @@ -180,14 +180,16 @@ function mainProcess(event, context, callback) {
} // Options
), {
path: '/',
maxAge: config.SESSION_DURATION
maxAge: config.SESSION_DURATION,
SameSite: 'None; Secure'
})
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', '', {
"value": cookie.serialize('NONCE', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
expires: new Date(1970, 1, 1, 0, 0, 0, 0),
SameSite: 'None; Secure'
})
}
],
Expand All @@ -204,16 +206,16 @@ function mainProcess(event, context, callback) {
internalServerError(callback);
}
})
.catch(function(error) {
.catch(function (error) {
console.log("Internal server error: " + error.message);
internalServerError(callback);
});
} else if ("cookie" in headers
&& "TOKEN" in cookie.parse(headers["cookie"][0].value)) {
&& "TOKEN" in cookie.parse(headers["cookie"][0].value)) {
console.log("Request received with TOKEN cookie. Validating.");

// Verify the JWT, the payload email, and that the email ends with configured hosted domain
jwt.verify(cookie.parse(headers["cookie"][0].value).TOKEN, config.PUBLIC_KEY.trim(), { algorithms: ['RS256'] }, function(err, decoded) {
jwt.verify(cookie.parse(headers["cookie"][0].value).TOKEN, config.PUBLIC_KEY.trim(), { algorithms: ['RS256'] }, function (err, decoded) {
if (err) {
switch (err.name) {
case 'TokenExpiredError':
Expand Down Expand Up @@ -252,23 +254,25 @@ function redirect(request, headers, callback) {
"statusDescription": "Found",
"body": "Redirecting to OIDC provider",
"headers": {
"location" : [{
"location": [{
"key": "Location",
"value": discoveryDocument.authorization_endpoint + '?' + querystring
}],
"set-cookie" : [
"set-cookie": [
{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', {
"value": cookie.serialize('TOKEN', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
expires: new Date(1970, 1, 1, 0, 0, 0, 0),
SameSite: 'None; Secure'
})
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', n[1], {
"value": cookie.serialize('NONCE', n[1], {
path: '/',
httpOnly: true
httpOnly: true,
SameSite: 'None; Secure'
})
}
],
Expand Down Expand Up @@ -304,19 +308,21 @@ function unauthorized(error, error_description, error_uri, callback) {
"statusDescription": "Unauthorized",
"body": page,
"headers": {
"set-cookie" : [
"set-cookie": [
{
"key": "Set-Cookie",
"value" : cookie.serialize('TOKEN', '', {
"value": cookie.serialize('TOKEN', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
expires: new Date(1970, 1, 1, 0, 0, 0, 0),
SameSite: 'None; Secure'
})
},
{
"key": "Set-Cookie",
"value" : cookie.serialize('NONCE', '', {
"value": cookie.serialize('NONCE', '', {
path: '/',
expires: new Date(1970, 1, 1, 0, 0, 0, 0)
expires: new Date(1970, 1, 1, 0, 0, 0, 0),
SameSite: 'None; Secure'
})
}
],
Expand Down
Loading