AWS API 网关自定义授权方奇怪显示错误
AWS API Gateway custom Authorizer strange showing error
上下文如下:
- 我在 API 网关中设置了一个资源。 /user/company
- 这个资源有2个方法。获取并 POST.
- 我已经为此资源配置了自定义授权方。
问题:
- 我可以通过发送正确的授权信息来调用 GET 方法,我得到了预期的结果。
- 我尝试发送 POST 请求,但收到以下错误:
{
"message": "User is not authorized to access this resource"
}
- 如果我等几分钟,然后调用 POST 方法,它将起作用。
- 如果在调用 POST 方法并得到结果后我调用 GET 方法,它会显示与上述相同的错误。
此外,我已为授权方禁用缓存。
可能是什么原因导致了这个问题?
这可以通过 buggy 的回答中描述的两种方式解决:https://forum.serverless.com/t/rest-api-with-custom-authorizer-how-are-you-dealing-with-authorization-and-policy-cache/3310
简短版本:
- 将自定义授权策略资源设置为“*”
- 或者(如果您可以不使用缓存)将自定义授权方的 TTL 设置为 0
有关详细信息,请参阅 Michael 的
在您的自定义策略构建代码中使用,节点 js 模块 aws-auth-policy
您可以使用的 Nodejs 部分,
AuthPolicy.prototype.allowAllMethods = function () {
addMethod.call(this, "allow", "*", "*", null);
}
在代码中
const AuthPolicy = require('aws-auth-policy');
const policy = new AuthPolicy(principalId, awsAccountId, apiOptions);
// policy.allowMethod(method, resource);
policy.allowAllMethods();
const authResponse = policy.build();
如果您使用 event.methodArn
作为生成策略的资源并在不同功能之间共享授权方,则会发生此错误,因为策略缓存的工作原理。对于提供的令牌,它在整个 API 中缓存策略,对于同一 API 和阶段(如果它们共享相同的授权方)中的所有方法和资源,它将是相同的缓存条目。
例如,当向 GET /users
发出请求时,ARN 将如下所示:
arn:aws:execute-api:us-1:abc:123/prod/GET/users
下一次调用具有相同身份验证令牌的任何端点将使用缓存策略,该策略是在第一次调用 GET /users
时创建的。该缓存策略的问题是它的资源只允许一个特定的资源arn: ... /prod/GET/users
,任何其他资源都将被拒绝。
根据您想要限制策略权限的程度,您可以在创建策略时提及所有可能的资源
{
"principalId": "user",
"policyDocument": {
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": [
"arn:aws:execute-api:us-1:abc:123/prod/GET/v1/users",
"arn:aws:execute-api:us-1:abc:123/prod/POST/v1/users",
"arn:aws:execute-api:us-1:abc:123/prod/GET/v1/orders"
]
}
],
"Version": "2012-10-17"
}
}
或使用wildcards
"Resource": "arn:aws:execute-api:us-1:abc:123/prod/*/v?/*"
甚至
"Resource": "*"
您可以使用 policy variables 一些高级模板。
也可以使用黑名单方法,允许使用通配符的所有内容,然后在另一个策略声明中拒绝特定资源。
来源:
我通过将 AuthorizerResultTtlInSeconds
设置为 0
来解决这个问题。
这是因为我使用的是共享授权方。然而,授权方通过读取请求的事件上下文并授予 IAM 然后调用特定的 lambda 来工作。
因为授权方是共享的,所以它正在缓存响应,这是针对特定 lambda 的 IAM,TTL 为(在我的例子中)300 秒。
因此,我可以在一分钟内呼叫一个 API,下一分钟就不能呼叫。
将上面的值更改为 0 解决了这个问题。
我遇到了同样的问题 'User is not authorized to access this resource' 我的错误是我没有在我的 api 网关
的授权方中提供 OAuth 范围
感谢@Orest 的回答!
要在 Auth0 custom authorizer 中的策略资源上设置通配符,请转至 lib.js
第 57 行并更改:
.then((decoded)=> ({
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', params.methodArn),
context: { scope: decoded.scope }
}));
来自
.then((decoded)=> ({
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', "*"),
context: { scope: decoded.scope }
}));
希望对大家有所帮助...
上下文如下:
- 我在 API 网关中设置了一个资源。 /user/company
- 这个资源有2个方法。获取并 POST.
- 我已经为此资源配置了自定义授权方。
问题:
- 我可以通过发送正确的授权信息来调用 GET 方法,我得到了预期的结果。
- 我尝试发送 POST 请求,但收到以下错误:
{
"message": "User is not authorized to access this resource"
}
- 如果我等几分钟,然后调用 POST 方法,它将起作用。
- 如果在调用 POST 方法并得到结果后我调用 GET 方法,它会显示与上述相同的错误。
此外,我已为授权方禁用缓存。
可能是什么原因导致了这个问题?
这可以通过 buggy 的回答中描述的两种方式解决:https://forum.serverless.com/t/rest-api-with-custom-authorizer-how-are-you-dealing-with-authorization-and-policy-cache/3310
简短版本:
- 将自定义授权策略资源设置为“*”
- 或者(如果您可以不使用缓存)将自定义授权方的 TTL 设置为 0
有关详细信息,请参阅 Michael 的
在您的自定义策略构建代码中使用,节点 js 模块 aws-auth-policy 您可以使用的 Nodejs 部分,
AuthPolicy.prototype.allowAllMethods = function () {
addMethod.call(this, "allow", "*", "*", null);
}
在代码中
const AuthPolicy = require('aws-auth-policy');
const policy = new AuthPolicy(principalId, awsAccountId, apiOptions);
// policy.allowMethod(method, resource);
policy.allowAllMethods();
const authResponse = policy.build();
如果您使用 event.methodArn
作为生成策略的资源并在不同功能之间共享授权方,则会发生此错误,因为策略缓存的工作原理。对于提供的令牌,它在整个 API 中缓存策略,对于同一 API 和阶段(如果它们共享相同的授权方)中的所有方法和资源,它将是相同的缓存条目。
例如,当向 GET /users
发出请求时,ARN 将如下所示:
arn:aws:execute-api:us-1:abc:123/prod/GET/users
下一次调用具有相同身份验证令牌的任何端点将使用缓存策略,该策略是在第一次调用 GET /users
时创建的。该缓存策略的问题是它的资源只允许一个特定的资源arn: ... /prod/GET/users
,任何其他资源都将被拒绝。
根据您想要限制策略权限的程度,您可以在创建策略时提及所有可能的资源
{
"principalId": "user",
"policyDocument": {
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": [
"arn:aws:execute-api:us-1:abc:123/prod/GET/v1/users",
"arn:aws:execute-api:us-1:abc:123/prod/POST/v1/users",
"arn:aws:execute-api:us-1:abc:123/prod/GET/v1/orders"
]
}
],
"Version": "2012-10-17"
}
}
或使用wildcards
"Resource": "arn:aws:execute-api:us-1:abc:123/prod/*/v?/*"
甚至
"Resource": "*"
您可以使用 policy variables 一些高级模板。
也可以使用黑名单方法,允许使用通配符的所有内容,然后在另一个策略声明中拒绝特定资源。
来源:
我通过将 AuthorizerResultTtlInSeconds
设置为 0
来解决这个问题。
这是因为我使用的是共享授权方。然而,授权方通过读取请求的事件上下文并授予 IAM 然后调用特定的 lambda 来工作。
因为授权方是共享的,所以它正在缓存响应,这是针对特定 lambda 的 IAM,TTL 为(在我的例子中)300 秒。
因此,我可以在一分钟内呼叫一个 API,下一分钟就不能呼叫。
将上面的值更改为 0 解决了这个问题。
我遇到了同样的问题 'User is not authorized to access this resource' 我的错误是我没有在我的 api 网关
的授权方中提供 OAuth 范围感谢@Orest 的回答!
要在 Auth0 custom authorizer 中的策略资源上设置通配符,请转至 lib.js
第 57 行并更改:
.then((decoded)=> ({
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', params.methodArn),
context: { scope: decoded.scope }
}));
来自
.then((decoded)=> ({
principalId: decoded.sub,
policyDocument: getPolicyDocument('Allow', "*"),
context: { scope: decoded.scope }
}));
希望对大家有所帮助...