[英]aws-sdk-go-v2 PutObject api error AccessDenied
In our Staging environment, we have credential-less access to our private S3 buckets.在我们的暂存环境中,我们可以无凭据访问我们的私有 S3 存储桶。 Access is granted to individual Docker containers.
访问权限授予单个 Docker 容器。 I am trying to upload a file using
PutObject
using the aws-sdk-go-v2 SDK library, but I'm continually getting a 403 AccessDenied api error.我正在尝试使用 aws-sdk-go-v2 SDK 库使用
PutObject
上传文件,但我不断收到 403 AccessDenied api 错误。
My upload code looks like this:我的上传代码如下所示:
var uploadFileFunc = func(s3Details S3Details, key string, payload []byte, params MetadataParams) (*s3.PutObjectOutput, error) {
client := getS3Client(s3Details)
return client.PutObject(context.TODO(), &s3.PutObjectInput{
Bucket: aws.String(s3Details.Bucket),
Key: aws.String(key),
Body: bytes.NewReader(payload),
ContentType: aws.String("text/xml"),
})
}
func getS3Client(s3Details S3Details) *s3.Client {
endpointResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if s3Details.EndpointUrl != "" {
return aws.Endpoint{
PartitionID: "aws",
URL: s3Details.EndpointUrl,
SigningRegion: s3Details.Region,
SigningMethod: s3Details.SignatureVersion,
}, nil
}
return aws.Endpoint{}, &aws.EndpointNotFoundError{}
})
cfg, _ := config.LoadDefaultConfig(context.TODO(),
config.WithEndpointDiscovery(aws.EndpointDiscoveryEnabled),
config.WithEndpointResolverWithOptions(endpointResolver))
return s3.NewFromConfig(cfg, func(o *s3.Options) {
o.Region = s3Details.Region
o.Credentials = aws.AnonymousCredentials{}
o.UsePathStyle = true
})
}
I am using aws.AnonymousCredentials{}
(as our access is credential-less) but this is only to be used for unsigned requests.我正在使用
aws.AnonymousCredentials{}
(因为我们的访问是无凭据的)但这仅用于未签名的请求。 I cannot use NewStaticCredentialsProvider
with empty values for AccessKeyID
and/or SecretAccessKey
as this will throw a StaticCredentialsEmptyError
during the Retrieve()
.我不能将
NewStaticCredentialsProvider
与AccessKeyID
和/或SecretAccessKey
的空值一起使用,因为这会在Retrieve()
期间抛出StaticCredentialsEmptyError
。 Adding dummy credentials will throw an error that they are not on record.添加虚拟凭据将引发错误,表明它们未记录在案。 I am assuming that this is the cause of my
403 AccessDenied
.我假设这是我的
403 AccessDenied
的原因。
How do I sign requests without providing credentials in the Go SDK?如何在 Go SDK 中不提供凭证的情况下签署请求? Is it even possible?
有可能吗? In the boto3 Python library this works fine.
在 boto3 Python 库中,这工作正常。
First of all, I'll strongly suggest you use the v2 of the AWS SDK of Go. I'll present here how I do this so far.首先,我强烈建议您使用 Go 的 AWS SDK 的 v2。我将在这里介绍到目前为止我是如何做到这一点的。
First, I get the AWS config to use with this code (only relevant parts are shown):首先,我获取与此代码一起使用的 AWS 配置(仅显示相关部分):
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
Log.Fatal(err)
}
Here the package used is github.com/aws/aws-sdk-go-v2/config
.这里使用的 package 是
github.com/aws/aws-sdk-go-v2/config
。 Then, I instantiate an s3Client to use for contacting AWS S3 service:然后,我实例化一个 s3Client 以用于联系 AWS S3 服务:
s3Client := s3.NewFromConfig(*cfg)
Here, we use this package github.com/aws/aws-sdk-go-v2/service/s3
.在这里,我们使用这个 package
github.com/aws/aws-sdk-go-v2/service/s3
。 Finally, to post your object you have to run this code:最后,要发布您的 object,您必须运行以下代码:
input := &s3.PutObjectInput{
Key: aws.String("test"),
Bucket: aws.String("test"),
Body: bytes.NewReader([]byte("test")),
ACL: types.ObjectCannedACLPrivate,
}
if _, err := s3Client.PutObject(context.TODO(), input); err != nil {
return "", fmt.Errorf("fn UploadFile %w", err)
}
The new package used here is github.com/aws/aws-sdk-go-v2/service/s3/types
.此处使用的新 package 是
github.com/aws/aws-sdk-go-v2/service/s3/types
。
This code is a simplification but you should able to achieve what you need.此代码是一种简化,但您应该能够实现您所需要的。 Furthermore, it should take very little time to update the version of the SDK and you can rely on both of them simultaneously if you've to work with a huge codebase.
此外,更新 SDK 的版本应该只需要很少的时间,如果您必须使用庞大的代码库,则可以同时依赖它们。
Let me know if this helps!让我知道这是否有帮助!
I updated my solution by using the aws.AnonymousCredentials{}
option.我使用
aws.AnonymousCredentials{}
选项更新了我的解决方案。 Now I was successfully able to upload a file into an s3 bucket with these options.现在我可以使用这些选项成功地将文件上传到 s3 存储桶中。 Below you can find the entire solution:
您可以在下面找到完整的解决方案:
package main
import (
"bytes"
"context"
"crypto/tls"
"net/http"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
)
func GetAwsConfig() (*aws.Config, error) {
cfg, err := config.LoadDefaultConfig(context.TODO(),
// config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody),
config.WithRegion("eu-west-1"),
config.WithHTTPClient(&http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}),
config.WithEndpointResolverWithOptions(
aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
return aws.Endpoint{
PartitionID: "aws",
URL: "http://127.0.0.1:4566",
SigningRegion: "eu-west-1",
HostnameImmutable: true,
}, nil
}),
))
if err != nil {
return nil, err
}
return &cfg, err
}
func main() {
cfg, _ := GetAwsConfig()
s3Client := s3.NewFromConfig(*cfg, func(o *s3.Options) {
o.Credentials = aws.AnonymousCredentials{}
})
if _, err := s3Client.PutObject(context.Background(), &s3.PutObjectInput{
Bucket: aws.String("mybucket"),
Key: aws.String("myfile"),
Body: bytes.NewReader([]byte("hello")),
ACL: types.ObjectCannedACLPrivate,
}); err != nil {
panic(err)
}
}
Before running the code, you've to create the bucket.在运行代码之前,您必须创建存储桶。 I used the below command:
我使用了以下命令:
aws --endpoint-url=http://localhost:4566 s3 mb s3://mybucket
Thanks to this you can upload the file into the mybucket
s3 bucket.由于这个,您可以将文件上传到
mybucket
s3 存储桶中。 To check for the file existence you can issue this command:要检查文件是否存在,您可以发出以下命令:
aws --endpoint-url=http://localhost:4566 s3 ls s3://mybucket --recursive --human-readable
Hope this helps in solving your issue!希望这有助于解决您的问题!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.