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?
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.
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.
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:
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"
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])