为了账号安全,请及时绑定邮箱和手机立即绑定

使用 SSE 对 S3 对象的预签名 url 进行 GET 请求失败,并出现 403 错误

使用 SSE 对 S3 对象的预签名 url 进行 GET 请求失败,并出现 403 错误

Go
森栏 2023-07-10 14:39:31
当我向 Go 中的GETAWS 方法生成的预签名 URL 发出请求时,收到 403 Forbidden HTTP 响应。Presign错误信息是:我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法X-Amz-SignedHeaders是:host;x-amz-server-side-encryption-customer-algorithm;x-amz-server-side-encryption-customer-key;x-amz-server-side-encryption-customer-key-md5我将对象写入 S3,如下所示:type DocumentStore struct {    bucketName               string    bucketEncryptionKeyAlias string    aws                      *session.Session}func (s *DocumentStore) PutDocument(ctx context.Context, envelope []byte, metadata map[string]string) (PutDocumentResult, error) {    uploader := s3manager.NewUploader(s.aws)    var objectKey = uuid.New().String()    if _, err := uploader.UploadWithContext(ctx, &s3manager.UploadInput{        Bucket:               aws.String(s.bucketName),        Key:                  aws.String(objectKey),        ContentType:          aws.String("application/octet-stream"),        Body:                 bytes.NewReader(envelope),        ServerSideEncryption: aws.String(s3.ServerSideEncryptionAwsKms),        SSEKMSKeyId:          aws.String(s.bucketEncryptionKeyAlias),        Metadata:             aws.StringMap(metadata),    }); err != nil {        return PutDocumentResult{}, fmt.Errorf("put document failed on upload: %v", err.Error())    }    return PutDocumentResult{        BucketName: s.bucketName,        ObjectKey:  objectKey,    }, nil}我像这样签署网址:func (s *DocumentStore) NewSignedGetURL(ctx context.Context, objectKey string, ttl time.Duration) (string, error) {    svc := s3.New(s.aws)    req, _ := svc.GetObjectRequest(&s3.GetObjectInput{        Bucket: aws.String(s.bucketName),        Key: aws.String(objectKey),        SSECustomerKey: aws.String(s.bucketEncryptionKeyAlias),        SSECustomerAlgorithm: aws.String(s3.ServerSideEncryptionAwsKms),    })    url, err := req.Presign(ttl)    if err != nil {        return "", fmt.Errorf("failed to presign GetObjectRequest for key %q: %v", objectKey, err)    }    return url, nil}我缺少什么?
查看完整描述

1 回答

?
HUWWW

TA贡献1874条经验 获得超12个赞

我发现:GetObject只要用户拥有DecryptKMS 密钥的权限,请求就不需要 SSE 参数。以下是相关变更:


我现在正在像这样签署网址:


func (s *DocumentStore) NewSignedGetURL(ctx context.Context, objectKey string, ttl time.Duration) (string, error) {

    svc := s3.New(s.aws)


    req, _ := svc.GetObjectRequest(&s3.GetObjectInput{

        Bucket: aws.String(s.bucketName),

        Key: aws.String(objectKey),

    })


    url, err := req.Presign(ttl)

    if err != nil {

        return "", fmt.Errorf("failed to presign GetObjectRequest for key %q: %v", objectKey, err)

    }


    return url, nil

}

我正在下载这样的对象:


getURL, err := target.NewSignedGetURL(context.TODO(), result.ObjectKey, time.Minute*5)

if err != nil {

    t.Errorf("failed to sign url: %v", err)

    return

}


req, _ := http.NewRequest("GET", getURL, nil)

req.Header.Add("host", req.Host)


resp, err := http.DefaultClient.Do(req.WithContext(context.TODO()))

if err != nil {

    t.Errorf("failed to request object from signed url: %v", err)

    return

}

defer resp.Body.Close()


data, err := ioutil.ReadAll(resp.Body)

if err != nil {

    t.Errorf("failed to read object stream from S3: %v", err)

    return

}


查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 179 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信