401 return from an API Gateway Custom Authorizer i

2020-02-02 05:59发布

In order to prevent users who have not logged in to call my lambda function through the AWS API Gateway, I'm using the Custom Authorizer lambda solution.

If the request is authorized (200) and I get a response from the called lambda everything works fine and I get the Access-Control-Allow-Origin header.

But if the request is not authorized, I get a 401 that has no Access-Control-Allow-Origin header, therefore preventing me from reading the 401 status of the response and redirecting the user to the log-in page.

I believe this is because the Custom Autorization mechanism is unaware that the request needs to use CORS. Does anyone know that this is actually the issue? Are you aware of any possible solution?

6条回答
不美不萌又怎样
2楼-- · 2020-02-02 06:21

I'm happy to announce the new Gateway Responses feature which allows you to customize the error responses for requests that don't call your integration. This allows you to ensure that CORS headers are included, even on failed auth requests.

Read more in our documentation, which includes a CORS example.

查看更多
Bombasti
3楼-- · 2020-02-02 06:22

Yes, this is a known bug with API Gateway custom authorizers. Thanks for bringing this to our attention. The team will update this post when we've deployed a fix. Apologies for the inconvenience.

查看更多
唯我独甜
4楼-- · 2020-02-02 06:22

The easiest way to resolve this for all 4XX error (including 401 errors) is to go to "Gateway Responses" and then select "Default 4XX" and then add the the header "Access-Control-Allow-Origin" with the value '*'.

See screenshot:

查看更多
够拽才男人
5楼-- · 2020-02-02 06:26

Adding to the answers above, if you're not using Cloudformation/SAM template, you can save yourself some manual steps using this python script:

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])
查看更多
Rolldiameter
6楼-- · 2020-02-02 06:38

Because it took me a while to figure out how to put it all together in Cloud Formation, here is a snippet showing how to set it up.

...
    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"
查看更多
仙女界的扛把子
7楼-- · 2020-02-02 06:45

This works for me (inline in AWS::APIGateway: definition)

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: "'*'"  

The available GatewayResponses Naming are:

DEFAULT_INTERNAL
DEFAULT_4XX
DEFAULT_5XX
RESOURCE_NOT_FOUND
UNAUTHORIZED
ACCESS_DENIED
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
THROTTLED
QUOTA_EXCEEDED
INVALID_API_KEY
WAF_FILTERED

So you could specify the Response customization for these Controlled AWS responses.

查看更多
登录 后发表回答