Kotlin中Request类型的Lambda Authorizer无法正常工作
解决Request类型Lambda授权器返回500内部服务器错误问题
以下是针对你的问题的排查和解决步骤:
1. 查看API Gateway的详细错误日志
Lambda授权器日志无报错但API返回500,大概率是API Gateway处理授权响应时出现了格式或解析问题。开启API Gateway的CloudWatch日志可获取具体错误原因:
- 登录AWS控制台,进入目标API的Stages页面
- 选中已部署的阶段,切换到Logs/Tracing标签
- 开启「Enable CloudWatch Logs」,设置Log level为INFO并保存配置
- 重新调用API,前往CloudWatch日志组查看API Gateway的日志,里面会明确标注错误类型(例如「Invalid policy document」)
2. 验证授权器返回的JSON结构是否符合AWS规范
AWS对Request类型授权器的返回格式有严格要求,核心是policyDocument的字段名必须为首字母大写的标准格式,正确示例如下:
{ "principalId": "user123", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "execute-api:Invoke", "Resource": "arn:aws:execute-api:xxx:xxx:xxx/*/GET/xxx" } ] } }
你可以在Lambda代码中添加日志,打印返回的JSON内容以验证结构:
override fun handleRequest(input: Map<String, Any>, context: Context?): AuthorizerResponse { // ... 原有业务代码 ... val response = AuthorizerResponse(principalId = tokenBody.userID, policyDocument = policyDocument) // 序列化响应并打印到日志 val mapper = ObjectMapper().registerModule(KotlinModule()) LOG.info("Authorizer Response JSON: ${mapper.writeValueAsString(response)}") return response }
重点检查:
policyDocument下的Version、Statement是否为首字母大写- 每个
Statement内的Effect、Action、Resource是否为首字母大写 - 字段值是否合规(例如
Version必须为2012-10-17,Action必须是execute-api:Invoke)
3. 修正IamPolicyResponse的序列化配置
如果日志显示JSON字段名为小写(如version而非Version),说明你的IamPolicyResponse类的@JsonProperty注解配置错误。请确保字段绑定正确的大写字段名:
// 示例PolicyDocument类 class PolicyDocument( @JsonProperty("Version") val version: String, @JsonProperty("Statement") val statements: List<Statement> ) // 示例Statement类 class Statement( @JsonProperty("Effect") val effect: String, @JsonProperty("Action") val action: String, @JsonProperty("Resource") val resources: List<String> )
对应的Builder也要确保设置正确的字段值:
val statement = Statement( effect = "Allow", action = "execute-api:Invoke", resources = listOf(arn) // 建议使用具体ARN而非*,提升安全性 ) val policyDocument = PolicyDocument( version = "2012-10-17", statements = listOf(statement) )
4. 修复潜在的空值安全问题
代码中的!!操作符遇到null会直接抛出NPE,若Lambda日志未捕获到,可能是日志配置问题。建议替换为安全的类型转换和空值检查,避免隐性错误:
// 安全获取headers val headers = input["headers"] as? Map<String, String> ?: throw IllegalArgumentException("请求缺少headers字段") // 安全获取authorization头 val authorization = headers["authorization"] ?: throw IllegalArgumentException("请求缺少Authorization头") // 安全获取routeArn val arn = input["routeArn"] as? String ?: throw IllegalArgumentException("请求缺少routeArn字段")
5. 用测试事件验证Lambda逻辑
在Lambda控制台创建模拟测试事件,模拟API Gateway发送的Request类型授权请求:
{ "type": "REQUEST", "routeArn": "arn:aws:execute-api:us-east-1:123456789012:your-api-id/*/GET/your-route", "headers": { "authorization": "Bearer your-test-token" }, "requestContext": { "accountId": "123456789012" } }
执行测试后,查看返回的JSON是否符合AWS规范,同时确认Lambda日志是否有异常抛出。
内容的提问来源于stack exchange,提问作者Kancha
相关产品推荐
相关产品推荐

