AWS Presign函数生成的URL不起作用

时间:2019-10-03 11:30:37

标签: amazon-web-services go pre-signed-url

每当我尝试使用AWS API生成Presign URL时,都会得到如下信息:

https://{OBJECT_PATH}?X-Amz-Algorithm=AWS4-HMAC-SHA256\\u0026X-Amz-Credential=AKIAJMALZY6GKVGFVOCQ%2F20191003%2Fus-east-1%2Fs3%2Faws4_request\\u0026X-Amz-Date=20191003T111419Z\\u0026X-Amz-Expires=300\\u0026X-Amz-SignedHeaders=host\\u0026X-Amz-Signature=c72a66c249fe2dada4c3925388efc62cbc734c84e01ffbf4748a5f6be9a99026\

当我尝试输入时,出现以下消息:

<Error>
   <Code>AuthorizationQueryParametersError</Code>
   <Message>X-Amz-Algorithm only supports "AWS4-HMAC-SHA256"</Message
   <RequestId>7236615A79C34A4B</RequestId>
   <HostId>PHoX1otuX6apJrXRTOMM/8GvgiajrNPdElrnfSzAZCzpLzMG8NFu9RIJEiyEYHWAls91n882QNE=</HostId>
</Error>

我试图用\\u0026替换&,因为我在文档(https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html)上看到这是应该构造前缀URL的方式,我得到:

<Error>
     <Code>SignatureDoesNotMatch</Code>
     <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
     <AWSAccessKeyId>AKIAJMALZY6GKVGFVOCQ</AWSAccessKeyId>
     <StringToSign>AWS4-HMAC-SHA256
20191003T112220Z
20191003/us-east-1/s3/aws4_request
a1d8f89ff0472249afb8f1320314eef950bcef423f05fe98420f53cc7f7d8e8f</StringToSign>
     <SignatureProvided>a1b2b7080c67e6456cbd2ab678565e5f3857483378e69ca03e35cc83232b2844\</SignatureProvided>
      <StringToSignBytes>{SEQUENCE_OF_BYTES}</StringToSignBytes>
      <CanonicalRequest>GET/{OBJECT_KEY}?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJMALZY6GKVGFVOCQ%2F20191003%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20191003T112220Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host host:{BUCKET_NAME} host UNSIGNED-PAYLOAD</CanonicalRequest>
      <CanonicalRequestBytes>{SEQUENCE_OF_BYTES}</CanonicalRequestBytes>
      <RequestId>F3A0303ADD62D8FD</RequestId
      <HostId>yU7FdXLoEO+j+KpZtQH1YjF6l3RnVugBi6rzCRJOgVYk7FEQqreobMuFdSiYtzIKUgl0Qr2GcAQ=</HostId>
</Error>

最后,这是我用来生成这些URL的代码:

var accessableURLs []string
    for _, fileName := range fileNames {
        objectKey := filepath.Join(fileDir, fileName)

        req, _ := s3Obj.Client.GetObjectRequest(&s3.GetObjectInput{
            Bucket: aws.String(s3Obj.Bucket),
            Key:    aws.String(objectKey),
        })

        urlStr, err := req.Presign(expireAfter)
        if err != nil {
            glog.Errorf("Failed during generating pre-signed S3 url, reason -%v ", err)
            return nil, err
        }

        accessableURLs = append(accessableURLs, urlStr)
    }

1 个答案:

答案 0 :(得分:0)

以下内容适用于v1 aws sdk。我不确定您的解决方案为何失败:

package main

import (
    "fmt"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    MyBucketName := "myAwesomeBucket"
    MyKeyName := "/path/filename.txt"
    days := 5

    session, err := session.NewSession(&aws.Config{
        Region: aws.String("us-east-1")},
    )
    s := s3.New(session)
    r, _ := s.GetObjectRequest(&s3.GetObjectInput{
        Bucket: aws.String(MyBucketName),
        Key:    aws.String(MyKeyName),
    })
    url, err := r.Presign(time.Duration(days) * 24 * time.Hour)

    if err != nil {
        fmt.Println("failure")
    }

    fmt.Println(url)
}

要注意的一件事是,用于签名的URL的IAM凭据必须在有效的时间内有效。这最终成为使用临时凭据的ec2机器的问题。一种解决方法是使应用程序具有用于签名网址的永久IAM凭据。