function processAuthRequest()

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);
    }
  });
}