0

I'm building an Angular app using AWS CDK. It's for my job, and InfoSec frown on publicly accessible S3 buckets. I'd like to use the new Distribution API without configuring the S3 bucket for website hosting. In that case, "the bucket is handled as a bucket origin and CloudFront's redirect and error handling will be used". When I set up the distribution using the following code, the root of the application works (i.e. /index.html) but the authentication redirect (/login/callback) produces an "Access Denied" XML response. How do I tell CloudFront to redirect everything to index.html?

    const bucket = new Bucket(this, "WebUIBucket", {
      versioned: false,
      removalPolicy: RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    })

     new BucketDeployment(this, "DeployWebUI", {
      sources: [Source.asset(path.resolve(__dirname, "../../frontend/dist/myapp"))],
      destinationBucket: bucket,
    })

    const cloudFront = new Distribution(this, "CloudFront", {
      defaultBehavior: {
        origin: new S3Origin(bucket),
        viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
      domainNames: [this.frontendFQDN],
      certificate: this.certificate,
      priceClass: PriceClass.PRICE_CLASS_100,
      defaultRootObject: "index.html",
    }

    const zone = HostedZone.fromLookup(this, 'Zone', { domainName: 'my.tld' })

    new ARecord(this, "frontendDNS", {
      zone: this.zone,
      recordName: 'my-angular-app',
      target: RecordTarget.fromAlias(new CloudFrontTarget(cloudFront)),
    }
Aurelia Peters
  • 2,169
  • 1
  • 20
  • 34

1 Answers1

1

Got it sorted. Thanks to this SO question I found I had to update my CloudFront distribution to the following:

    const cloudFront = new Distribution(this, "CloudFront", {
      defaultBehavior: {
        origin: new S3Origin(bucket),
        viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
      domainNames: [this.frontendFQDN],
      certificate: this.certificate,
      priceClass: PriceClass.PRICE_CLASS_100,
      defaultRootObject: "index.html",
      errorResponses: [
        {
          httpStatus: 404,
          responseHttpStatus: 200,
          responsePagePath: "/index.html",
        },
        {
          httpStatus: 403,
          responseHttpStatus: 200,
          responsePagePath: "/index.html",
        },
        {
          httpStatus: 400,
          responseHttpStatus: 200,
          responsePagePath: "/index.html",
        },
      ],
    }

What I'm doing here is redirecting errors 400, 403, and 404 back to Angular via index.html.

Aurelia Peters
  • 2,169
  • 1
  • 20
  • 34