如何在Golang中解析Postman请求携带的AWS Signature签名信息

问题解答
无法获取secret值的原因
AWS Signature Version 4(SigV4)认证机制的设计原则就是不会在请求中明文传输Secret Access Key。客户端仅会使用Secret Access Key生成请求签名,服务端需要根据请求中提取到的Access Key,在本地的密钥存储系统中查询匹配的Secret Access Key,再通过相同的签名逻辑生成签名和请求携带的签名做比对,完成认证,因此你不可能从http.Request对象的任何字段中直接获取到secret的值。
从Authorization头提取access_key和region的方法
AWS SigV4的Authorization头有固定格式,示例如下:AWS4-HMAC-SHA256 Credential=AKIAXXXXXXXXXXXX/20240101/cn-north-1/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=xxxxxxxxxx
其中Credential字段按斜杠拆分后,第一个片段就是access_key,第三个片段就是region,你可以参考如下Go代码实现提取:
import ( "fmt" "net/http" "strings" ) func parseAWSigV4Header(r *http.Request) (accessKey, region string, err error) { authHeader := r.Header.Get("Authorization") // 校验是否为合法的AWS SigV4请求头 if authHeader == "" || !strings.HasPrefix(authHeader, "AWS4-HMAC-SHA256 ") { return "", "", fmt.Errorf("not a valid AWS SigV4 request") } // 拆分头内容提取Credential字段 authParts := strings.Split(strings.TrimPrefix(authHeader, "AWS4-HMAC-SHA256 "), ", ") var credential string for _, part := range authParts { if strings.HasPrefix(part, "Credential=") { credential = strings.TrimPrefix(part, "Credential=") break } } if credential == "" { return "", "", fmt.Errorf("no Credential field found in Authorization header") } // 拆分Credential获取参数 credSegments := strings.Split(credential, "/") if len(credSegments) < 5 { return "", "", fmt.Errorf("invalid Credential format") } return credSegments[0], credSegments[2], nil }
如果需要做完整的签名校验,建议直接使用AWS官方Go SDK提供的SigV4校验工具,避免自行解析实现存在的逻辑漏洞。
内容的提问来源于stack exchange,提问作者Keval Bhogayata
相关产品推荐
相关产品推荐

