API 网关映射模板未向 Lambda 函数发送 JWT 身份验证声明
API Gateway mapping template is not sending JWT auth claims to Lambda function
我无法将从请求的授权 header 派生的特定 JWT 授权声明信息发送到 API 网关 REST API 端点(使用 non-proxy Lambda一体化)。该端点由 Cognito 用户池授权方保护,并使用 Login with Amazon 作为身份提供者。从 API 网关的 Cloudwatch 执行日志中,我可以看到 JWT 授权方声明:
(***) 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:
我定义了以下映射模板来组成一个 Lambda 函数事件,其中包含 API 请求 body、参数、headers 以及包含来自JWT 声明 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"
}
}
当我将事件 object 的 JSON 转储记录到 Cloudwatch 时,我看到空的 JSON object {}
。是我的映射模板有问题,还是我的 API 网关配置导致了此行为?
原来我应该在每次更改 VTL 映射模板时部署 API!仅在修改模板后点击 [保存] 按钮不会使更改生效。应更新 AWS 文档,因为 API 何时应为 re-deployed.
并不明显
此外,由于 JWT 授权方声明中 identities
键的值是一个字符串,因此我需要对 userId
[=20= 上的上述映射模板进行轻微修改].
"userId": "$util.parseJson($context.authorizer.claims.identities).userId",
我无法将从请求的授权 header 派生的特定 JWT 授权声明信息发送到 API 网关 REST API 端点(使用 non-proxy Lambda一体化)。该端点由 Cognito 用户池授权方保护,并使用 Login with Amazon 作为身份提供者。从 API 网关的 Cloudwatch 执行日志中,我可以看到 JWT 授权方声明:
(***) 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:
我定义了以下映射模板来组成一个 Lambda 函数事件,其中包含 API 请求 body、参数、headers 以及包含来自JWT 声明 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"
}
}
当我将事件 object 的 JSON 转储记录到 Cloudwatch 时,我看到空的 JSON object {}
。是我的映射模板有问题,还是我的 API 网关配置导致了此行为?
原来我应该在每次更改 VTL 映射模板时部署 API!仅在修改模板后点击 [保存] 按钮不会使更改生效。应更新 AWS 文档,因为 API 何时应为 re-deployed.
并不明显此外,由于 JWT 授权方声明中 identities
键的值是一个字符串,因此我需要对 userId
[=20= 上的上述映射模板进行轻微修改].
"userId": "$util.parseJson($context.authorizer.claims.identities).userId",