MinIO REST请求身份认证:请求头格式与签名计算方法
MinIO REST API 请求认证问题解答
背景
在Windows 10系统上通过Docker运行MinIO,直接向http://localhost:9000/发送GET请求时返回403 Access Denied错误,原因是未按S3兼容的身份认证机制构造请求。
1. MinIO请求头格式
MinIO兼容S3 API,核心请求头需包含以下内容:
- Host: MinIO服务地址,例:
localhost:9000 - Date 或 x-amz-date: UTC格式的请求时间戳,两种格式二选一即可:
- Date头格式:
Wed, 21 Oct 2015 07:28:00 GMT - x-amz-date头格式:
20240520T123456Z(YYYYMMDD'T'HHMMSS'Z')
- Date头格式:
- Authorization: 签名认证头,固定格式:
AWS4-HMAC-SHA256 Credential=<你的MinIO AccessKey>/<日期字符串>/<区域>/s3/aws4_request, SignedHeaders=<签名头列表>, Signature=<计算出的签名> - x-amz-content-sha256(可选但推荐):请求体的SHA256哈希值,无请求体的GET/HEAD请求可填
UNSIGNED-PAYLOAD
2. 签名计算步骤
签名计算基于HMAC-SHA256算法,分5步完成:
步骤1:准备基础参数
- AccessKey/SecretKey:MinIO启动时配置的
MINIO_ROOT_USER和MINIO_ROOT_PASSWORD - 日期字符串:格式
YYYYMMDD(如20240520),与x-amz-date中的日期部分一致 - 时间字符串:格式
YYYYMMDD'T'HHMMSS'Z'(如20240520T123456Z) - 区域:MinIO默认是
us-east-1,若启动时指定了其他区域则用对应值
步骤2:构造规范请求(Canonical Request)
规范请求是签名的基础,格式如下:
<HTTP方法> <URI路径> <查询字符串> <规范头列表>\n <签名头列表> <请求体哈希>
以GET请求根路径为例,规范请求内容:
GET / host:localhost:9000 x-amz-date:20240520T123456Z host;x-amz-date UNSIGNED-PAYLOAD
注意事项:
- 规范头需全部小写、按字母顺序排序,每个头后加换行,最后再补一个空行
- 签名头是逗号分隔的小写头名(需与规范头对应)
- 无请求体时,请求体哈希填
UNSIGNED-PAYLOAD
步骤3:构造字符串待签(String to Sign)
格式:
AWS4-HMAC-SHA256 <时间字符串> <日期字符串>/<区域>/s3/aws4_request <规范请求的SHA256哈希值>
示例:
AWS4-HMAC-SHA256 20240520T123456Z 20240520/us-east-1/s3/aws4_request abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
步骤4:计算签名密钥(Signing Key)
通过四次HMAC-SHA256迭代生成:
kDate = HMAC-SHA256("AWS4" + SecretKey, 日期字符串) kRegion = HMAC-SHA256(kDate, 区域) kService = HMAC-SHA256(kRegion, "s3") kSigning = HMAC-SHA256(kService, "aws4_request")
步骤5:生成最终签名
用签名密钥对字符串待签做HMAC-SHA256哈希,将结果转为十六进制字符串,即为Authorization头中的Signature值。
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

