如何在API网关前添加CloudFront

时间:2015-09-28 14:23:00

标签: amazon-web-services cdn amazon-cloudfront aws-api-gateway

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

如何配置CF来解决此问题?

5 个答案:

答案 0 :(得分:51)

直到API网关(APIG)通过其内部使用CloudFormation(CF)支持边缘缓存,我提出了一种解决方法。

你确实可以把CF dist放在APIG面前,诀窍是只强制使用HTTPS"查看器协议策略"并且 NOT 转发HOST标头,因为APIG需要SNI。

我设置了我的CF"默认缓存行为设置"不转发任何标题,强制"查看器协议政策"到"仅限HTTPS;"它的工作原理。希望这有助于其他人。

这是一个具有所有必需配置的CloudFormation资源对象(注意:我对StackName使用约定<stage>--<app name>):

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原型:MinimumProtocolVersion: TLSv1.1_2016
  • 我已将此(和许多其他)最佳做法纳入OSS项目:aws-blueprint

答案 1 :(得分:4)

添加到以前的答案:

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


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

原始域+路径为<id>.execute-api.<region>.amazonaws.com/stage-name

行为路径模式必须为 my-apimy-api/*my-api/something


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

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

不是这样。

答案 2 :(得分:2)

如果API Gateway返回403错误:

  

授权标题需要&#39;凭据&#39;参数。授权   标题需要&#39;签名&#39;参数。授权标头需要   &#39; SignedHeaders&#39;参数。授权标头需要存在   要么是&#39; X-Amz-Date&#39;或者日期&#39;报头中。

也可能是原点端点不正确。 &#34; API Gateway将所有错误视为不存在的路径,因为403权限被拒绝错误而不是404未找到错误。&#34; (见this support thread)。

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

答案 3 :(得分:2)

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

如何使用自己的CloudFront发行版设置API网关? https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudfront-distribution/

如果您使用AWS控制台设置CloudFront分配,则根本原因是将基于所选请求标头的缓存设置为全部

enter image description here

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

答案 4 :(得分:0)

随着API Gateway区域端点于2017年11月启动,我认为现在最好将它们与CloudFront Distributions一起使用。有关从Edge Optimized API迁移到Regional API以及设置CloudFront分布的一些详细说明,请参见:

AWS API Gateway should prevent use of TLS v1

相关问题