cubefs/objectnode/auth_header_test.go
yhjiango 4401624f96 feat(objectnode): s3 sts and signature auth
1. sts federation token
2. signature auth code refactor

Signed-off-by: yhjiango <jiangyunhua@oppo.com>
2023-08-30 20:05:32 +08:00

248 lines
12 KiB
Go

// Copyright 2023 The CubeFS Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
package objectnode
import (
"fmt"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestNewHeaderAuthV2(t *testing.T) {
// normal
now := time.Now().UTC()
datetime := now.Format(ISO8601Format)
accessKey := "AKIAIOSFODNN7EXAMPLE"
signature := "qgk2+6Sv9/oM7G3qLEjTH1a1l1g="
request := httptest.NewRequest("GET", "http://s3.cubefs.com/photos/puppy.jpg", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, signature))
request.Header.Set(Date, datetime)
ha, err := NewHeaderAuth(request)
require.NoError(t, err)
require.False(t, ha.IsPresigned())
require.False(t, ha.IsExpired())
require.False(t, ha.IsSkewed())
require.Empty(t, ha.SignedHeaders())
require.Equal(t, signatureV2, ha.Version())
require.Equal(t, signV2Algorithm, ha.Algorithm())
cred := ha.Credential()
require.Equal(t, accessKey, cred.AccessKey)
require.Empty(t, cred.Request)
require.Empty(t, cred.Date)
require.Empty(t, cred.Region)
require.Empty(t, cred.Service)
require.Empty(t, cred.Expires)
require.Equal(t, datetime, cred.TimeStamp)
// time skewed
datetime = now.Add(-time.Duration(MaxRequestSkewedSeconds+1) * time.Second).Format(ISO8601Format)
request.Header.Set("X-Amz-Date", datetime)
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.IsSkewed())
}
func TestNewHeaderAuthV4(t *testing.T) {
// normal
now := time.Now().UTC()
date := now.Format(DateLayout)
datetime := now.Format(ISO8601Format)
accessKey := "AKIAIOSFODNN7EXAMPLE"
credential := fmt.Sprintf("%s/%s/cn-south-1/s3/aws4_request", accessKey, date)
signedHeaders := "date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class"
signature := "98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd"
request := httptest.NewRequest("GET", "http://s3.cubefs.com/photos/puppy.jpg", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS4-HMAC-SHA256 Credential=%s,SignedHeaders=%s,Signature=%s", credential, signedHeaders, signature))
request.Header.Set(Date, datetime)
ha, err := NewHeaderAuth(request)
require.NoError(t, err)
require.False(t, ha.IsPresigned())
require.False(t, ha.IsExpired())
require.False(t, ha.IsSkewed())
require.Equal(t, signatureV4, ha.Version())
require.Equal(t, signV4Algorithm, ha.Algorithm())
require.Equal(t, []string{"date", "host", "x-amz-content-sha256", "x-amz-date", "x-amz-storage-class"}, ha.SignedHeaders())
cred := ha.Credential()
require.Equal(t, "cn-south-1", cred.Region)
require.Equal(t, "s3", cred.Service)
require.Equal(t, "aws4_request", cred.Request)
require.Equal(t, accessKey, cred.AccessKey)
require.Equal(t, date, cred.Date)
require.Equal(t, datetime, cred.TimeStamp)
require.Equal(t, accessKey, cred.AccessKey)
require.Empty(t, cred.Expires)
// time skewed
datetime = now.Add(-time.Duration(MaxRequestSkewedSeconds+1) * time.Second).Format(ISO8601Format)
request.Header.Set("X-Amz-Date", datetime)
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.IsSkewed())
}
func TestHeaderAuthV2SignatureMatch(t *testing.T) {
accessKey := "AKIAIOSFODNN7EXAMPLE"
secretKey := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
wildcards, err := NewWildcards([]string{"us-west-1.s3.amazonaws.com", "s3.us-west-1.amazonaws.com"})
require.NoError(t, err)
// Object GET
request := httptest.NewRequest("GET", "http://awsexamplebucket1.us-west-1.s3.amazonaws.com/photos/puppy.jpg", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "qgk2+6Sv9/oM7G3qLEjTH1a1l1g="))
request.Header.Set(Date, "Tue, 27 Mar 2007 19:36:42 +0000")
request.Header.Set(Host, "awsexamplebucket1.us-west-1.s3.amazonaws.com")
ha, err := NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Object PUT
request = httptest.NewRequest("PUT", "http://awsexamplebucket1.s3.us-west-1.amazonaws.com/photos/puppy.jpg", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "iqRzw+ileNPu1fhspnRs8nOjjIA="))
request.Header.Set(Date, "Tue, 27 Mar 2007 21:15:45 +0000")
request.Header.Set(ContentType, "image/jpeg")
request.Header.Set(ContentLength, "94328")
request.Header.Set(Host, "awsexamplebucket1.s3.us-west-1.amazonaws.com")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// List
request = httptest.NewRequest("GET", "http://awsexamplebucket1.s3.us-west-1.amazonaws.com/?prefix=photos&max-keys=50&marker=puppy", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "m0WP8eCtspQl5Ahe6L1SozdX9YA="))
request.Header.Set(Date, "Tue, 27 Mar 2007 19:42:41 +0000")
request.Header.Set("User-Agent", "Mozilla/5.0")
request.Header.Set(Host, "awsexamplebucket1.s3.us-west-1.amazonaws.com")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Fetch
request = httptest.NewRequest("GET", "http://awsexamplebucket1.s3.us-west-1.amazonaws.com/?acl", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "82ZHiFIjc+WbcwFKGUVEQspPn+0="))
request.Header.Set(Date, "Tue, 27 Mar 2007 19:44:46 +0000")
request.Header.Set(Host, "awsexamplebucket1.s3.us-west-1.amazonaws.com")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Delete
request = httptest.NewRequest("DELETE", "http://s3.us-west-1.amazonaws.com/awsexamplebucket1/photos/puppy.jpg", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "Ri1hpB1zpS9pGqR7y8kuNFCl4sE="))
request.Header.Set(Date, "Tue, 27 Mar 2007 21:20:27 +0000")
request.Header.Set(XAmzDate, "Tue, 27 Mar 2007 21:20:26 +0000")
request.Header.Set(Host, "s3.us-west-1.amazonaws.com")
request.Header.Set("User-Agent", "dotnet")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Upload
request = httptest.NewRequest("PUT", "http://s3.us-west-1.amazonaws.com/awsexamplebucket1/db-backup.dat.gz", nil)
request.Header.Set(Authorization, fmt.Sprintf("AWS %s:%s", accessKey, "pzpCkfxTNZ143SPzMtH8on0yBH8="))
request.Header.Set("User-Agent", "curl/7.15.5")
request.Header.Set(Date, "Tue, 27 Mar 2007 21:06:08 +0000")
request.Header.Set(Host, "s3.us-west-1.amazonaws.com")
request.Header.Set(XAmzAcl, "public-read")
request.Header.Set(ContentType, "application/x-download")
request.Header.Set(ContentMD5, "4gJE4saaMU4BqNR0kLY+lw==")
request.Header.Set(ContentDisposition, "attachment; filename=database.dat")
request.Header.Set(ContentEncoding, "gzip")
request.Header.Set(ContentLength, "5913339")
request.Header.Set("X-Amz-Meta-ReviewedBy", "joe@example.com")
request.Header.Add("X-Amz-Meta-ReviewedBy", "jane@example.com")
request.Header.Set("X-Amz-Meta-FileChecksum", "0x02661779")
request.Header.Set("X-Amz-Meta-ChecksumAlgorithm", "crc32")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
}
func TestHeaderAuthV4SignatureMatch(t *testing.T) {
secretKey := "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
wildcards, err := NewWildcards([]string{"s3.amazonaws.com"})
require.NoError(t, err)
// GET Object
request := httptest.NewRequest("GET", "http://examplebucket.s3.amazonaws.com/test.txt", nil)
request.Header.Set(Authorization, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41")
request.Header.Set(Range, "bytes=0-9")
request.Header.Set(Host, "examplebucket.s3.amazonaws.com")
request.Header.Set(XAmzDate, "20130524T000000Z")
request.Header.Set(XAmzContentSha256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
ha, err := NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// PUT Object
request = httptest.NewRequest("PUT", "http://examplebucket.s3.amazonaws.com/test%24file.text", nil)
request.Header.Set(Authorization, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd")
request.Header.Set(Host, "examplebucket.s3.amazonaws.com")
request.Header.Set(Date, "Fri, 24 May 2013 00:00:00 GMT")
request.Header.Set(XAmzDate, "20130524T000000Z")
request.Header.Set(XAmzStorageClass, "REDUCED_REDUNDANCY")
request.Header.Set(XAmzContentSha256, "44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// GET Bucket Lifecycle
request = httptest.NewRequest("GET", "http://examplebucket.s3.amazonaws.com/?lifecycle", nil)
request.Header.Set(Authorization, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543")
request.Header.Set(Host, "examplebucket.s3.amazonaws.com")
request.Header.Set(XAmzDate, "20130524T000000Z")
request.Header.Set(XAmzContentSha256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Get Bucket (List Objects)
request = httptest.NewRequest("GET", "http://examplebucket.s3.amazonaws.com/?max-keys=2&prefix=J", nil)
request.Header.Set(Authorization, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7")
request.Header.Set(Host, "examplebucket.s3.amazonaws.com")
request.Header.Set(XAmzDate, "20130524T000000Z")
request.Header.Set(XAmzContentSha256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
// Chunked PUT Object
request = httptest.NewRequest("PUT", "http://s3.amazonaws.com/examplebucket/chunkObject.txt", nil)
request.Header.Set(Authorization, "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9")
request.Header.Set(Host, "s3.amazonaws.com")
request.Header.Set(ContentEncoding, "aws-chunked")
request.Header.Set(ContentLength, "66824")
request.Header.Set(XAmzDecodedContentLength, "66560")
request.Header.Set(XAmzDate, "20130524T000000Z")
request.Header.Set(XAmzStorageClass, "REDUCED_REDUNDANCY")
request.Header.Set(XAmzContentSha256, "STREAMING-AWS4-HMAC-SHA256-PAYLOAD")
ha, err = NewHeaderAuth(request)
require.NoError(t, err)
require.True(t, ha.SignatureMatch(secretKey, wildcards))
}