阿里云OSS防盗链与权限访问控制完全指南

apphuang2026年07月01日 19:14:012

引言:为什么需要重视OSS的访问控制

对象存储服务(OSS)作为阿里云最核心的存储产品之一,承载着海量企业的图片、视频、文档等静态资源。然而,随着业务规模的扩大,资源被盗链、数据被未授权访问、流量费用激增等问题频发。如何科学地配置防盗链与权限访问控制,成为每个OSS使用者必须掌握的技能。

OSS提供了多层次、多维度的安全防护体系:从基础的Referer防盗链,到精细化的Bucket Policy和RAM Policy权限策略,再到临时授权的签名URL与STS机制。本文将从原理到实践,逐一剖析这些技术手段,帮助读者构建一套完整、安全的OSS访问控制方案。

需要先登录阿里云控制台,点击:阿里云控制台

一、防盗链:基于Referer的第一道防线

1.1 什么是防盗链

防盗链是OSS提供的一种基于HTTP请求头中Referer字段的访问控制机制。当用户通过浏览器或应用访问OSS资源时,请求头中会携带来源页面的URL(即Referer)。OSS通过检查这个Referer是否在允许的白名单中,来决定是否放行该请求。这一机制的核心价值在于:防止其他网站将您的OSS资源嵌入自己的页面,从而盗用带宽和流量,给您带来不必要的费用支出。

1.2 防盗链的三种配置要素

在OSS控制台配置防盗链时,需要关注三个核心参数:

白名单Referer:允许访问的域名列表。只有来自这些域名的请求才会被放行。多个Referer之间使用回车换行分隔。配置时需要注意,白名单中的域名需要同时包含http和https两种协议版本。

黑名单Referer:禁止访问的域名列表。黑名单中的域名发起的请求将被直接拒绝。当白名单和黑名单同时存在时,OSS会先判断黑名单,再判断白名单。这一顺序意味着:即使某个域名同时出现在白名单和黑名单中,它也会被黑名单规则拦截。

空Referer策略:决定是否允许请求头中不带Referer或Referer为空的请求。如果选择"不允许",则所有浏览器中直接输入URL访问OSS文件的行为都会被拒绝。这在某些场景下可能影响正常使用——例如用户从浏览器地址栏直接访问图片、或者某些隐私浏览器不发送Referer时。

1.3 防盗链的生效逻辑

防盗链的判定逻辑可以总结为以下三种情况:

第一种情况:如果Referer白名单为空,则所有请求都会被允许,防盗链功能实际上处于未启用状态。

第二种情况:如果Referer白名单不为空,且不允许空Referer,则只有Referer属于白名单的请求被允许,其他请求(包括Referer为空的请求)都会被拒绝。

第三种情况:如果Referer白名单不为空,但允许空Referer,则Referer为空的请求和符合白名单的请求会被允许,其他请求都会被拒绝。

理解这一逻辑至关重要。很多用户在配置防盗链后发现自己的网站无法访问OSS资源,往往是因为没有正确设置空Referer策略——例如,当用户从HTTPS页面引用HTTP资源时,某些浏览器可能不会发送Referer,此时如果防盗链设置为"不允许空Referer",请求就会被拒绝。

1.4 QueryString截断规则

在防盗链配置中,还有一个容易被忽视的选项——截断QueryString。当选择"允许"截断时,OSS在匹配Referer时会忽略URL中的查询参数。例如,将Referer设置为 http://www.example.com/?action=nop,OSS实际会使用 http://www.example.com/ 进行匹配。选择"不允许"时,则会完整匹配带查询参数的URL。这一配置对于使用了动态参数的网站尤为重要,需要根据实际业务场景选择合适的策略。

1.5 通过Java SDK配置防盗链

除了控制台图形化操作,OSS也支持通过SDK编程方式配置防盗链。以下是一个使用Java SDK设置防盗链的完整示例:

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.BucketReferer;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import java.util.ArrayList;
import java.util.List;

public class RefererDemo {
    public static void main(String[] args) throws Exception {
        // 从环境变量获取访问凭证
        EnvironmentVariableCredentialsProvider credentialsProvider = 
            CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        
        // 填写Endpoint和Bucket名称
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        String bucketName = "examplebucket";
        
        // 创建OSSClient实例
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        
        try {
            // 构建Referer白名单
            List<String> refererList = new ArrayList<String>();
            refererList.add("https://www.example.com");
            refererList.add("http://www.example.com");
            
            // 创建BucketReferer对象
            // 参数说明:白名单列表,是否允许空Referer,是否截断QueryString
            BucketReferer bucketReferer = new BucketReferer(refererList, false, true);
            
            // 设置防盗链配置
            ossClient.setBucketReferer(bucketName, bucketReferer);
            
            System.out.println("防盗链配置成功");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient
            ossClient.shutdown();
        }
    }
}

