Skip to content

Instantly share code, notes, and snippets.

@bernhardjt
Created August 22, 2020 15:34
Show Gist options
  • Save bernhardjt/ae88235503e8ea0f115c4cb420746e53 to your computer and use it in GitHub Desktop.
Save bernhardjt/ae88235503e8ea0f115c4cb420746e53 to your computer and use it in GitHub Desktop.
cloudfront-authorization-at-edge-keycloak
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d111111abcdef8.cloudfront.net",
"distributionId": "EDFDVBD6EXAMPLE",
"eventType": "viewer-request",
"requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
},
"request": {
"clientIp": "203.0.113.178",
"headers": {
"host": [
{
"key": "Host",
"value": "d111111abcdef8.cloudfront.net"
}
],
"user-agent": [
{
"key": "User-Agent",
"value": "curl/7.66.0"
}
],
"authorization": [
{
"key": "Authorization",
"value": "*****enter*here*****"
}
],
"accept": [
{
"key": "accept",
"value": "*/*"
}
]
},
"method": "GET",
"querystring": "",
"uri": "/"
}
}
}
]
}
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d111111abcdef8.cloudfront.net",
"distributionId": "EDFDVBD6EXAMPLE",
"eventType": "viewer-request",
"requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
},
"request": {
"clientIp": "203.0.113.178",
"headers": {
"host": [
{
"key": "Host",
"value": "d111111abcdef8.cloudfront.net"
}
],
"user-agent": [
{
"key": "User-Agent",
"value": "curl/7.66.0"
}
],
"accept": [
{
"key": "accept",
"value": "*/*"
}
]
},
"method": "GET",
"querystring": "",
"uri": "/login.js"
}
}
}
]
}
{
"Records": [
{
"cf": {
"config": {
"distributionDomainName": "d111111abcdef8.cloudfront.net",
"distributionId": "EDFDVBD6EXAMPLE",
"eventType": "viewer-request",
"requestId": "4TyzHTaYWb1GX1qTfsHhEqV6HUDd_BzoBZnwfnvQc_1oF26ClkoUSEQ=="
},
"request": {
"clientIp": "203.0.113.178",
"headers": {
"host": [
{
"key": "Host",
"value": "d111111abcdef8.cloudfront.net"
}
],
"user-agent": [
{
"key": "User-Agent",
"value": "curl/7.66.0"
}
],
"accept": [
{
"key": "accept",
"value": "*/*"
}
]
},
"method": "GET",
"querystring": "",
"uri": "/"
}
}
}
]
}
const jwt = require('jsonwebtoken'); // tested with "^8.5.1" // npm install jsonwebtoken --save
/*
This script is checking the header "Authorization" and the cookie "SSOToken" for a valide jwt (access_token).
If the token is valide and satisfies the criteria of issuer_url, client_name and allow_algorithms, the request will permit.
Unauthorized user get and "content" and "/login.js".
*/
const publicKEY = `
-----BEGIN PUBLIC KEY-----
MIIB*****
-----END PUBLIC KEY-----`;
const issuer_url = 'https://login.example.com/auth/realms/realmexample'
const client_name = 'mypage'
const allow_algorithms = ['RS256']
function parseCookies(headers) {
const parsedCookie = {};
if (headers.cookie) {
headers.cookie[0].value.split(';').forEach((cookie) => {
if (cookie) {
const parts = cookie.split('=');
parsedCookie[parts[0].trim()] = parts[1].trim();
}
});
}
return parsedCookie;
}
function checkJWT(jwtToken) {
//Fail if the token is not jwt
var decodedJwt = jwt.decode(jwtToken, {complete: true});
if (!decodedJwt) {
return false;
}
try {
var decoded = jwt.verify(jwtToken, publicKEY, { algorithms: allow_algorithms, issuer: issuer_url });
if (decoded.azp == client_name) {
return true
}
} catch(err) {
console.log(err.message);
return false
}
return false
}
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
if (request.uri == '/login.js') {
callback(null, request);
return;
}
if (headers['authorization']) {
if (checkJWT(headers['authorization'][0].value)) {
callback(null, request);
return;
} else {
console.log('NO valid token')
}
}
const parsedCookies = parseCookies(headers);
if (parsedCookies && parsedCookies['SSOToken']) {
if (checkJWT(parsedCookies['SSOToken'])) {
callback(null, request);
return;
} else {
console.log('NO valid token')
}
}
const content = `
<!DOCTYPE html>
<html>
<head>
<title>Login Redirect</title>
</head>
<body>
<script src='/login.js'></script>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
</body>
</html>
`;
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: content,
};
callback(null, response);
};
const client_id = "mypage";
const ipd_url = "https://login.example.com";
const realm = "realmexample";
if (window.location.hash) {
console.log("hash url")
var lochash = window.location.hash.substr(1),
mylocation = lochash.substr(lochash.search(/(?<=^|&)access_token=/))
.split('&')[0]
.split('=')[1];
if (mylocation) {
console.log(mylocation);
document.cookie = `SSOToken=${mylocation};path=/`;
location.reload();
}
} else {
const encodedRedirectUrl = (window.location.href);
window.location.replace(`${ipd_url}/auth/realms/${realm}/protocol/openid-connect/auth?client_id=${client_id}&response_type=token&redirect_uri=${encodedRedirectUrl}`);
}
cat event_***.json | docker run --rm \
-v "$PWD/src":/var/task:ro,delegated \
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
lambci/lambda:nodejs12.x \
index.handler
# Example for jwt expired token
cat event_auth_cookie.json| docker run --rm \
-v "$PWD/src":/var/task:ro,delegated \
-i -e DOCKER_LAMBDA_USE_STDIN=1 \
lambci/lambda:nodejs12.x \
index.handler
START RequestId: fe4dde49-d4cb-1913-e977-2b40b96cebf0 Version: $LATEST
2020-08-22T15:24:56.535Z fe4dde49-d4cb-1913-e977-2b40b96cebf0 INFO jwt expired
2020-08-22T15:24:56.539Z fe4dde49-d4cb-1913-e977-2b40b96cebf0 INFO NO valid token
END RequestId: fe4dde49-d4cb-1913-e977-2b40b96cebf0
REPORT RequestId: fe4dde49-d4cb-1913-e977-2b40b96cebf0 Init Duration: 648.50 ms Duration: 23.68 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 45 MB
{"status":"401","statusDescription":"Unauthorized","body":"\n \u003c!DOCTYPE html\u003e\n \u003chtml\u003e\n \u003chead\u003e\n \u003ctitle\u003eLogin Redirect\u003c/title\u003e\n \u003c/head\u003e\n \u003cbody\u003e\n \u003cscript src='/login.js'\u003e\u003c/script\u003e\n \u003cnoscript\u003e\n You need to enable JavaScript to run this app.\n \u003c/noscript\u003e\n \u003c/body\u003e\n \u003c/html\u003e\n "}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment