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

如何为特定群组配置Amazon S3静态网站的私密访问权限?

给Amazon S3静态网站添加HTTP基础认证(类似.htaccess)

我明白你想要给S3静态网站加上像Apache .htaccess那样的用户名密码验证,而IP限制因为没法收集所有访问者的IP所以行不通——这确实是个很常见的需求。咱先明确一点:S3本身并不直接支持HTTP基础认证,所以得借助CloudFront来实现这个功能,下面给你两个实用的方案,你可以根据自己的场景选:

方案一:CloudFront + Lambda@Edge 实现灵活认证

这个方案适合需要稍微复杂逻辑的场景(比如从密钥管理服务拉取密码),步骤如下:

1. 创建Lambda@Edge函数

Lambda@Edge是运行在CloudFront边缘节点的Lambda函数,必须在us-east-1区域创建:

  • 打开Lambda控制台,选择us-east-1区域,创建新函数,选择Python 3.x运行时。
  • 替换函数代码为以下内容(记得修改USERNAME和PASSWORD为你自己的凭证):
import base64

USERNAME = "your-custom-username"
PASSWORD = "your-custom-password"

def lambda_handler(event, context):
    request = event['Records'][0]['cf']['request']
    headers = request['headers']
    
    # 检查是否携带Authorization头
    if 'authorization' not in headers:
        return generate_unauthorized_response()
    
    # 解码认证信息
    auth_header = headers['authorization'][0]['value']
    encoded_creds = auth_header.split(' ')[1]
    decoded_creds = base64.b64decode(encoded_creds).decode('utf-8')
    username, password = decoded_creds.split(':')
    
    # 验证凭证
    if username != USERNAME or password != PASSWORD:
        return generate_unauthorized_response()
    
    # 认证通过,放行请求
    return request

def generate_unauthorized_response():
    return {
        'status': '401',
        'statusDescription': 'Unauthorized',
        'headers': {
            'www-authenticate': [{
                'key': 'WWW-Authenticate',
                'value': 'Basic realm="Restricted S3 Site"'
            }]
        }
    }
  • 发布函数版本(Lambda@Edge需要使用已发布的版本),然后在函数控制台的「Actions」里选择「Deploy to Lambda@Edge」,关联到你的CloudFront分发的Viewer Request事件(这个事件会在CloudFront收到用户请求后立刻触发)。

2. 配置S3桶的访问限制

为了防止用户绕开CloudFront直接访问S3,需要设置S3桶的权限:

  • 创建CloudFront的Origin Access Identity(OAI),并在CloudFront分发的原点设置里关联这个OAI。
  • 修改S3桶的桶策略,只允许这个OAI访问桶内的对象,同时关闭S3的公共访问设置。示例桶策略如下:
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity YOUR-OAI-ID"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

方案二:CloudFront Functions(轻量低成本)

如果你的认证逻辑很简单(只是固定用户名密码),CloudFront Functions是更优选择——它比Lambda@Edge更轻量、成本更低,且没有冷启动问题:

1. 创建CloudFront Function

  • 打开CloudFront控制台,进入「Functions」页面,创建新函数,选择「Viewer Request」类型。
  • 替换函数代码为以下内容(修改用户名密码):
function handler(event) {
    const request = event.request;
    const headers = request.headers;
    
    const USERNAME = 'your-custom-username';
    const PASSWORD = 'your-custom-password';
    
    // 检查Authorization头是否存在
    if (!headers.authorization) {
        return {
            statusCode: 401,
            statusDescription: 'Unauthorized',
            headers: {
                'www-authenticate': { value: 'Basic realm="Restricted S3 Site"' }
            }
        };
    }
    
    // 解码并验证凭证
    const authValue = headers.authorization.value;
    const encodedCreds = authValue.split(' ')[1];
    const decodedCreds = atob(encodedCreds);
    const [username, password] = decodedCreds.split(':');
    
    if (username !== USERNAME || password !== PASSWORD) {
        return {
            statusCode: 401,
            statusDescription: 'Unauthorized',
            headers: {
                'www-authenticate': { value: 'Basic realm="Restricted S3 Site"' }
            }
        };
    }
    
    // 认证通过,放行请求
    return request;
}
  • 发布函数,然后在你的CloudFront分发的缓存行为里,将这个函数关联到Viewer Request事件。

2. 同样配置S3桶的OAI访问限制

和方案一的第二步一样,确保用户只能通过CloudFront访问S3内容。

重要注意事项

  • 不要硬编码凭证! 如果用Lambda@Edge,建议把用户名密码存在AWS Secrets Manager里,让函数在运行时动态拉取,提升安全性;CloudFront Functions目前不支持访问其他AWS服务,如果你用这个方案,可以考虑定期轮换凭证。
  • 测试时直接访问CloudFront的域名,浏览器会自动弹出用户名密码输入框,输入正确凭证即可访问,错误则返回401。

内容的提问来源于stack exchange,提问作者Sandeep Nair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:16:20