需要注意的是,设置防盗链需要具备 oss:PutBucketReferer 权限。在实际生产环境中,建议通过RAM用户而非主账号进行操作,以遵循最小权限原则。

1.6 通过ossutil命令行配置防盗链

对于运维自动化场景,ossutil命令行工具提供了更高效的配置方式。查看当前防盗链配置:

ossutil api get-bucket-referer --bucket examplebucket

以JSON格式查看:

ossutil api get-bucket-referer --bucket examplebucket --output-format json

设置防盗链则通过 put-bucket-referer 命令完成,需要将配置写入JSON文件后通过 --body 参数传入。

二、权限访问控制:多层次防护体系

防盗链只能解决"谁可以引用"的问题,但无法控制"谁可以读取、写入、删除"。OSS提供了四层权限控制机制,从简单到复杂依次是:ACL、Bucket Policy、RAM Policy,以及临时授权机制(签名URL和STS)。

2.1 ACL:最基础的权限控制

ACL(访问控制列表)是OSS中最简单、最直接的权限控制方式。它通过预定义的权限等级来控制资源的公开或私有状态,支持以下三种等级:

私有(private):数据完全私有,仅资源拥有者或被授权的用户可访问。这是Bucket的默认配置,也是推荐的安全配置。

公共读(public-read):任何人都可以读取数据,但只有资源拥有者或被授权用户可以写入。适用于需要对外提供公开静态资源的场景,如图片、CSS、JavaScript文件等。

公共读写(public-read-write):任何人都可以公开读取和写入数据。这种权限等级风险极高,除非有特殊需求,否则强烈不建议使用。

Bucket ACL控制整个存储空间的默认访问权限,而Object ACL可以单独控制某个对象的权限,且优先级高于Bucket ACL。也就是说,即使Bucket设置为私有,也可以为某个特定文件设置公共读权限。

2.2 Bucket Policy:基于资源的精细化授权

当ACL无法满足复杂的授权需求时,Bucket Policy提供了更强大的能力。Bucket Policy是直接附加在Bucket上的授权策略,可以定义谁(Principal)在什么条件下(Condition)可以对哪些资源(Resource)执行什么操作(Action)。

Bucket Policy的核心优势在于:

  • 单条策略即可授权多个用户访问同一个Bucket,无需为每个用户单独配置
  • 支持基于IP地址、VPC网络、访问时间等条件的精细化控制
  • 支持授权给其他阿里云账号的RAM用户
  • 支持授权给匿名用户(需谨慎使用)
  • 配置简单,在控制台即可完成图形化操作

常见Bucket Policy配置示例

示例一:允许特定IP地址的匿名用户读取Bucket中的所有对象

{
  "Statement": [
    {
      "Action": [
        "oss:GetObject",
        "oss:GetObjectAcl",
        "oss:ListObjects"
      ],
      "Condition": {
        "IpAddress": {
          "acs:SourceIp": [ "10.10.10.10" ]
        }
      },
      "Effect": "Allow",
      "Principal": [ "*" ],
      "Resource": [
        "acs:oss:*:174649585760xxxx:examplebucket/*"
      ]
    }
  ],
  "Version": "1"
}

示例二:授予特定RAM用户对指定目录的只读访问权限

{
  "Statement": [
    {
      "Action": [ "oss:GetObject" ],
      "Effect": "Allow",
      "Principal": [ "acs:ram::1234567890:user/username" ],
      "Resource": [
        "acs:oss:*:1234567890:examplebucket/hangzhou/2020/*",
        "acs:oss:*:1234567890:examplebucket/hangzhou/2015/*"
      ]
    }
  ],
  "Version": "1"
}

配置Bucket Policy的重要注意事项

当Principal设置为通配符(*)且不包含Condition时,策略仅对Bucket Owner以外的用户生效。当Principal设置为通配符(*)且包含Condition时,策略对所有用户生效——包括Bucket Owner和匿名用户。这意味着,如果配置了拒绝访问的Condition策略,连Bucket Owner自身也会被拒绝访问,可能导致整个Bucket无法访问。因此,配置Bucket Policy时务必谨慎。

另外,acs:SourceIp条件关键字仅匹配请求的源IP地址,不区分该IP来自公网还是VPC内网。如果仅使用acs:SourceIp限制访问,其他VPC中恰好使用相同IP地址段的请求也可能被放行,存在越权访问风险。最佳实践是同时配置acs:SourceVpc来明确请求的网络来源。

2.3 RAM Policy:基于身份的权限管理

RAM Policy是附加在RAM用户、用户组或RAM角色上的授权策略。与Bucket Policy不同,RAM Policy是"基于身份"的——它定义的是"这个用户能做什么",而非"这个Bucket允许谁访问"。

OSS支持两种RAM Policy类型:

系统策略:由阿里云预置,用户只能使用不能修改。最常用的两个系统策略是 AliyunOSSFullAccess(OSS完全管理权限)和 AliyunOSSReadOnlyAccess(OSS只读权限)。

自定义策略:由用户自行创建和维护,提供最灵活的权限配置能力。自定义策略采用JSON格式编写,核心元素包括:

  • Effect:授权效力,取值为 Allow(允许)或 Deny(拒绝)
  • Action:对资源执行的具体操作,支持使用通配符 *
  • Resource:策略作用的资源范围
  • Condition:策略生效的条件(可选)

自定义RAM Policy示例

以下策略允许对 example-bucket 及该Bucket内所有资源执行全部操作:

{
  "Version": "1",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "oss:*",
      "Resource": [
        "acs:oss:*:*:example-bucket",
        "acs:oss:*:*:example-bucket/*"
      ]
    }
  ]
}

RAM Policy与Bucket Policy的协同工作

当RAM Policy和Bucket Policy同时存在时,OSS会综合评估所有策略。权限判定的核心原则是:

  • 显式拒绝优先:任何策略中存在匹配请求的Deny规则,请求立即被拒绝
  • 寻找显式允许:不存在Deny规则时,若存在匹配的Allow规则,请求被允许
  • 默认拒绝:既无Deny也无Allow,请求默认被拒绝

这一原则意味着:即使某个RAM Policy允许了某操作,如果某个Bucket Policy明确拒绝了该操作,请求依然会被拒绝。反之亦然。

2.4 OSS扁平化存储结构对权限配置的影响

OSS采用扁平化存储模型,所有文件直接隶属于存储空间,物理上不存在目录层级结构。控制台中看到的"目录"实际上是通过对象Key的前缀和分隔符(/)模拟出来的。目录对象的Key以 / 结尾,这是OSS识别"目录"的标志。

这一结构对权限配置有重要影响:当需要授权访问某个"目录"时,实际上是在授权访问具有特定前缀的所有对象。例如,授权访问 Development/ 目录,等同于授权访问所有Key以 Development/ 开头的对象。

不同操作目标对应的API请求和Resource配置也不同:

  • 列举存储空间根目录:调用 ListObjects(prefix为空,delimiter为/),Resource指向Bucket本身
  • 进入某个文件夹:调用 ListObjects(prefix为文件夹名/,delimiter为/),Resource指向Bucket本身,通过Condition的oss:Prefix限制可列举范围
  • 读写文件内容:Resource可精确到路径,如 acs:oss:*:*:examplebucket/文件夹名/*,支持通配符

通过OSS控制台访问时,用户需要从Bucket列表逐层导航进入目标目录,这比直接使用API/SDK需要更多的权限——除了目标资源的操作权限外,还需要 oss:ListBuckets、oss:GetBucketInfo 等辅助权限。

三、临时授权:签名URL与STS

在实际业务中,我们常常需要让没有OSS账号的第三方临时访问某个文件——比如让用户下载私有文件、让合作方上传数据等。此时,ACL、Bucket Policy、RAM Policy都无法满足需求,因为它们都需要预先定义好"谁"可以访问。签名URL和STS临时凭证正是为解决这一场景而生。

3.1 签名URL:为单个文件生成临时访问链接

签名URL(又称预签名URL)将签名信息和认证参数直接嵌入URL中,让您无需共享访问凭证即可授予对OSS资源的临时访问权限。任何持有该URL的人都可以在有效期内执行指定的操作(如下载、上传),URL过期后自动失效。

签名URL的核心特性

  • 有效期可配置:使用V4签名算法时,AccessKey签名URL有效期最长为7天(604800秒),STS临时凭证签名URL最长为12小时(43200秒)
  • 支持多次访问:在有效期内,同一个URL可以被多次使用
  • 操作绑定:生成URL时指定HTTP方法(GET用于下载,PUT用于上传等),URL只能执行该操作
  • 无需凭证:访问者无需持有任何AccessKey,直接使用URL即可

使用Python SDK生成签名URL(下载)

以下示例使用OSS Python SDK V2生成一个用于下载文件的预签名URL:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from datetime import timedelta

# 从环境变量加载凭证
credentials_provider = EnvironmentVariableCredentialsProvider()

# 配置Endpoint和Region
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket_name = "examplebucket"
object_name = "exampledir/exampleobject.pdf"

# 创建Bucket对象
auth = oss2.ProviderAuthV4(credentials_provider)
bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)

# 生成预签名URL,有效期30分钟
expires = timedelta(minutes=30)
result = bucket.presign('GET', object_name, expires=expires)

print("预签名URL:", result.url)
print("过期时间:", result.expiration)

使用Python SDK生成签名URL(上传)

以下示例生成一个用于上传文件的预签名URL:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 从环境变量加载凭证
credentials_provider = EnvironmentVariableCredentialsProvider()

endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
region = "cn-hangzhou"
bucket_name = "examplebucket"
object_name = "exampledir/exampleobject.txt"

# 创建Bucket对象
auth = oss2.ProviderAuthV4(credentials_provider)
bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)

# 生成用于PUT上传的预签名URL,有效期60秒
# slash_safe=True确保路径中的斜杠不会被转义
url = bucket.sign_url('PUT', object_name, 60, slash_safe=True)
print("上传预签名URL:", url)

上传者获得该URL后,只需发送HTTP PUT请求到该URL即可完成上传,无需任何OSS凭证。

签名URL的V4签名结构

一个完整的V4签名URL包含以下查询参数:

https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject
  ?x-oss-additional-headers=host
  &x-oss-credential=LTAI********************/20241203/cn-hangzhou/oss/aliyun_v4_request
  &x-oss-date=20241203T034420Z
  &x-oss-expires=86400
  &x-oss-signature=70c542eaf652ac291c0c343d63ac24ede41c0526661d9d4c63c0906a2686160c
  &x-oss-signature-version=OSS4-HMAC-SHA256

