Why does my CloudFront distribution give access denied when I have any path or query params in the URL?

0

For example www.example.com loads fine but on load if the URL changes to www.example.com/upload and then I click reload in the browser I get an access denied. The same behaviour occurs when I have query parameters in the URL, I will admit I haven't read the docs thoroughly, but would be grateful if someone just directs my in the right direction. Thanks. Enter image description here
Enter image description here

More details:

  • My bucket is private
  • SSE-KMS is disabled
  • I use an OAC policy to access the contents
  • I have alternative aliases configured to point to my Route53 domain name
  • I have this specified in my S3 bucket policy: "Action": "s3:GetObject", "Resource": "arn:aws:s3:::staging-filtering-bucket/*",
  • I have this in my CORS S3 config: [ { "AllowedHeaders": [], "AllowedMethods": [ "GET" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [], "MaxAgeSeconds": 0 } ]

This is my Terraform configuration for my CloudFront distribution:

resource "aws_cloudfront_origin_access_control" "frontend_oac" {
  count                             = var.create_resources ? 1 : 0
  name                              = aws_s3_bucket.frontend_bucket[0].bucket_regional_domain_name
  description                       = "Origin Access Control policy for frontends"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

resource "aws_cloudfront_distribution" "s3_distribution" {
  count = var.create_resources ? 1 : 0
  origin {
    domain_name              = aws_s3_bucket.frontend_bucket[0].bucket_regional_domain_name
    origin_access_control_id = aws_cloudfront_origin_access_control.frontend_oac[0].id
    origin_id                = var.s3_origin_id

    origin_shield {
      enabled = true
      origin_shield_region = "eu-west-2"
    }
  }

  enabled = true

  is_ipv6_enabled     = var.is_ipv6_enabled
  comment             = "Cloudfront for the frontend application."
  default_root_object = var.default_root_object
	
  logging_config {
    include_cookies = false
    bucket          = module.log_bucket[0].s3_bucket_bucket_domain_name
    prefix          = "${var.environment}-${var.name}"
  }

  aliases = var.aliases

  default_cache_behavior {
    allowed_methods  = var.default_cache_allowed_methods
    cached_methods   = var.default_cached_methods
    target_origin_id = var.s3_origin_id

    forwarded_values {
      query_string = true

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
    compress               = var.compress
    viewer_protocol_policy = var.viewer_protocol_policy
  }
  
  price_class = var.price_class

  restrictions {
    geo_restriction {
      restriction_type = var.restriction_type
      locations        = var.geo_locations
    }
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate_validation.cert_validation[0].certificate_arn
    minimum_protocol_version = "TLSv1.2_2021"
    ssl_support_method       = "sni-only"
  }

  depends_on = [
    aws_s3_bucket.frontend_bucket
  ]
}
taxmann
gefragt vor 7 Monaten314 Aufrufe
1 Antwort
1
Akzeptierte Antwort

This isn't about query parameters, it's about finding the "root" object in a "folder".

First: S3 doesn't have folders. That we use the "/" character to separate objects names in S3 and we treat them like folders is merely a way for humans to deal with things easily.

Second: In CloudFront you will have set the default object somewhere - perhaps it is index.html. So www.example.com means CloudFront will get index.html from S3. But when you request www.example.com/something/ CloudFront wants to find something/ from S3 which doesn't exist.

But there is a solution: https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/

profile pictureAWS
EXPERTE
beantwortet vor 7 Monaten
profile picture
EXPERTE
überprüft vor 7 Monaten
  • Thank you for your response, the S3 bucket keys make a lot of sense.

    Since I'm hosting an SPA vue.js application after two days of battling with this issue the solution seems to be to create a custom error response in CloudFront in the 'Error Pages' tab - select the '403:Forbidden' HTTP Error code and configure the Response page path to be '/index.html' with a HTTP response code to 200:OK.

    Writing this comment here for anyone else struggling with this issue, hope you don't have to fight with this for 2 days like I had to.

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen