44

API Gateway (APIG),虽然它使用 CloudFront (CF),但它不支持 CDN 边缘缓存。当我将 CF 分发配置为使用 APIG 作为自定义源时,我收到权限被拒绝错误。

如何配置 CF 来解决这个问题?

4

5 回答 5

77

在 API Gateway (APIG) 通过其内部使用 CloudFront (CF) 支持边缘缓存之前,我想出了一个解决方法。

您确实可以将 CF dist 放在 APIG 前面,诀窍是强制 HTTPS 仅“查看器协议策略”并且转发 HOST 标头,因为 APIG 需要 SNI。

我将我的 CF“默认缓存行为设置”设置为不转发任何标头,并将“查看器协议策略”强制设置为“仅 HTTPS”并且它可以工作。希望这对其他人有帮助。

这是一个具有所有必需配置的 CloudFormation 资源对象(注意:我使用<stage>--<app name>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

2018 年末更新

  • CloudFormation 终于支持设置 SSL proto ver:MinimumProtocolVersion: TLSv1.1_2016
  • 我已经将这个(以及许多其他)最佳实践融入到一个 OSS 项目中:aws-blueprint
于 2015-09-28T14:23:00.307 回答
10

添加到以前的答案:

重要的是,行为路径模式实际上是匹配“真实”路径的东西。


如果 API 端点是<id>.execute-api.<region>.amazonaws.com/stage-name/my-api

而源域+路径是<id>.execute-api.<region>.amazonaws.com/stage-name

行为路径模式必须是 my-api, my-api/*, my-api/something, 等等


我不知道为什么,但我认为路径模式可以用作别名,例如:

https://www.example.com/random-name(路径模式random-name)解析为域 + 源中设置的路径,例如<id>.execute-api.<region>.amazonaws.com/stage-name.

事实并非如此。

于 2018-12-16T16:50:41.377 回答
3

如果 API Gateway 返回 403 错误:

授权标头需要“凭据”参数。授权标头需要“签名”参数。授权标头需要“SignedHeaders”参数。授权标头要求存在“X-Amz-Date”或“日期”标头。

也可能是源端点不正确。“API Gateway 将不存在路径的所有错误视为 403 权限被拒绝错误,而不是 404 未找到错误。” (请参阅此支持线程)。

我收到此错误并假设我错误地转发了 Authorization 标头,但我只是错误地配置了原始路径。

于 2017-09-22T22:37:59.470 回答
2

我只想在这里重申,对于任何遵循 AWS 高级支持知识中心指南的人,

如何使用我自己的 CloudFront 分配设置 API Gateway? https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudfront-distribution/

如果您使用 AWS 控制台设置 CloudFront 分配,根本原因是您将Cache Based on Selected Request Headers设置为all

在此处输入图像描述

将其设置为无或排除Host白名单中的标头将解决问题。

于 2020-07-01T00:10:26.593 回答
0

随着 2017 年 11 月 API Gateway 区域端点的推出,我相信现在最好将这些端点与 CloudFront 分发一起使用。有关从边缘优化 API 迁移到区域 API 和设置 CloudFront 分配的一些详细说明如下:

AWS API Gateway 应阻止使用 TLS v1

于 2019-02-06T23:42:52.097 回答