web-dev-qa-db-fra.com

L'en-tête 'Access-Control-Allow-Allow-Origin' manquant dans l'en-tête 401 retour d'un API Gateway

Afin d'empêcher les utilisateurs qui ne se sont pas connectés d'appeler ma fonction lambda via AWS API Gateway, j'utilise la solution lambda Custom Authorizer.

Si la demande est autorisée (200) et que le lambda appelé me ​​donne une réponse, tout se passe bien et l’en-tête Access-Control-Allow-Origin apparaît.

Mais si la demande n'est pas autorisée, j'obtiens un 401 sans en-tête Access-Control-Allow-Origin, ce qui m'empêche de lire le statut 401 de la réponse et de rediriger l'utilisateur vers la page de connexion.

Je pense que cela est dû au fait que le mécanisme d'authentification personnalisée ne sait pas que la demande doit utiliser CORS. Est-ce que quelqu'un sait que c'est effectivement le problème? Êtes-vous au courant de toute solution possible?

36
hanbzu

Je suis heureux d'annoncer la nouvelle fonctionnalité Gateway Responses, qui vous permet de personnaliser les réponses d'erreur pour les demandes qui n'appellent pas votre intégration. Cela vous permet de vous assurer que les en-têtes CORS sont inclus, même en cas d'échec des demandes d'authentification. 

Lisez-en plus dans notre documentation , qui inclut un exemple CORS.

14
Bob Kinney

Oui, il s'agit d'un bogue connu avec les autoriseurs personnalisés API Gateway. Merci d'avoir porté cela à notre attention. L'équipe mettra à jour ce post lorsque nous aurons déployé un correctif. Mes excuses pour le derangement. 

12
Lorenzo de Lara

Le moyen le plus simple de résoudre ce problème pour toutes les erreurs 4XX (y compris les erreurs 401) consiste à accéder à "Réponses de la passerelle", puis à sélectionner "4XX par défaut", puis à ajouter l'en-tête "Accès-Contrôle-Autoriser-Origine" avec la valeur '* '.

Voir la capture d'écran: 

5
Alex Robinson

Comme il m'a fallu un certain temps pour comprendre comment assembler tout cela dans Cloud Formation, voici un extrait montrant comment le configurer.

...
    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"
3
pisomojado

En ajoutant aux réponses ci-dessus, si vous n'utilisez pas le modèle Cloudformation/SAM, vous pouvez enregistrer certaines étapes manuelles à l'aide de ce script 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])
0
amsh