私有权限的Bucket或Object需要携带签名URL进行请求,同时签名URL地址存在有效期的烦恼,即需要不停地获取签名URL,并放到实际业务中访问。本文主要介绍OSS如何在私有的读写权限环境下,如何应用到业务中。
OSS权限利弊介绍
公共读权限
-
优点:简便性高,无需携带请求参数,无有效期烦恼。
-
缺点:安全性低,当遇到恶意请求时,易出现高额账单。
私有权限
-
优点:安全性高,每次请求都需要签名校验。
-
缺点:使用复杂度高,需结合自身业务,频繁获取签名地址进行请求。
业务场景介绍
网站业务:通过OSS存储静态文件(如:图片、视频等),通过网站OSS地址进行访问。以下为视频放到网站中的效果。
在 Aliplayer 播放预览页面中播放视频时,浏览器 DevTools 的 Network 面板显示产生了两条 aliyunmedia.mp4 的 206 Partial Content 请求,大小分别为 118 kB 和 8.2 MB,表明视频通过分段请求方式从 OSS 加载。
设置 Bucket 为私有权限
-
登录 OSS 控制台,单击 Bucket 列表,选择目标 Bucket。
-
在左侧导航栏选择权限控制 > 读写权限,单击设置。
-
选择私有,单击保存。
设置为私有后,直接访问文件 URL 会返回 403 AccessDenied (Code=AccessDenied, Message=You have no right to access this object because of bucket acl)。
如需从公共读改为私有,需先在控制台的数据服务 > 阻止公共访问中关闭该功能,否则无法完成设置。
解决方案
整理如下几个解决方法:
-
CDN + OSS【推荐】
-
OSS开启私有读写权限,同时CDN开启“私有Bucket回源”功能。通过这个方式,CDN域名无需签名的URL地址进行请求到OSS资源,也可以实现避免恶意客户端请求到公共读的OSS上,并产生大量流量。【将OSS访问路径引到CDN侧,同时实现加速】
-
CDN防护,通过CDN配置进行拦截【通过CDN实现拦截】
-
-
ECS + OSS
-
ECS进行反向代理,访问链路是:客户端 -> ECS -> OSS,OSS开启私有权限,ECS通过反向代理方式请求到OSS。使用ECS实例反向代理OSS
-
ECS获取签名URL,访问链路是:客户端 -> ECS -> 客户端 -> OSS。
-
客户端请求应用服务器,获取签名URL地址。
-
客户端通过签名URL地址,访问OSS,过期后需重复获取。
-
-
STS 临时凭证直传
通过 RAM 用户的 AccessKey 调用 STS 的
AssumeRole接口获取临时凭证,客户端使用临时凭证直接上传文件到私有 Bucket,无需暴露长期 AccessKey。-
创建 RAM 角色并为其附加
AliyunOSSFullAccess策略。 -
使用 RAM 用户的 AccessKey 调用
AssumeRole获取AccessKeyId、AccessKeySecret、SecurityToken三元组。根账号的 AccessKey 无法调用AssumeRole,必须使用 RAM 用户的 AccessKey,并为该 RAM 用户附加AliyunSTSAssumeRoleAccess权限。 -
使用获取的临时凭证初始化 OSSClient,调用
PutObject上传文件。
import oss2 from alibabacloud_sts20150401.client import Client as StsClient from alibabacloud_tea_openapi import models as open_api_models config = open_api_models.Config( access_key_id='<RAM用户AccessKeyId>', access_key_secret='<RAM用户AccessKeySecret>', endpoint='sts.cn-hangzhou.aliyuncs.com', region_id='cn-hangzhou' ) sts_client = StsClient(config) response = sts_client.assume_role(assume_role_request) creds = response.body.credentials auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) bucket = oss2.Bucket(auth, endpoint, bucket_name) bucket.put_object('example.txt', b'file content') signed_url = bucket.sign_url('GET', 'example.txt', 60)除 STS 临时凭证直传外,也可以直接使用 OSS SDK 的
sign_url方法生成临时下载 URL,前端直接通过该 URL 访问私有 Bucket 中的文件,无需引入 STS 临时凭证流程,适合仅需下载、不涉及上传的场景。 -
-