in serverless-rest-api/javascript-http-sam/src/api/authorizer.js [320:415]
function processAuthRequest(event, tokenIssuer, awsAccountId, apiOptions, callback) {
var token = event.authorizationToken;
if (token.startsWith("Bearer ")) {
token = token.substring(7, token.length);
}
//Fail if the token is not jwt
var decodedJwt = jwt.decode(token, {complete: true});
if (!decodedJwt) {
let policy = new AuthPolicy('', awsAccountId, apiOptions);
console.log("Not valid JWT token, returning deny all policy");
policy.denyAllMethods();
let iamPolicy = policy.build();
callback(null, iamPolicy);
return;
}
//Fail if token is not from your User Pool
if (decodedJwt.payload['iss'] != tokenIssuer) {
console.log("Provided Token not from UserPool, returning deny all policy");
let policy = new AuthPolicy('', awsAccountId, apiOptions);
policy.denyAllMethods();
let iamPolicy = policy.build();
callback(null, iamPolicy);
return;
}
//Reject the jwt if it's not an 'Identity Token'
if (decodedJwt.payload['token_use'] != 'id') {
console.log("Provided Token is not and identity token, returning deny all policy");
let policy = new AuthPolicy('', awsAccountId, apiOptions);
policy.denyAllMethods();
let iamPolicy = policy.build();
callback(null, iamPolicy);
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 Identity token, returning deny all policy");
let policy = new AuthPolicy('', awsAccountId, apiOptions);
policy.denyAllMethods();
let iamPolicy = policy.build();
callback(null, iamPolicy);
return;
}
//Verify the signature of the JWT token to ensure it's really coming from your User Pool
jwt.verify(token, pem, {issuer: tokenIssuer}, function (err, payload) {
if (err) {
console.log("Error while trying to verify the Token, returning deny-all policy");
let policy = new AuthPolicy('', awsAccountId, apiOptions);
policy.denyAllMethods();
let iamPolicy = policy.build();
callback(null, iamPolicy);
} else {
//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.
const pId = decodedJwt.payload['sub'];
let policy = new AuthPolicy(pId, awsAccountId, apiOptions);
// Add all allowed public resources/methods explicitly
policy.allowMethod(AuthPolicy.HttpVerb.GET, 'locations');
policy.allowMethod(AuthPolicy.HttpVerb.GET, 'locations/*');
policy.allowMethod(AuthPolicy.HttpVerb.GET, 'locations/*/resources');
policy.allowMethod(AuthPolicy.HttpVerb.GET, 'locations/*/resources/*/bookings');
// Add user specific resources and methods
policy.allowMethod(AuthPolicy.HttpVerb.GET, `/users/${pId}/bookings`);
policy.allowMethod(AuthPolicy.HttpVerb.GET, `/users/${pId}/bookings/*`);
policy.allowMethod(AuthPolicy.HttpVerb.PUT, `/users/${pId}/bookings`);
policy.allowMethod(AuthPolicy.HttpVerb.DELETE, `/users/${pId}/bookings/*`);
//Check the Cognito group entry for Admin.
//Assuming here that the Admin group has always higher /precedence
if (decodedJwt.payload['cognito:groups'] &&
decodedJwt.payload['cognito:groups'][0] === process.env.ADMIN_GROUP_NAME) {
policy.allowMethod(AuthPolicy.HttpVerb.DELETE, '/locations');
policy.allowMethod(AuthPolicy.HttpVerb.DELETE, '/locations/*');
policy.allowMethod(AuthPolicy.HttpVerb.PUT, '/locations');
policy.allowMethod(AuthPolicy.HttpVerb.PUT, '/locations/*');
}
let iamPolicy = policy.build();
console.log('Effective IAM statement', iamPolicy.policyDocument.Statement);
callback(null, iamPolicy);
}
});
}