You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS S3托管Web应用:如何通过预签名URL访问并阻止公共访问(权限问题排查与正确实现方案)

How to Restrict S3 Static Website to Pre-Signed URLs Only

Got it, let's break down what's going wrong here and fix it step by step. Your core issue boils down to a critical AWS IAM rule: Deny statements always take precedence over Allow statements—even for requests authenticated via pre-signed URLs. The Deny you added for index.html blocks all requests to that object, including the valid pre-signed ones you generated. Let's walk through the correct approach to lock down your site so only pre-signed URLs (or CloudFront signed URLs, if you prefer static site endpoints) work.

Step 1: Clean Up Your Bucket Policy & Disable Public Access

First, undo the settings that opened up public access and caused the conflict:

  • Delete the PublicReadGetObject Allow statement in your bucket policy (you don't want any public access to objects)
  • Remove the PrivateReadGetObject Deny statement entirely—this is what's blocking your pre-signed URLs
  • Enable Block all public access for your S3 bucket (in the bucket's Permissions tab) to ensure no accidental public access slips through.

Your bucket policy should now be minimal (or empty, unless you need to grant access to specific services like CloudFront). Here's an example if you plan to use CloudFront later:

{
  "Version": "2012-10-17",
  "Id": "PrivateBucketPolicy",
  "Statement": [
    {
      "Sid": "AllowCloudFrontAccess",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::web-portal/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::YOUR_AWS_ACCOUNT_ID:distribution/YOUR_CLOUDFRONT_DIST_ID"
        }
      }
    }
  ]
}

Step 2: Ensure the IAM Entity Generating Pre-Signed URLs Has Permissions

The AWS SDK user/role that generates the pre-signed URL must have the s3:GetObject permission for the web-portal bucket objects. Here's an example IAM policy for that entity:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::web-portal/*"
    }
  ]
}

Step 3: Use the Correct S3 Endpoint for Pre-Signed URLs

Important callout: S3 static website hosting endpoints do not support pre-signed URLs. If you try to use a pre-signed URL with the static site domain (e.g., web-portal.s3-website-us-east-1.amazonaws.com), it will fail. Instead, use the S3 REST API endpoint when generating and accessing the pre-signed URL.

Your existing SDK code is correct, but the resulting URL will look like:
https://web-portal.s3.amazonaws.com/index.html?X-Amz-Algorithm=AWS4-HMAC-SHA256&...

This is the valid endpoint for pre-signed URL access.

Optional: Use CloudFront for Static Site Endpoints + Signed URLs

If you want to keep using the static website experience (or need custom domains/HTTPS), use CloudFront with signed URLs:

  1. Create a CloudFront distribution, setting the origin to your S3 static website endpoint
  2. Configure CloudFront to require signed URLs/Cookies (in the distribution's Behaviors settings)
  3. Update your S3 bucket policy to only allow access from CloudFront (as shown earlier)
  4. Generate CloudFront signed URLs instead of S3 pre-signed URLs—these work with the CloudFront (or custom) domain.

Key Takeaways

  • Avoid using Deny statements to restrict public access; rely on disabling public permissions and enabling Block All Public Access instead
  • Pre-signed URLs depend on the IAM permissions of the entity that generates them—make sure that entity has s3:GetObject rights
  • S3 static site endpoints don't support pre-signed URLs; use the REST endpoint or CloudFront if you need the static site domain.

内容的提问来源于stack exchange,提问作者Nirojan Selvanathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:09:07