我有一个API网关,该网关的端点由AWS Lambda代理集成实现。我还为此端点配置了自定义授权者。我看到一个问题,我对此端点发出的第一个请求成功,但是其他调用将失败;我收到403-禁止的错误。如果我稍等片刻,我可以发出另一个成功的请求,但是随后我开始遇到相同的问题。
这是我给授权人的代码:
const jwt = require('jsonwebtoken');
exports.authorizer = async function (event, context) {
const bearerToken = event.authorizationToken.slice(7);
const { payload } = jwt.decode(bearerToken);
return {
principalId: payload.sub,
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: 'Allow',
Resource: event.methodArn,
}],
},
};
};
在该端点的API网关日志中,我可以看到授权者正在返回Allow
,但是我仍然可以看到授权失败:
(50ac5f87-e152-4933-a797-63d84a528f61)客户无权执行此操作。
有人知道如何或为什么会发生这种情况吗?
答案 0 :(得分:2)
我认为问题出在授权者发回的响应中。在政策文件中,您可以看到您正在返回Resource: event.methodArn
。
如果授权者没有缓存来自自定义授权者的响应(通常处于启用状态),通常这将起作用。当您发出请求API网关并获取与当前请求的请求ARN不匹配的缓存授权者响应时,就会遇到您遇到的问题。 This post explains more about how Lambda authorizers work, including caching。
您可以通过进入AWS控制台并为自定义授权者禁用缓存来验证是否存在此问题;完成此操作后,您将不再遇到此问题。
那么您如何解决这个长期问题?有两种选择:
禁用缓存:这是最简单的解决方案。缺点是您现在要在每个请求中调用授权者,这会给API带来更多延迟。
返回更广泛的政策:这是最好的解决方案,但更为复杂。这里有两个选项,您可以在授权者响应中返回多个Allow
策略,这些策略适用于使用该授权者的任何端点。
如果您查看format of an authorizer request,则会发现methodArn
的格式如下:
{
"type":"TOKEN",
"authorizationToken":"{caller-supplied-token}",
"methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{appId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
因此,您可能会为methodArn
返回类似的内容:
arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/e56bde3c-7c77-46c6-bdf0-ab4a8cb5f5ca
适用于此端点的任何资源的更广泛的策略是:
arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/*
如果您有多个使用相同授权者的端点,则可以返回多个策略:
{
"principalId": "user",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/GET/my-resource/*"
},
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/POST/my-resource"
}
]
}
}