diff options
| author | Er2 <er2@dismail.de> | 2024-10-03 18:08:19 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-03 08:08:19 -0700 |
| commit | 5644bc8f012d3df08bc12f6ddb364b7a4d76193e (patch) | |
| tree | e166afc963417a5de2f33a7623ce342af3e5988f | |
| parent | 416cc58cce7e411b218a6208c079df3d1b0fceb8 (diff) | |
| download | seaweedfs-5644bc8f012d3df08bc12f6ddb364b7a4d76193e.tar.xz seaweedfs-5644bc8f012d3df08bc12f6ddb364b7a4d76193e.zip | |
s3api: Fix signature v4 with reverse proxy at sub-path (#6092)
| -rw-r--r-- | weed/s3api/auth_signature_v4.go | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/weed/s3api/auth_signature_v4.go b/weed/s3api/auth_signature_v4.go index 71ef6cd6e..c8135ef10 100644 --- a/weed/s3api/auth_signature_v4.go +++ b/weed/s3api/auth_signature_v4.go @@ -148,15 +148,38 @@ func (iam *IdentityAccessManagement) doesSignatureMatch(hashedPayload string, r } } + if forwardedPrefix := r.Header.Get("X-Forwarded-Prefix"); forwardedPrefix != "" { + // Handling usage of reverse proxy at prefix. Note that it's an undefined behavior for AWS S3 and not supported in MinIO. + // Trying with prefix before main path. + + // Get canonical request. + canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, forwardedPrefix + req.URL.Path, req.Method) + + errCode = iam.genAndCompareSignatureV4(canonicalRequest, cred.SecretKey, t, signV4Values) + if errCode == s3err.ErrNone { + return identity, errCode + } + } + // Get canonical request. canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, queryStr, req.URL.Path, req.Method) + errCode = iam.genAndCompareSignatureV4(canonicalRequest, cred.SecretKey, t, signV4Values) + + if errCode == s3err.ErrNone { + return identity, errCode + } + return nil, errCode +} + +// Generate and compare signature for request. +func (iam *IdentityAccessManagement) genAndCompareSignatureV4(canonicalRequest, secretKey string, t time.Time, signV4Values signValues) s3err.ErrorCode { // Get string to sign from canonical request. stringToSign := getStringToSign(canonicalRequest, t, signV4Values.Credential.getScope()) // Calculate signature. newSignature := iam.getSignature( - cred.SecretKey, + secretKey, signV4Values.Credential.scope.date, signV4Values.Credential.scope.region, signV4Values.Credential.scope.service, @@ -165,11 +188,9 @@ func (iam *IdentityAccessManagement) doesSignatureMatch(hashedPayload string, r // Verify if signature match. if !compareSignatureV4(newSignature, signV4Values.Signature) { - return nil, s3err.ErrSignatureDoesNotMatch + return s3err.ErrSignatureDoesNotMatch } - - // Return error none. - return identity, s3err.ErrNone + return s3err.ErrNone } // credentialHeader data type represents structured form of Credential @@ -664,7 +685,10 @@ func extractSignedHeaders(signedHeaders []string, r *http.Request) (http.Header, extractedSignedHeaders.Set(header, "100-continue") case "host": // Go http server removes "host" from Request.Header - if forwardedFor := r.Header.Get("X-Forwarded-For"); forwardedFor != "" { + if forwardedHost := r.Header.Get("X-Forwarded-Host"); forwardedHost != "" { + // Trying to use reverse proxy at prefix. Note that it's an undefined behavior for AWS S3 and not supported in MinIO. + extractedSignedHeaders.Set(header, forwardedHost) + } else if forwardedFor := r.Header.Get("X-Forwarded-For"); forwardedFor != "" { extractedSignedHeaders.Set(header, forwardedFor) } else { extractedSignedHeaders.Set(header, r.Host) |
