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
491 stars 160 forks source link

Access denied from static S3 website after successful login #280

Open bpgould opened 4 months ago

bpgould commented 4 months 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 4 months 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 4 months 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 4 months 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 4 months 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 4 months 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 4 months 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
}