Browse Source

address comments

pull/6989/head
chrislu 3 months ago
parent
commit
21ae7ae5e9
  1. 91
      weed/s3api/auto_signature_v4_test.go

91
weed/s3api/auto_signature_v4_test.go

@ -6,13 +6,10 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/url"
"sort" "sort"
"strconv"
"strings" "strings"
"sync" "sync"
"testing" "testing"
@ -210,6 +207,53 @@ func mustNewPresignedRequest(iam *IdentityAccessManagement, method string, urlSt
return req return req
} }
// preSignV4 adds presigned URL parameters to the request
func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKey, secretKey string, expires int64) error {
// Create credential scope
now := time.Now().UTC()
dateStr := now.Format(iso8601Format)
// Create credential header
scope := fmt.Sprintf("%s/%s/%s/%s", now.Format(yyyymmdd), "us-east-1", "s3", "aws4_request")
credential := fmt.Sprintf("%s/%s", accessKey, scope)
// Get the query parameters
query := req.URL.Query()
query.Set("X-Amz-Algorithm", signV4Algorithm)
query.Set("X-Amz-Credential", credential)
query.Set("X-Amz-Date", dateStr)
query.Set("X-Amz-Expires", fmt.Sprintf("%d", expires))
query.Set("X-Amz-SignedHeaders", "host")
// Set the query on the URL (without signature yet)
req.URL.RawQuery = query.Encode()
// Get the payload hash
hashedPayload := getContentSha256Cksum(req)
// Extract signed headers
extractedSignedHeaders := make(http.Header)
extractedSignedHeaders["host"] = []string{req.Host}
// Get canonical request
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, req.URL.RawQuery, req.URL.Path, req.Method)
// Get string to sign
stringToSign := getStringToSign(canonicalRequest, now, scope)
// Get signing key
signingKey := getSigningKey(secretKey, now.Format(yyyymmdd), "us-east-1", "s3")
// Calculate signature
signature := getSignature(signingKey, stringToSign)
// Add signature to query
query.Set("X-Amz-Signature", signature)
req.URL.RawQuery = query.Encode()
return nil
}
// Returns new HTTP request object. // Returns new HTTP request object.
func newTestRequest(method, urlStr string, contentLength int64, body io.ReadSeeker) (*http.Request, error) { func newTestRequest(method, urlStr string, contentLength int64, body io.ReadSeeker) (*http.Request, error) {
if method == "" { if method == "" {
@ -459,47 +503,6 @@ func signRequestV4(req *http.Request, accessKey, secretKey string) error {
return nil return nil
} }
// preSignV4 presign the request, in accordance with
// http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html.
func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKeyID, secretAccessKey string, expires int64) error {
// Presign is not needed for anonymous credentials.
if accessKeyID == "" || secretAccessKey == "" {
return errors.New("Presign cannot be generated without access and secret keys")
}
region := "us-east-1"
date := time.Now().UTC()
scope := getScope(date, region)
credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
// Set URL query.
query := req.URL.Query()
query.Set("X-Amz-Algorithm", signV4Algorithm)
query.Set("X-Amz-Date", date.Format(iso8601Format))
query.Set("X-Amz-Expires", strconv.FormatInt(expires, 10))
query.Set("X-Amz-SignedHeaders", "host")
query.Set("X-Amz-Credential", credential)
query.Set("X-Amz-Content-Sha256", unsignedPayload)
// "host" is the only header required to be signed for Presigned URLs.
extractedSignedHeaders := make(http.Header)
extractedSignedHeaders.Set("host", req.Host)
queryStr := strings.Replace(query.Encode(), "+", "%20", -1)
canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, queryStr, req.URL.Path, req.Method)
stringToSign := getStringToSign(canonicalRequest, date, scope)
signingKey := getSigningKey(secretAccessKey, date.Format(yyyymmdd), region, "s3")
signature := getSignature(signingKey, stringToSign)
req.URL.RawQuery = query.Encode()
// Add signature header to RawQuery.
req.URL.RawQuery += "&X-Amz-Signature=" + url.QueryEscape(signature)
// Construct the final presigned URL.
return nil
}
// EncodePath encode the strings from UTF-8 byte representations to HTML hex escape sequences // EncodePath encode the strings from UTF-8 byte representations to HTML hex escape sequences
// //
// This is necessary since regular url.Parse() and url.Encode() functions do not support UTF-8 // This is necessary since regular url.Parse() and url.Encode() functions do not support UTF-8

Loading…
Cancel
Save