in src/authorizer/index.js [60:198]
function ValidateToken(pems, event, context, callback) {
var token = event.authorizationToken;
// the auth header may come in the format of "Bearer <token>" or "<token>"
var parts = token.split(' ');
if (parts.length == 2) {
var schema = parts.shift().toLowerCase();
token = parts.join(' ');
if ('bearer' != schema) {
console.log("Schema " + schema + " not supported");
context.fail("Unauthorized");
return;
}
}
//Fail if the token is not jwt
var decodedJwt = jwt.decode(token, {complete: true});
if (!decodedJwt) {
console.log("Not a valid JWT token");
context.fail("Unauthorized");
return;
}
//Fail if token is not from your UserPool
if (decodedJwt.payload.iss != iss) {
console.log("invalid issuer");
context.fail("Unauthorized");
return;
}
//Reject the jwt if it's not an 'Access Token'
if (decodedJwt.payload.token_use != 'access') {
console.log("Not an access token");
context.fail("Unauthorized");
return;
}
//Get the kid from the token and retrieve corresponding PEM
var kid = decodedJwt.header.kid;
var pem = pems[kid];
if (!pem) {
console.log('Invalid access token');
context.fail("Unauthorized");
return;
}
//Verify the signature of the JWT token to ensure it's really coming from your User Pool
jwt.verify(token, pem, {issuer: iss}, function (err, payload) {
if (err) {
console.log("error verifying token: " + JSON.stringify(err, null, 2));
context.fail("Unauthorized");
} else {
console.log("Token payload: " + JSON.stringify(payload));
//Valid token. Generate the API Gateway policy for the user
//Always generate the policy on value of 'sub' claim and not for 'username' because username is reassignable
//sub is UUID for a user which is never reassigned to another user.
var principalId = payload.username;
//Get AWS AccountId and API Options
var apiOptions = {};
var tmp = event.methodArn.split(':');
var apiGatewayArnTmp = tmp[5].split('/');
var awsAccountId = tmp[4];
apiOptions.region = tmp[3];
apiOptions.restApiId = apiGatewayArnTmp[0];
apiOptions.stage = apiGatewayArnTmp[1];
var method = apiGatewayArnTmp[2];
var resource = '/'; // root resource
if (apiGatewayArnTmp[3]) {
resource += apiGatewayArnTmp[3];
}
//For more information on specifics of generating policy, refer to blueprint for API Gateway's Custom authorizer in Lambda console
var policy = new AuthPolicy(principalId, awsAccountId, apiOptions);
// Any authenticated clients can list customization options
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/horns");
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/socks");
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/glasses");
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/capes");
// When the scope matches the partner admin scope
if (payload.scope.includes(PARTNER_ADMIN_SCOPE)) {
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/partner*");
policy.allowMethod(AuthPolicy.HttpVerb.POST, "/partner*");
policy.allowMethod(AuthPolicy.HttpVerb.DELETE, "/partner*");
const authResponse = policy.build();
console.log("authResponse:" + JSON.stringify(authResponse, null, 2));
callback(null, authResponse);
return;
}
// When the scope matches the unicorn customizations scope, ensure the company can be found in the ID loopup table
if (payload.scope.includes(CUSTOMIZE_SCOPE)) {
policy.allowMethod(AuthPolicy.HttpVerb.GET, "/customizations*");
policy.allowMethod(AuthPolicy.HttpVerb.POST, "/customizations*");
policy.allowMethod(AuthPolicy.HttpVerb.DELETE, "/customizations*");
const authResponse = policy.build();
// look up the backend ID for the company
var params = {
TableName: companyDDBTable,
Key: {'ClientID': payload["client_id"]}
};
ddbDocClient.get(params).promise().then(data => {
console.log("DDB response:\n" + JSON.stringify(data));
if (data["Item"] && "CompanyID" in data["Item"]) {
authResponse.context = {
CompanyID: data["Item"]["CompanyID"]
};
// Uncomment here to pass on the client ID as the api key in the auth response
// authResponse.usageIdentifierKey = payload["client_id"];
console.log("authResponse:" + JSON.stringify(authResponse, null, 2));
callback(null, authResponse);
return;
} else {
console.log("did not find matching clientID");
context.fail("Unauthorized");
return;
}
}).catch(err => {
console.error((err));
callback("Error: Internal Error");
return;
});
} else {
console.log("did not find matching clientID");
context.fail("Unauthorized");
return;
}
}
});
}