I am having trouble sending specific JWT authorization claims information derived from the Authorization header of a request to an API Gateway REST API endpoint (with non-proxy Lambda integration). The endpoint is secured with a Cognito User Pool Authorizer with Login with Amazon as the identity provider. From the Cloudwatch execution logs of API Gateway, I can see the JWT authorizer claims:
(***) Cognito User Pool Authorizer claims from JWT: {
at_hash=***,
sub=***,
cognito:groups=us-east-1_***_LoginWithAmazon,
email_verified=false,
iss=https://cognito-idp.us-east-1.amazonaws.com/us-east-1_***,
cognito:username=loginwithamazon_amzn1.account.***,
nonce=***,
origin_jti=***,
aud=***,
identities={
"dateCreated":"***",
"userId":"amzn1.account.***",
"providerName":"LoginWithAmazon",
"providerType":"LoginWithAmazon",
"issuer":null,
"primary":"true"
},
token_use=id,
auth_time=***,
name=***,
exp=*** UTC 2022,
iat=*** UTC 2022,
jti=***,
email=***
}
(***) Method request path: {}
(***) Method request query string: {}
(***) Method request headers: {Authorization=******[TRUNCATED]
(***) Method request body before transformations:
(***) Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:***:function:***/invocations
(***) Endpoint request headers: {x-amzn-lambda-integration-tag=***, Authorization=***, X-Amz-Date=***, x-amzn-apigateway-api-id=***, X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:***:***/***/GET/myapi, Accept=application/json, User-Agent=AmazonAPIGateway_***, X-Amz-Security-Token=*** [TRUNCATED]
(***) Method request body after transformations:
I defined the following mapping template to compose a Lambda function event containing the API request body, parameters, headers, and a context that holds specific pieces of information from the JWT claims object:
## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
#if($foreach.hasNext),#end
#end
},
"context" : {
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"caller" : "$context.identity.caller",
"http-method" : "$context.httpMethod",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath",
"userId": "$context.authorizer.claims.identities.userId",
"name": "$context.authorizer.claims.name",
"email": "$context.authorizer.claims.email",
"email_verified": "$context.authorizer.claims.email_verified"
}
}
When I log a JSON dump of the event object to Cloudwatch, I see an empty JSON object {}
. Is my mapping template the problem, or is my API Gateway configuration causing this behavior?