从API网关自定义授权器返回的401缺少'访问控制 - 允许 - 来源'头

时间:2016-04-28 11:25:04

标签: amazon-web-services cors aws-lambda aws-api-gateway

为了防止尚未登录的用户通过AWS API网关调用我的lambda函数,我使用自定义授权者lambda解决方案。

如果请求被授权(200)并且我从被叫lambda得到响应,一切正常,我得到Access-Control-Allow-Origin标题。

但是如果请求未被授权,我会得到一个没有Access-Control-Allow-Origin标头的401,因此阻止我读取响应的401状态并将用户重定向到登录页面。

我认为这是因为自定义自动化机制不知道请求需要使用CORS。有谁知道这实际上是问题吗?你知道任何可能的解决方案吗?

7 个答案:

答案 0 :(得分:16)

我很高兴地宣布新的网关响应功能,该功能允许您自定义不会调用您的集成的请求的错误响应。这允许您确保包含CORS头,即使在失败的身份验证请求中也是如此。

在我们的documentation中阅读更多内容,其中包括一个CORS示例。

答案 1 :(得分:13)

是的,这是API Gateway自定义授权程序的已知错误。谢谢让我们注意到这个。我们在部署修复程序时会更新此帖子。不便之处敬请原谅。

答案 2 :(得分:6)

解决所有4XX错误(包括401错误)的最简单方法是转到“网关响应”,然后选择“默认4XX”,然后添加标题“Access-Control-Allow-Origin”值'*'。

查看屏幕截图:

答案 3 :(得分:4)

因为我花了一些时间来弄清楚如何将它们整合在Cloud Formation中,所以这里有一个片段展示了如何设置它。

...
    MyApi:
      Type: "AWS::ApiGateway::MyApi"
      Properties:
        Description: My API
        Name: "my-api"
    MyApiAuthorizer:
      Type: "AWS::ApiGateway::Authorizer"
      Properties:
         Name: "my-api-authorizer"
         IdentitySource: "method.request.header.Authorization"
         ProviderARNs:
           - !GetAtt MyUserPool.Arn
         RestApiId: !Ref MyAApi
         Type: COGNITO_USER_POOLS
    MyApiGatewayResponse:
      Type: "AWS::ApiGateway::GatewayResponse"
      Properties:
        ResponseParameters:
          "gatewayresponse.header.Access-Control-Allow-Origin": "'*'"
          "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
        ResponseType: UNAUTHORIZED
        RestApiId: !Ref MyApi
        StatusCode: "401"

答案 4 :(得分:1)

如果像我一样,您在API Gateway V2(尤其是HTTP API)中遇到问题-ANY方法似乎不适用于即插即用的CORS产品。我必须为每个方法分别创建一个路由(令人讨厌的是,因为它们都调用相同的lambda函数,但是很好)。

答案 5 :(得分:0)

除了上述答案外,如果您不使用Cloudformation / SAM模板,则可以使用以下python脚本保存一些手动步骤:

import boto3
import sys

if len(sys.argv) != 3:
    print("usage: python script.py <API_ID> <STAGE>")
    exit()

client = boto3.client('apigateway')

response = client.put_gateway_response(
    restApiId=sys.argv[1],
    responseType='UNAUTHORIZED',
    statusCode='401',
    responseParameters={
        "gatewayresponse.header.Access-Control-Allow-Origin": "'*'",
        "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
    }
)
response = client.create_deployment(
    restApiId=sys.argv[1],
    stageName=sys.argv[2])

答案 6 :(得分:0)

这对我有用(在AWS :: APIGateway:定义中内联)

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Dev
      GatewayResponses:
        UNAUTHORIZED:
          StatusCode: 401
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"
        ACCESS_DENIED:
          StatusCode: 403
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"
        DEFAULT_5XX:
          StatusCode: 500
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"
        RESOURCE_NOT_FOUND:
          StatusCode: 404
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"  

可用的GatewayResponses命名为:

指定了无效的GatewayResponseType。有效选项是 DEFAULT_INTERNAL, DEFAULT_4XX, DEFAULT_5XX, RESOURCE_NOT_FOUND, 未经授权, 拒绝访问, AUTHORIZER_FAILURE, AUTHORIZER_CONFIGURATION_ERROR, MISSING_AUTHENTICATION_TOKEN, INVALID_SIGNATURE, EXPIRED_TOKEN, INTEGRATION_FAILURE, INTEGRATION_TIMEOUT, API_CONFIGURATION_ERROR, UNSUPPORTED_MEDIA_TYPE, REQUEST_TOO_LARGE, BAD_REQUEST_PARAMETERS, BAD_REQUEST_BODY, 节流 超出配额, INVALID_API_KEY, WAF_FILTERED

因此您可以为这些受控AWS响应指定响应自定义。