API Gateway (APIG), bien qu’elle utilise CloudFront (CF), elle ne prend pas en charge la mise en cache CDN Edge. Lorsque j'ai configuré une distribution CF pour qu'elle utilise APIG en tant qu'origine personnalisée, j'obtiens une erreur d'autorisation refusée.
Comment configurer CF pour résoudre ce problème?
Jusqu'à ce que la passerelle API (APIG) prenne en charge la mise en cache Edge via son utilisation interne de CloudFormation (CF), je propose une solution de contournement.
Vous pouvez en effet mettre CF dist devant APIG, l’astuce consiste à forcer HTTPS uniquement "Stratégie de protocole du visualiseur" ET à ne pas transmettre l’en-tête de l’hôte, car APIG a besoin du SNI.
J'ai configuré mes "Paramètres de comportement du cache par défaut" de la CF pour qu'ils ne transmettent aucun en-tête, et j'ai forcé "Stratégie de protocole du visualiseur" à "HTTPS uniquement" et cela fonctionne. J'espère que cela aide les autres.
Voici un objet de ressource CloudFormation qui a toute la configuration requise (Remarque: j'utilise la convention <stage>--<app name>
pour StackName):
CloudFront:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
IPV6Enabled: true
HttpVersion: http2
Comment: !Join [ '--', [!Ref 'AWS::StackName', ' Cloud Front']]
Aliases: [!Ref CloudFrontCname]
ViewerCertificate:
AcmCertificateArn: !Ref AcmCertificateArn
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.1_2016
Origins:
- Id: APIGOrigin
DomainName: !Sub
- ${apigId}.execute-api.${AWS::Region}.amazonaws.com
- { apigId: !Ref ApiGatewayLambdaProxy }
OriginPath: !Sub
- /${Stage}
- { Stage: !Select [ "0", !Split [ '--', !Ref 'AWS::StackName' ] ] }
CustomOriginConfig:
# HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: https-only
OriginCustomHeaders:
- HeaderName: 'Verify-From-Cf'
HeaderValue: !Ref VerifyFromCfHeaderVal
DefaultCacheBehavior:
AllowedMethods: ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
CachedMethods: ["GET", "HEAD", "OPTIONS"]
ForwardedValues:
Headers:
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Authorization
# - Host APIG needs to use SNI
QueryString: true
TargetOriginId: APIGOrigin
ViewerProtocolPolicy: https-only
Compress: true
DefaultTTL: 0
CustomErrorResponses:
- ErrorCachingMinTTL: 0
ErrorCode: 400
- ErrorCachingMinTTL: 1
ErrorCode: 403
- ErrorCachingMinTTL: 5
ErrorCode: 500
DNSARecord:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Ref 'AWS::StackName'
Name: !Ref CloudFrontCname
Type: A
HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
AliasTarget:
HostedZoneId: !Ref Route53HostedZoneId
DNSName: !GetAtt CloudFront.DomainName
DNSAAAARecord:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Ref 'AWS::StackName'
Name: !Ref CloudFrontCname
Type: AAAA
HostedZoneName: !Join ['.', [ !Select [1, !Split ['.', !Ref CloudFrontCname]], !Select [2, !Split ['.', !Ref CloudFrontCname]], '']]
AliasTarget:
HostedZoneId: !Ref Route53HostedZoneId
DNSName: !GetAtt CloudFront.DomainName
Mises à jour fin 2018
MinimumProtocolVersion: TLSv1.1_2016
Si API Gateway renvoie une erreur 403 avec:
L'en-tête d'autorisation nécessite le paramètre 'Credential'. Autorisation l'en-tête nécessite le paramètre 'Signature'. L'en-tête d'autorisation nécessite Paramètre 'SignedHeaders'. L'en-tête d'autorisation requiert l'existence de soit un en-tête 'X-Amz-Date' ou 'Date'.
il se peut également que le noeud final Origin soit incorrect. "API Gateway traite toutes les erreurs sur des chemins inexistants comme des erreurs 403 d'autorisation refusées plutôt qu'une erreur 404 non trouvée." (voir ce fil de support ).
J'ai eu cette erreur et j'ai supposé que je transmettais incorrectement l'en-tête Authorization, mais j'avais simplement mal configuré le chemin d'origine.
Ajout aux réponses précédentes:
il est important que le modèle de chemin de comportement corresponde en réalité à un chemin "réel".
Si le point de terminaison de l'API est <id>.execute-api.<region>.amazonaws.com/stage-name/my-api
Et le domaine d'origine + chemin est <id>.execute-api.<region>.amazonaws.com/stage-name
Le modèle de chemin de comportement doit êtremy-api
, my-api/*
, my-api/something
, etc.
Je ne sais pas pourquoi, mais je pensais que ce type de chemin pouvait être utilisé comme alias, par exemple:
https://www.example.com/random-name (modèle de chemin random-name
) est résolu en domaine + chemin défini dans Origine, par exemple <id>.execute-api.<region>.amazonaws.com/stage-name
.
Ce n'est pas le cas.
Avec le lancement des points finaux régionaux API Gateway en novembre 2017, je pense qu'il est maintenant optimal de les utiliser avec les distributions CloudFront au sommet. Voici des instructions détaillées pour passer des API Edge Optimized aux API régionales et configurer les distributions CloudFront: