首頁  >  文章  >  後端開發  >  PutObject 上的 SignatureDoesNotMatch - 處理 GetObject

PutObject 上的 SignatureDoesNotMatch - 處理 GetObject

PHPz
PHPz轉載
2024-02-09 15:00:101182瀏覽

PutObject 上的 SignatureDoesNotMatch - 处理 GetObject

php小編草莓在本文中將為您介紹如何處理「PutObject上的SignatureDoesNotMatch - 處理GetObject」的問題。在進行物件上傳和取得操作時,有時會遇到此錯誤提示,這可能是由於請求的簽章不符導致的。本文將為您詳細解釋該問題的原因,並提供解決方案,幫助您順利處理此錯誤,確保您的物件上傳和取得操作能夠正常進行。

問題內容

我正在嘗試為 s3 中的 putobject 建立簽名 url。我為 getobject 執行此操作的方法運行良好,因此我的憑證有效。

我已經關閉了所有公共存取區塊,因此它應該是公開的。

儲存桶策略:

{
    "version": "2012-10-17",
    "statement": [
        {
            "sid": "allowputobject",
            "effect": "allow",
            "principal": "*",
            "action": "s3:putobject",
            "resource": "arn:aws:s3:::adobe-sign-test/*"
        }
    ]
}

儲存桶 cors:

[
    {
        "allowedheaders": [
            "*"
        ],
        "allowedmethods": [
            "get",
            "head",
            "put"
        ],
        "allowedorigins": [
            "*"
        ],
        "exposeheaders": []
    }
]

我嘗試過使用 s3 函式庫,現在在本例中使用 s3manager。但是,當我嘗試使用簽名 url 放置物件時,我收到一條 xml 錯誤,告訴我 signaturedoesnotmatch。

下面是有效的 get 和失敗的 put 的程式碼。

func getpresignedurl(bucket, key, operation string, expiresin int64, region string, s3accesskeyid string, s3secretaccesskey string) string {
    sess := session.must(session.newsession(&aws.config{
        region: aws.string(region),
        credentials: credentials.newstaticcredentials(
            s3accesskeyid,
            s3secretaccesskey,
            "",
        ),
    }))

    uploader := s3manager.newuploader(sess)

    if operation == "putobject" {
        // generate a pre-signed url for a putobject operation
        uploadurl, _ := uploader.upload(&s3manager.uploadinput{
            bucket: aws.string(bucket),
            key:    aws.string(key),
            acl:    aws.string("bucket-owner-full-control"),
        })

        return uploadurl.location
    }

    // generate a pre-signed url for a getobject operation
    req, _ := uploader.s3.getobjectrequest(&s3.getobjectinput{
        bucket: aws.string(bucket),
        key:    aws.string(key),
    })

    geturl, err := req.presign(time.duration(expiresin) * time.second)
    if err != nil {
        fmt.println(err)
        return ""
    }

    return geturl
}

以下是我嘗試使用curl put 檔案的方法: curl -x put -t some-file.jpg "https://adobe-sign-test.s3.eu-north-1.amazonaws.com/hejsan.jpg?x-amz-algorithm=aws4-hmac -sha256&x- amz-credential=akiaqjglaa​​ktl3qqfz73/20230706/eu-north-1/s3/aws4_request&x-amz-date=20230706t074846z&x-amz-expm; c 1c8ffcae64d77a588119cfde81512bc5c4516a1120b20e26cac7「

這是 put 操作的錯誤訊息:

<?xml version="1.0" encoding="UTF-8"?>
<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>AKIAQJGLAAKTL3QQFZ73</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256
20230706T074846Z
20230706/eu-north-1/s3/aws4_request
7666f6675cc3fe3a3aa20f98928aeccd4b9bc851666fcf03fb425d5819d7e72d</StringToSign><SignatureProvided>5eb429ee8efc1c8ffcae64d77a588119cfde81512bc5c4516a1120b20e26cac7</SignatureProvided><StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 33 30 37 30 36 54 30 37 34 38 34 36 5a 0a 32 30 32 33 30 37 30 36 2f 65 75 2d 6e 6f 72 74 68 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 37 36 36 36 66 36 36 37 35 63 63 33 66 65 33 61 33 61 61 32 30 66 39 38 39 32 38 61 65 63 63 64 34 62 39 62 63 38 35 31 36 36 36 66 63 66 30 33 66 62 34 32 35 64 35 38 31 39 64 37 65 37 32 64</StringToSignBytes><CanonicalRequest>PUT
/hejsan.jpg
X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKIAQJGLAAKTL3QQFZ73%2F20230706%2Feu-north-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20230706T074846Z&amp;X-Amz-Expires=3600&amp;X-Amz-SignedHeaders=host
host:adobe-sign-test.s3.eu-north-1.amazonaws.com

host
UNSIGNED-PAYLOAD</CanonicalRequest><CanonicalRequestBytes>50 55 54 0a 2f 68 65 6a 73 61 6e 2e 6a 70 67 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 51 4a 47 4c 41 41 4b 54 4c 33 51 51 46 5a 37 33 25 32 46 32 30 32 33 30 37 30 36 25 32 46 65 75 2d 6e 6f 72 74 68 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 33 30 37 30 36 54 30 37 34 38 34 36 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 33 36 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 68 6f 73 74 0a 68 6f 73 74 3a 61 64 6f 62 65 2d 73 69 67 6e 2d 74 65 73 74 2e 73 33 2e 65 75 2d 6e 6f 72 74 68 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes><RequestId>SMFDTR996NQE9DDV</RequestId><HostId>VehdLPGdnoVZclkNKs2+lTjFpAssA1Xe+HZSj5ZCCVK2QnumQHqzsePFg3TWWaai3+vqGgnwxpjMd3b8526I7Q==</HostId></Error>

解決方法

aws 開發工具包程式碼庫中有一個 範例go 具有 get 和 put 以及 s3 的預簽 url,也許會有幫助。您可以複製儲存庫並按照自述文件中的說明自行執行這些範例。該範例具有方法,然後有一個控制台應用程式演示如何運行它們。

// GetObject makes a presigned request that can be used to get an object from a bucket.
// The presigned request is valid for the specified number of seconds.
func (presigner Presigner) GetObject(
    bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) {
    request, err := presigner.PresignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, func(opts *s3.PresignOptions) {
        opts.Expires = time.Duration(lifetimeSecs * int64(time.Second))
    })
    if err != nil {
        log.Printf("Couldn't get a presigned request to get %v:%v. Here's why: %v\n",
            bucketName, objectKey, err)
    }
    return request, err
}



// PutObject makes a presigned request that can be used to put an object in a bucket.
// The presigned request is valid for the specified number of seconds.
func (presigner Presigner) PutObject(
    bucketName string, objectKey string, lifetimeSecs int64) (*v4.PresignedHTTPRequest, error) {
    request, err := presigner.PresignClient.PresignPutObject(context.TODO(), &s3.PutObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    }, func(opts *s3.PresignOptions) {
        opts.Expires = time.Duration(lifetimeSecs * int64(time.Second))
    })
    if err != nil {
        log.Printf("Couldn't get a presigned request to put %v:%v. Here's why: %v\n",
            bucketName, objectKey, err)
    }
    return request, err
}



// DeleteObject makes a presigned request that can be used to delete an object from a bucket.
func (presigner Presigner) DeleteObject(bucketName string, objectKey string) (*v4.PresignedHTTPRequest, error) {
    request, err := presigner.PresignClient.PresignDeleteObject(context.TODO(), &s3.DeleteObjectInput{
        Bucket: aws.String(bucketName),
        Key:    aws.String(objectKey),
    })
    if err != nil {
        log.Printf("Couldn't get a presigned request to delete object %v. Here's why: %v\n", objectKey, err)
    }
    return request, err
}

以上是PutObject 上的 SignatureDoesNotMatch - 處理 GetObject的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除