其中 x-oss-credential 包含AccessKeyId、日期、Region和服务名称。需要注意的是,URL中的斜杠需要进行URI编码。

3.2 STS临时凭证:为复杂场景提供临时身份

签名URL适用于单个文件的临时访问,但当需要为第三方应用提供持续的、多操作的OSS访问能力时,STS(Security Token Service)临时凭证是更好的选择。

STS的核心价值在于:

  • 无需泄露长期AccessKey给第三方
  • 可自定义访问权限和有效期限
  • 凭证过期后自动失效,无需手动撤销

STS临时授权的典型流程

以企业A授权企业B上传数据到OSS为例:

步骤一:企业A创建RAM用户,并授予该用户调用STS服务 AssumeRole 接口的权限(AliyunSTSAssumeRoleAccess系统策略)。

步骤二:企业A创建RAM角色,定义该角色被扮演时可以拥有的OSS访问权限。

步骤三:企业A调用STS AssumeRole 接口获取临时访问凭证(包括临时AccessKey ID、AccessKey Secret和SecurityToken),并将其传递给企业B。

步骤四:企业B使用临时凭证构造签名请求,访问OSS资源。临时凭证的有效时间最小为900秒,最大值以角色设定的最大会话时间为准。

使用STS临时凭证的注意事项

当使用STS临时账号生成预签名URL时,有效时长以两者中较小者为准。例如,STS临时凭证有效期为1200秒,预签名URL设置为3600秒,则实际有效期为1200秒。

OSS控制台中默认的URL有效时间为3600秒,最大值为32400秒。如果需要超过32400秒的有效期,必须使用ossutil或OSS SDK生成。

四、综合安全策略与最佳实践

4.1 多层防护的组合使用

单一的安全措施往往不够,建议将多种手段组合使用:

第一层:Bucket ACL设置为私有,确保默认情况下所有数据不公开。

第二层:配置Referer防盗链,防止其他网站盗用资源。

第三层:使用Bucket Policy或RAM Policy进行精细化权限控制,明确谁可以访问什么。

第四层:对于临时访问需求,使用签名URL或STS临时凭证,严格控制有效时间。

4.2 成本优化与安全加固

防盗链不仅是安全手段,也是成本控制手段。恶意盗链会导致大量的外网下行流量费用。建议定期检查OSS的流量监控数据,发现异常流量及时排查是否为盗链行为。

同时,建议启用OSS的日志记录功能,分析访问日志中的Referer字段,及时发现未授权的引用来源。

4.3 最小权限原则

无论是RAM Policy还是Bucket Policy,都应遵循最小权限原则——只授予完成工作所必需的最小权限集。避免使用 AliyunOSSFullAccess 这样的高权限系统策略,而是创建自定义策略,精确控制操作和资源范围。

对于生产环境,建议使用RAM角色和STS临时凭证替代长期AccessKey,减少密钥泄露的风险。

五、常见问题解答

