aws-samples / cloudfront-authorization-at-edge

Protect downloads of your content hosted on CloudFront with Cognito authentication using cookies and Lambda@Edge
https://aws.amazon.com/blogs/networking-and-content-delivery/authorizationedge-using-cookies-protect-your-amazon-cloudfront-content-from-being-downloaded-by-unauthenticated-users/
MIT No Attribution
468 stars 158 forks source link

Access denied from static S3 website after successful login #280

Open bpgould opened 1 month ago

bpgould commented 1 month ago

following up from https://github.com/aws-samples/cloudfront-authorization-at-edge/issues/51

I have encountered a similar issue:

I have the same issue when deploying with following config:

resource "aws_serverlessapplicationrepository_cloudformation_stack" "cloudfront_authorization_at_edge" {
  name             = "CloudFrontAuthorizationAtEdge"
  application_id   = "arn:aws:serverlessrepo:us-east-1:520945424137:applications/cloudfront-authorization-at-edge"
  semantic_version = "2.3.0"
  capabilities = [
    "CAPABILITY_IAM",
    "CAPABILITY_RESOURCE_POLICY",
  ]

  parameters = {
    # Uncomment and modify the parameters as needed
    # AdditionalCookies: "{}"
    AlternateDomainNames : "private.mydomain.com"
    # CloudFrontAccessLogsBucket: ""
    # CookieCompatibility: "amplify"
    # CookieSettings: "{\"idToken\": null,\"accessToken\": null,\"refreshToken\": null,\"nonce\": null}"
    # CreateCloudFrontDistribution : "true"
    # CustomOriginDomainName: ""
    # CustomOriginHeaderName: ""
    # CustomOriginHeaderValue: ""
    DefaultRootObject : ""
    EmailAddress : "email@gmail.com"
    EnableSPAMode : "false"
    # HttpHeaders: "{\"Content-Security-Policy\": \"default-src 'none'; img-src 'self'; script-src 'self' https://code.jquery.com https://stackpath.bootstrapcdn.com; style-src 'self' 'unsafe-inline' https://stackpath.bootstrapcdn.com; object-src 'none'; connect-src 'self' https://*.amazonaws.com https://*.amazoncognito.com\",\"Strict-Transport-Security\": \"max-age=31536000; includeSubdomains; preload\",\"Referrer-Policy\": \"same-origin\",\"X-XSS-Protection\": \"1; mode=block\",\"X-Frame-Options\": \"DENY\",\"X-Content-Type-Options\": \"nosniff\"}"
    # LogLevel: "none"
    OAuthScopes : "phone,email,profile,openid,aws.cognito.signin.user.admin"
    OriginAccessIdentity : "${aws_cloudfront_origin_access_identity.oai.id}"
    # PermissionsBoundaryPolicyArn: ""
    # RedirectPathAuthRefresh: "/refreshauth"
    # RedirectPathSignIn: "/parseauth"
    # RedirectPathSignOut: "/"
    # ResourceSuffix: ""
    # RewritePathWithTrailingSlashToIndex: "false"
    S3OriginDomainName : "something.s3.us-east-2.amazonaws.com"
    # SignOutUrl: "/signout"
    # UserPoolArn : ""
    # UserPoolAuthDomain : ""
    # UserPoolClientId : ""
    # UserPoolClientSecret: ""
    # UserPoolGroupName: ""
    # Version: "2.3.0"
    # WebACLId: ""
  }
}

when navigating to the CloudFront Distribution URL I get:

This XML file does not appear to have any style information associated with it. The document tree is shown below. <Error> <Code>AccessDenied</Code> <Message>Access Denied</Message> <RequestId>E5Q5TY2V8N7SFAHW</RequestId> <HostId>xM7ISQL6LsSlrwZ5IKBKsUxR+LEZMdpINQM2ZTBU5J1owOcPSSe0o84yj1cx9MYVkE21xOzr19HhCFJi2OuFjw==</HostId> </Error>

When investigating the ParseAuth or HttpHeadersHandler, etc Lambda I see in the console:

There was an error while making a request to StartQuery Log group '/aws/lambda/serverlessrepo-CloudFrontAuthoriz-ParseAuthHandler-UUKhV0aiSBqS' does not exist for account ID '547...' (Service: AWSLogs; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 292cb6cb-488f-4d20-a52f-ec09315a9953; Proxy: null)

bpgould commented 1 month ago

also for clarity, I have the site deployed into the root of the s3 bucket as well as site/ and tried setting the root object as empty, 'index.html', and 'site/index.html'. None yielded any different behavior. It appears that the log groups were not created.

bpgould commented 1 month ago

When lookin into serverlessrepo-CloudFrontAu-LambdaEdgeExecutionRole-DXsn3O05DURm

I see that the trust relationship is correct but the policy is:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

and should be like:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "logs:CreateLogGroup",
      "Resource": "arn:aws:logs:region:accountId:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:region:accountId:log-group:/aws/lambda/functionName:*"
      ]
    }
  ]
}

the error mentioned above is referenced here: https://repost.aws/knowledge-center/lambda-cloudwatch-log-streams-error

ottokruse commented 1 month ago

About accessing Lambda@Edge logs

This is different from "normal" Lambda. Assuming a lambda with the name "abc" it would normally write to log group "/aws/lambda/abc" in the same region as the Lambda -- but this is not so for Lambda@Edge. So for Lambda@Edge, the link in the Lambda UI that takes you to the log group would actually always show you "The specified log group does not exist" ––as you've found.

For Lambda@Edge the log group will be in the region where the Lambda@Edge function was executed (which can be any region on the Globe), and will have a name like so: /aws/lambda/us-east-1.abc

The easiest way to locate the right log group and the right region, is to use the CloudFront monitoring dashboard (https://console.aws.amazon.com/cloudfront/v2/home#/monitoring) and navigate to the lambda function logs in the right region, from there.

Hope that helps. Let us know where your investigation leads.

ottokruse commented 1 month ago

Added that info the the README https://github.com/aws-samples/cloudfront-authorization-at-edge?tab=readme-ov-file#accessing-lambdaedge-function-logs

Thanks for the nudge :)

bpgould commented 1 month ago

I learned something new. I would like to leave this open until I find the access denied issue though since it appears other users have had the same issue without any documented fix.

bpgould commented 1 month ago

The issue was needing to set the bucket policy to allow the OAI. It would be favorable for the project to switch to new OAC and also update the policy automatically, since that is possible via the console --> Cloudfront > Distributions > xyz-123 > Edit Origin protected-origin (created by tool) > Origin Access > Bucket Policy > Yes, update the bucket policy

I got it working this way then turned it back off and replicated in terraform via:

resource "aws_s3_bucket_policy" "bucket-policy" {
  bucket = aws_s3_bucket.<redacted>.id

  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "2",
      "Effect": "Allow",
      "Principal": {
        "AWS": "${aws_cloudfront_origin_access_identity.oai.iam_arn}"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::<redacted>/*"
    }
  ]
}
POLICY
}