使用S3协议访问OSS
- 一、前提
- 0、OSS对S3的兼容性
- 1、权限控制:
- 1. RAM policy
- 2. bucket policy
- 3. bucket ACL
- 4. object ACL
- 2、同地域的ECS访问OSS 可以使用内网访问,不走流量。
- 3、bucket删除:
- 需要先关闭关联日志(如果有):
- 删除:
- 二、创建bucket
- 1、创建bucket
- 2、S3协议访问,需要暴露headers ETag
- 3、权限控制使用Bucket授权策略
- 4、控制台上传文件
- 三、使用S3协议Go SDK访问OSS
- 1、配置
- 2、简单访问
一、前提
0、OSS对S3的兼容性
OSS对S3兼容文档地址:https://help.aliyun.com/document_detail/389025.html
1、权限控制:
文档地址:https://help.aliyun.com/document_detail/430201.html
针对存放在Bucket的Object的访问,OSS提供了以下权限控制策略:
1. RAM policy
基于用户的授权策略。
适用场景:
- 同一个账户下的不同RAM用户授予相同权限。
- OSS服务级别权限配置。
- 对多个bucket设置相同权限。
- 临时账号访问权限控制。
2. bucket policy
- 可以指定用户授予权限
- 可以授予匿名用户限制IP的访问权限
使用场景:
- 对同一账号下的不同RAM用户授予不同权限。
- 要进行跨账号或对匿名用户授权。
3. bucket ACL
(一般默认私有,不做改动)
Bucket ACL分为public-read-write(公共读写)、public-read(公共读)和private(私有)三种。
使用场景:
- 对单个Bucket内的所有Object设置相同的访问权限。
4. object ACL
(一般继承bucket ACL,不做改动)
Object ACL分为继承Bucket、public-read-write(公共读写)、public-read(公共读)和private(私有)四种。
使用场景:
- 对单个Object单独授权。
例如,已通过RAM Policy或者Bucket Policy将Bucket内的所有Object或者与指定Prefix匹配的Object的访问权限设置为私有,但是考虑到您需要将其中某个Object开放给所有互联网匿名用户访问,则选择Object ACL,并将ACL设置为public-read。
当前测试使用基于bucket policy对指定用户进行授权。
2、同地域的ECS访问OSS 可以使用内网访问,不走流量。
我的云服务器ECS:华北2:北京
我的OSS资源包:大陆通用,新建一个bucket同属华北2:北京地域即可。
3、bucket删除:
对象存储-bucket列表-bucketname下
需要先关闭关联日志(如果有):
- 日志管理-实时查询-右侧关闭关联日志
删除:
- 基础设置-最下面删除
二、创建bucket
1、创建bucket
- 地域选择华北2-北京
- 开启实施日志查询
2、S3协议访问,需要暴露headers ETag
权限管理-跨域设置-创建规则
- 方便测试,允许methods全选,来源和允许headers用 *
3、权限控制使用Bucket授权策略
在此之前先创建一个 RAM 子账号:
权限管理-访问控制RAM:前往控制台:
RAM访问控制-身份管理-用户-创建用户:
- 访问方式:选中Open API调用访问即可。无需添加任何权限。
- 【重要】记住 AccessKey ID和AccessKey Secret,记不住再创建新的也可以。
权限管理-Bucket授权策略-按图形策略添加:
- 新增授权
- 授权资源:整个bucket
- 授权用户:选中子账户,选择刚才创建的RAM子账户
- 授权操作:简单设置-完全控制(测试使用完全控制即可)
4、控制台上传文件
文件管理-上传文件-扫描文件-选择本地的1.jpg-上传文件。
查看文件管理,文件上传成功。
三、使用S3协议Go SDK访问OSS
1、配置
历史原因,aws sdk for go使用的V1版本,现在有V2版本可用。
文档地址:https://docs.aws.amazon.com/zh_cn/sdk-for-go/?id=docs_gateway
github地址:https://github.com/aws/aws-sdk-go
oss文档地址:https://help.aliyun.com/product/31815.html
公共云下OSS Region和Endpoint对照表
文档地址:https://help.aliyun.com/document_detail/31837.html
我们这里是华北2-北京:
Region :oss-cn-beijing
外网Endpoint:oss-cn-beijing.aliyuncs.com
内网Endpoint:oss-cn-beijing-internal.aliyuncs.com
2、简单访问
- 此次测试写在外网,endpoint使用外网endpoint(oss-cn-beijing.aliyuncs.com)
- 虚拟托管访问方式:
- S3支持路径(Path)请求风格和虚拟托管(Virtual Hosted)请求风格。虚拟托管请求风格是指将Bucket置于Host Header的访问方式。基于安全考虑,OSS仅支持虚拟托管访问方式。(https://help.aliyun.com/document_detail/389025.html)
- NewSession的参数:S3ForcePathStyle: aws.Bool(false)
- true代表使用路径(Path)请求风格,oss不支持,所有设置为false。其实默认就是false。
代码给oss中的文件1.jpg预签名一个超时时间1分钟的地址,可以在浏览器上访问,一分钟后过期:
package main
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"log"
"time"
)
var (
accessKey = "AccessKey ID" //""
secretKey = "AccessKey Secret" //""
region = "oss-cn-beijing"
endpoint = "oss-cn-beijing.aliyuncs.com"
//timeout time.Duration = time.Second * 5
)
func main() {
sess, err := session.NewSession(&aws.Config{
Credentials: credentials.NewStaticCredentials(accessKey, secretKey, ""),
Endpoint: aws.String(endpoint),
Region: aws.String(region),
//minio:true,oss:false
S3ForcePathStyle: aws.Bool(false),
})
if err != nil {
panic(err)
}
svc := s3.New(sess)
PreGetObj(svc, "bkt-bj1", "1.jpg")
}
func PreGetObj(svc *s3.S3, bucket, key string) {
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
urlStr, err := req.Presign(1 * time.Minute)
if err != nil {
log.Println("Failed to sign request", err)
return
}
log.Println("The URL is", urlStr)
}
打印出来的地址,可以复制到浏览器中可以访问。
一分钟后再访问会提示如下:(拒绝访问)
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired.</Message>
<RequestId>62DF47196AD6D538304DFD0F</RequestId>
<HostId>bkt-bj1.oss-cn-beijing.aliyuncs.com</HostId>
<Expires>20220726T014449Z</Expires>
<ServerTime>20220726T014457Z</ServerTime>
<X-Amz-Expires>60</X-Amz-Expires>
</Error>