auth0-lambda-authorizer
Version:
An Auth0 Authorizer for AWS Lambda
180 lines • 7.9 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
exports.__esModule = true;
var Either_1 = require("fp-ts/lib/Either");
var jwt = require("jsonwebtoken");
var R = require("ramda");
var logFactory_1 = require("./logFactory");
var log = logFactory_1.logFactory.getLogger("lambda.authorizer");
exports.getPolicyDocument = function (effect, resource) {
var policyDocument = {
Statement: [
{
Action: "execute-api:Invoke",
Effect: effect,
Resource: resource
},
],
Version: "2012-10-17"
};
return policyDocument;
};
var validateToken = function (token) {
if (!token) {
var errorMessage = "Expected 'event.authorizationToken' parameter to be set";
log.error(errorMessage);
throw new Error(errorMessage);
}
};
var validateParams = function (params) {
if (!params.type || params.type !== "TOKEN") {
var errorMessage = "Expected 'event.type' parameter to have value TOKEN";
log.error(errorMessage);
throw new Error(errorMessage);
}
};
var getToken = function (params) {
validateParams(params);
var tokenString = params.authorizationToken;
validateToken(tokenString);
var match = tokenString.match(/^Bearer (.*)$/);
if (!match || match.length < 2) {
var errorMessage = "Invalid Authorization token - '" + tokenString + "' does not match 'Bearer .*'";
log.error(errorMessage);
throw new Error(errorMessage);
}
return match[1];
};
var verifyToken = function (token, secret, algorithm, audience) {
try {
var verified = jwt.verify(token, secret, { algorithms: [algorithm] });
if (!R.is(String, verified)) {
return Either_1.right(verified);
}
else {
log.error({ data: verified, msg: "FAILED TO VERIFY" });
return Either_1.left(new Error("Failed to verify"));
}
}
catch (e) {
log.error({ data: e, msg: "Failed to verify the Auth0 token" });
return Either_1.left(e);
}
};
var getRoles = function (payload) {
if (R.isNil(payload)) {
return [];
}
else {
return payload.roles;
}
};
var craftResponse = function (token, client, algorithm, policyDocument) {
log.info({ msg: "In retrieveSigningKey ", data: { token: token, client: client, policyDocument: policyDocument } });
var decoded = jwt.decode(token, { complete: true });
var kid = decoded.header.kid;
log.info({ msg: "Decoded ", data: decoded });
if (decoded instanceof String) {
log.error({ data: decoded, msg: "FAILED TO DECODE " });
return Either_1.left(Error("Decoding failed"));
}
else {
var authResponse = {
context: {
scope: decoded.payload.sub
},
policyDocument: policyDocument,
principalId: decoded.payload.sub
};
return Either_1.right({ authResponse: authResponse, payload: decoded.payload });
}
};
exports.getKeys = function (token, client) {
return new Promise(function (resolve, reject) {
client.getKeys(function (err, keys) {
if (err) {
log.error({ data: err, msg: "An error occurred getting keys" });
return reject(err);
}
return resolve(keys);
});
});
};
exports.getSigningKey = function (client, kid) {
return new Promise(function (resolve, reject) {
client.getSigningKey(kid, function (err, key) {
if (err) {
log.error({ data: err, msg: "An error occurred fetching the Signing Key" });
return reject(err);
}
var signingKey = key.publicKey || key.rsaPublicKey;
return resolve(signingKey);
});
});
};
exports.authenticate = function (apiGatewayEvent, tokenConfig) { return __awaiter(_this, void 0, void 0, function () {
var client, algorithm, auth0Audience, token, policyDocument, keys, signingKey, verification;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
client = tokenConfig.client, algorithm = tokenConfig.algorithm, auth0Audience = tokenConfig.auth0Audience;
token = getToken(apiGatewayEvent);
policyDocument = exports.getPolicyDocument("Allow", apiGatewayEvent.methodArn);
log.info({ msg: "Created Policy Document: ", data: policyDocument });
return [4 /*yield*/, exports.getKeys(token, client)];
case 1:
keys = _a.sent();
log.info({ data: keys, msg: "Fetched Keys from Auth0" });
return [4 /*yield*/, exports.getSigningKey(client, keys[0].kid)];
case 2:
signingKey = _a.sent();
log.info({ data: signingKey, msg: "Retrieved signing key from Auth0" });
verification = verifyToken(token, signingKey, algorithm, auth0Audience)
.chain(function (verified) {
log.info({ msg: "Verified Token: ", data: verified });
return craftResponse(token, client, algorithm, policyDocument);
})
.mapLeft(function (e) {
log.error({ msg: "An unrecovarable exception ocurred while authenticating ", data: e });
return e;
});
return [2 /*return*/, verification];
}
});
}); };
//# sourceMappingURL=authorizer.js.map
;