问1:配置了Referer白名单后,为什么我的网站还是无法访问OSS图片?

答:最常见的原因是空Referer策略配置不当。如果您的网站使用HTTPS协议引用HTTP资源,或者用户使用隐私模式浏览器,请求可能不携带Referer。请检查防盗链配置中是否选择了"允许空Referer"。另外,请确认白名单中的域名是否同时包含了 http 和 https 两种协议。

问2:Bucket Policy和RAM Policy有什么区别?我应该用哪个?

答:Bucket Policy是基于资源的授权策略,直接附加在Bucket上,适合"谁可以访问这个Bucket"的场景(如跨账号授权、IP限制)。RAM Policy是基于身份的授权策略,附加在用户/角色上,适合"这个用户可以访问什么"的场景(如统一管理某个用户的所有权限)。两者可以同时使用,权限判定遵循"显式拒绝优先"原则。

问3:签名URL的有效期最长可以设置多久?

答:使用V4签名算法时,AccessKey签名URL最长有效期为7天(604800秒);使用STS临时凭证生成的签名URL最长有效期为12小时(43200秒),且以STS凭证的有效期为准。OSS控制台生成的URL默认有效期为3600秒,最大32400秒。

问4:为什么我配置了Bucket Policy基于IP限制访问后,某些请求仍然被拒绝?

答:首先检查acs:SourceIp条件是否正确配置了目标IP地址。其次,acs:SourceIp仅匹配源IP,不区分公网还是VPC内网。建议同时配置acs:SourceVpc来明确网络来源。另外,如果Bucket Owner自身访问也被拒绝,请检查Principal配置——当Principal为*且包含Condition时,策略对Bucket Owner也生效。

问5:防盗链中的黑名单和白名单同时存在时,哪个优先?

答:OSS会先判断黑名单,再判断白名单。这意味着即使某个域名在白名单中,如果它也在黑名单中,请求会被黑名单规则拦截。

问6:如何防止OSS资源被恶意刷流量?

答:建议从以下几个方面入手:1)Bucket ACL设置为私有,避免公开可读;2)配置Referer防盗链,限制仅允许特定域名引用;3)使用Bucket Policy限制访问IP范围;4)对敏感文件使用签名URL,控制访问时效;5)开启OSS的监控告警,及时发现异常流量。

相关文章

买阿里云服务器能便宜吗?十年代理揭秘 3 大省钱攻略!

买阿里云服务器能便宜吗?十年代理揭秘 3 大省钱攻略!

作为深耕阿里云代理领域 10 年的 “老司机”,经常被问到:“买阿里云服务器能便宜吗?有没有优惠价格?” 今天就用实打实的行业经验告诉你:不仅能便宜,选对渠道还能省一大笔! 这篇文章带你解锁阿里云服务…

做了 10 年腾讯云代理,我想跟你聊聊返佣那些事儿​

做了 10 年腾讯云代理,我想跟你聊聊返佣那些事儿​

最近总有朋友问我:“腾讯云有返点吗?腾讯云服务器能拿佣金不?返佣比例到底有多少?” 作为一个在腾讯云代理行业摸爬滚打了 10 年的 “老人”,今天就来跟大家好好…

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商的核心价值定位1. 代理商的角色与职责阿里云代理商作为阿里云生态的核心合作伙伴,承担着双重核心职能:• 产品销售:负责推广销售阿里云全系列云产品,包括云服务器ECS、云数据库RDS、对象存…

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

阿里云代理商返佣机制深度解析:头部代理优势与企业合作策略

01一、阿里云代理商的核心价值定位1. 代理商的角色与职责阿里云代理商作为阿里云生态的核心合作伙伴,承担着双重核心职能:• 产品销售:负责推广销售阿里云全系列云产品,包括云服务器ECS、云数据库RDS…

阿里云代理商有哪些?阿里云代理返点是真的么?

阿里云代理商有哪些?阿里云代理返点是真的么?

一,阿里云代理商基本介绍阿里云代理商通俗一点,就是指从事阿里云云服务器,云数据库等阿里云公有云产品销售的代理商,每销售一件阿里云公有云产品出去,阿里云给予该代理商一定比例的提成。在阿里云官方定义中,这…

2026阿里云代理商生态全解析:五级代理体系、返佣政策与企业上云指南

2026阿里云代理商生态全解析:五级代理体系、返佣政策与企业上云指南

一、阿里云五级代理体系:权益阶梯与合作价值1. 五级代理的核心权益差异阿里云构建了多层次的代理生态体系,涵盖全国总代理、区域核心代理、行业ISV(独立软件开发商)、金牌/银牌认证代理及标准代理五大核心…