我有一个带有自定义授权者的1 Amazon Api Gateway设置(授权者基本上只是返回允许的任何内容)
我启用了CORS,并且正在 jQuery 网页上运行。
我有两种方法
我看到的行为是第一个请求正常,我看到它拉了 OPTIONS ,然后执行了 GET 请求。 然后,我按了 OPTIONS 的另一种方法,然后get返回了 403 ,但是如果我再次启动请求(在同一资源上),我得到了 200
我正在使用Cloudformation,但是当我使用无服务器框架时,我注意到了相同的行为。
下面是我的理智的一些屏幕截图,希望其他人已经看到了这种陌生感。
以下是我的Cloudformation YAML模板的一部分,我正在学习中。
HelloAPI:
Type: AWS::Serverless::Api
Properties:
StageName: !Sub ${Environment}
DefinitionBody:
swagger: 2.0
info:
title:
Ref: AWS::StackName
securityDefinitions:
test-authorizer:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: custom
x-amazon-apigateway-authorizer:
type: token
authorizerUri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${AuthorizerFunc.Arn}/invocations
authorizerResultTtlInSeconds: 5
paths:
/vehicles:
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${VehiclesLambda.Arn}/invocations
responses: {}
security:
- test-authorizer: []
options:
tags:
- "CORS"
summary: "CORS support"
description: "Enable CORS by returning correct headers\n"
consumes:
- "application/json"
produces:
- "application/json"
parameters: []
responses:
"200":
description: "Default response for CORS method"
headers:
Access-Control-Allow-Headers:
type: "string"
Access-Control-Allow-Methods:
type: "string"
Access-Control-Allow-Origin:
type: "string"
x-amazon-apigateway-integration:
type: "mock"
requestTemplates:
application/json: "{\n \"statusCode\" : 200\n}\n"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key'"
method.response.header.Access-Control-Allow-Methods: "'*'"
method.response.header.Access-Control-Allow-Origin: "'*'"
responseTemplates:
application/json: "{}\n"
/bookings:
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri:
!Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${BookingsLambda.Arn}/invocations
responses: {}
security:
- test-authorizer: []
options:
tags:
- "CORS"
summary: "CORS support"
description: "Enable CORS by returning correct headers\n"
consumes:
- "application/json"
produces:
- "application/json"
parameters: []
responses:
"200":
description: "Default response for CORS method"
headers:
Access-Control-Allow-Headers:
type: "string"
Access-Control-Allow-Methods:
type: "string"
Access-Control-Allow-Origin:
type: "string"
x-amazon-apigateway-integration:
type: "mock"
requestTemplates:
application/json: "{\n \"statusCode\" : 200\n}\n"
responses:
default:
statusCode: "200"
responseParameters:
method.response.header.Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key'"
method.response.header.Access-Control-Allow-Methods: "'*'"
method.response.header.Access-Control-Allow-Origin: "'*'"
responseTemplates:
application/json: "{}\n"
这是我的一切授权人:
'use strict';
const generatePolicy = function(principalId, effect, resource) {
const authResponse = {};
authResponse.principalId = principalId;
if (effect && resource) {
const policyDocument = {};
policyDocument.Version = '2012-10-17';
policyDocument.Statement = [];
const statementOne = {};
statementOne.Action = 'execute-api:Invoke';
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
return authResponse;
};
exports.handler = (event, context, callback) => {
console.log("Hit Authorizer")
console.log(event)
callback(null, generatePolicy('user123', 'Allow', event.methodArn));
};
还有其他人看到过这个,或者知道如何调试它吗?
我把它放在一个测试站点上,只是有人想看看我在看什么。
答案 0 :(得分:2)
在自定义授权者代码中,在行
statementOne.Resource = resource;
将您的资源更改为以下格式:“ arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b / * / GET /”。
在您的情况下,允许所有这些操作:
statementOne.Resource = arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/*/*/
这是AWS了解您的授权者的方式。因为在自定义授权方中,您可以从请求标头中获取用户,组等信息,然后针对您的授权数据库验证信息,并确定允许谁或什么继续执行请求类型POST / GET / OPTION,但API网关不会在您以AWS格式提供有效答案之前,不知道您的决定
{
"principalId": "yyyyyyyy", // The principal user identification associated with the token sent by the client.
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow|Deny",
"Resource": "arn:aws:execute-api:{regionId}:{accountId}:{appId}/{stage}/{httpVerb}/[{resource}/[child-resources]]"
}
]
},
"context": {
"stringKey": "value",
"numberKey": "1",
"booleanKey": "true"
},
"usageIdentifierKey": "{api-key}" # Optional
}
您可以访问此页面以了解更多信息:
答案 1 :(得分:0)
只需与AWS代表讨论类似问题。当前的问题是lambda授权者缓存,这与API Gateway缓存不同。
默认情况下,您可能会对lambda授权者进行缓存(参见照片),因此,当您最初发出请求时,您的策略(特定于单个资源)将被缓存为TTL。随后对使用SAME LAMBDA AUTHORIZER的不同资源的请求将返回原始资源(不是手头的资源)的SAME POLICY,因此,您得到403。
将返回的策略更改为更一般的方式,例如@Dominic Nguyen的答案是一种解决方案(通常涉及添加/ * s),但是您也可以执行我的操作,而只是禁用对lambda Authorizer的缓存: