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

使用Curl从AWS S3下载Landsat 8时遭遇403访问拒绝错误

问题:AWS S3 usgs-landsat存储桶下载Landsat影像返回403 AccessDenied

我写了一段bash脚本,本应支持付费用户从AWS S3的usgs-landsat存储桶下载Landsat 8影像,脚本如下:

#!/usr/bin/env bash


#!/bin/bash

# Path to your test file
req_path="/collection02/level-2/standard/oli-tirs/2023/233/245/LC08_L2SP_233245_20230510_20230518_02_T2/LC08_L2SP_233245_20230510_20230518_02_T2_SR_B1.TIF"

# We need the current date to calculate the signature and also to pass to S3/GCS
curr_date=`date -R`

# This is the name of your S3/GCS bucket
bucket_name="usgs-landsat"
string_to_sign="GET\n\n\n${curr_date}\n/${bucket_name}${req_path}"

# Your secret (this one works fine when I used aws cli command)
secret="qc2Kc...."

# Your S3 key (this one works fine when I used aws cli command)
s3_key="AKIAY..."

# We will now calculate the signature to be sent as a header.
signature=$(echo -en "${string_to_sign}" | openssl sha1 -hmac "${secret}" -binary | base64)

# That's all we need. Now we can make the request as follows.


# S3
curl -v -H "Host: ${bucket_name}.s3.amazonaws.com" \
        -H "Date: $curr_date" \
        -H "Authorization: AWS ${s3_key}:${signature}" \
         "https://${bucket_name}.s3.amazonaws.com${req_path}" 

运行后返回403错误:

< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Fri, 07 Jul 2023 01:00:40 GMT
< Server: AmazonS3
< 
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host usgs-landsat.s3.amazonaws.com left intact
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>9AST0DFVKK34KFW8</RequestId><HostId>dFyJ9kCQeeWVEnB8WoXbHpZhsloRmqm1Mc3yY7WP90ZWhrOk02J7Vxe1ci9/3bvu59soxAYx6pU=</HostId></Error>

注:脚本中使用的密钥在AWS CLI中可正常使用,寻求解决该403访问拒绝问题的方法。


解决方法
  • 修正签名字符串的换行格式:AWS S3 V2签名要求待签字符串的换行必须是真实的换行符,而非\n转义字符。脚本中用"GET\n\n\n${curr_date}\n/${bucket_name}${req_path}"可能存在解析偏差,建议改用多行字符串生成:

    string_to_sign=$(cat <<EOF
    GET
    
    
    ${curr_date}
    /${bucket_name}${req_path}
    EOF
    )
    
  • 切换到区域专属端点:usgs-landsat存储桶位于us-west-2区域,通用s3.amazonaws.com端点可能导致签名验证失败,需改用区域端点:

    # 修改curl请求的Host头和URL
    curl -v -H "Host: ${bucket_name}.s3.us-west-2.amazonaws.com" \
            -H "Date: $curr_date" \
            -H "Authorization: AWS ${s3_key}:${signature}" \
             "https://${bucket_name}.s3.us-west-2.amazonaws.com${req_path}"
    
  • 升级到AWS V4签名:V2签名已逐步被淘汰,部分存储桶/区域可能限制使用。改用V4签名的完整流程如下:

    # 生成V4签名所需的日期参数
    date_stamp=$(date -u +"%Y%m%d")
    amz_date=$(date -u +"%Y%m%dT%H%M%SZ")
    region="us-west-2"
    service="s3"
    
    # 生成签名密钥
    kSecret="AWS4${secret}"
    kDate=$(echo -n "${date_stamp}" | openssl sha256 -hmac "${kSecret}" -binary)
    kRegion=$(echo -n "${region}" | openssl sha256 -hmac "${kDate}" -binary)
    kService=$(echo -n "${service}" | openssl sha256 -hmac "${kRegion}" -binary)
    kSigning=$(echo -n "aws4_request" | openssl sha256 -hmac "${kService}" -binary)
    
    # 生成规范化请求和待签字符串
    canonical_request="GET\n${req_path}\n\nhost:${bucket_name}.s3.${region}.amazonaws.com\nx-amz-date:${amz_date}\n\nhost;x-amz-date\nUNSIGNED-PAYLOAD"
    canonical_hash=$(echo -en "${canonical_request}" | openssl sha256 -binary | xxd -p -c 256)
    string_to_sign="AWS4-HMAC-SHA256\n${amz_date}\n${date_stamp}/${region}/${service}/aws4_request\n${canonical_hash}"
    
    # 计算签名并发起请求
    signature=$(echo -en "${string_to_sign}" | openssl sha256 -hmac "${kSigning}" -binary | base64)
    curl -v -H "Host: ${bucket_name}.s3.${region}.amazonaws.com" \
            -H "x-amz-date: ${amz_date}" \
            -H "Authorization: AWS4-HMAC-SHA256 Credential=${s3_key}/${date_stamp}/${region}/${service}/aws4_request, SignedHeaders=host;x-amz-date, Signature=${signature}" \
             "https://${bucket_name}.s3.${region}.amazonaws.com${req_path}"
    
  • 确认IAM权限与存储桶策略:虽然CLI可用,仍需检查IAM用户是否拥有s3:GetObject权限(资源需覆盖usgs-landsat/*),同时确认USGS存储桶的资源策略未限制付费用户的访问。

内容的提问来源于stack exchange,提问作者Bằng Rikimaru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:37:21