OSS支持对云盒Bucket设置防盗链,即通过对访问来源设置白名单的机制,避免OSS资源被其他人盗用。
功能介绍
防盗链功能通过设置Referer白名单以及是否允许空Referer,限制仅白名单中的域名可以访问您Bucket内的资源。OSS支持基于HTTP和HTTPS header中表头字段Referer的方法设置防盗链。
是否进行防盗链验证的具体场景如下:
- 仅当通过签名URL或者匿名访问Object时,进行防盗链验证。
- 当请求的Header中包含
Authorization
字段,不进行防盗链验证。
- 用户A在https://10.10.10.10嵌入test.jpg图片,当浏览器请求访问此图片时会带上https://10.10.10.10的Referer,此场景下OSS将允许该请求的访问。
- 用户B盗用了test.jpg的图片链接并将其嵌入https://192.168.0.0,当浏览器请求访问此图片时会带上https://192.168.0.0的Referer,此场景下OSS将拒绝该请求的访问。
Referer配置规则
- 单个Bucket支持配置多个Referer。通过控制台设置Referer时,使用回车作为换行符分隔;通过API设置Referer时,使用英文逗号(,)分隔。
- Referer支持使用通配符星号(*)和问号(?)。
- 通配符星号(*)表示使用星号代替0个或多个字符。如果Referer白名单配置为*.aliyun.com,且不允许空Referer的情况下,则只有HTTP或HTTPS header中包含Referer字段的请求才能访问OSS资源,例如help.aliyun.com、www.aliyun.com等;如果Referer白名单配置为*.aliyun.com,且允许空Referer的情况下,则Referer为空的请求也允许访问OSS资源。
- 通配符问号(?)表示使用问号代替一个字符。如果设置了包含通配符问号(?)的Referer白名单,且不允许空Referer的情况下,则只有HTTP或HTTPS Header中包含Referer字段的请求才能访问OSS资源。如果设置了包含通配符问号(?)的Referer白名单,且允许空Referer的情况下,则Referer为空的请求也允许访问OSS资源。
- Referer支持使用反斜线(\)对通配符星号(*)和问号(?)进行转义。
- Referer默认截断QueryString。如有特殊需求,可设置不允许截断QueryString。
例如,Referer设置为http://www.example.com/?action=nop,由于OSS匹配该Referer时默认截断QueryString,即使用http://www.example.com/进行匹配。如果希望OSS使用http://www.example.com/?action=nop进行Referer匹配,请通过设置AllowTruncateQueryString参数为false实现不允许截断QueryString。关于设置不允许截断QueryString的具体操作,请参见PutBucketReferer。
设置不允许截断QueryString时,Referer匹配规则有以下注意事项:
- 不解码QueryString
通过 http://www.example.com/?job_id=task$01访问OSS时,可能该访问URL会被继续保留为 http://www.example.com/?job_id=task$01,也可能被转义为 http://www.example.com/?job_id=task%2401。通过Referer进行匹配时,不会对访问URL中的QueryString进行解码,示例如下:
- 当Referer设置为http://www.example.com/?job_id=task%2401的情况下,通过http://www.example.com/?job_id=task$01请求访问OSS时,OSS将拒绝该请求。
- 当Referer设置为http://www.example.com/?job_id=task$01的情况下,通过http://www.example.com/?job_id=task%2401请求访问OSS时,OSS将拒绝该请求。
- 忽略QueryString中的参数大小写
通过Referer进行匹配时,会忽略QueryString中的大小写。即当Referer设置为http://www.example.com/?action=nop的情况下,通过http://www.examplecom/?ACTION=NOP请求访问OSS时,OSS将允许该请求。
- 不解析QueryString中的参数
默认情况下,浏览器会将http://example.com/?a=b&b=c与http://example.com/?b=c&a=b视为相同的访问URL。但是通过Referer进行匹配时,不会对QueryString中的参数进行解析,因此http://example.com/?a=b&b=c与http://example.com/?b=c&a=b会被视为不同的访问URL。即当Referer设置为http://example.com/?a=b&b=c的情况下,通过http://example.com/?b=c&a=b请求访问OSS时,OSS将拒绝该请求。
- 不解码QueryString
Referer配置效果
- 如果Referer白名单为通配符星号(*),且不允许空Referer,则带Referer且Referer不为空的请求会被允许。
- 如果Referer白名单为通配符星号(*),且允许空Referer,则带Referer且Referer为空的请求会被允许。
- 如果Referer白名单不为通配符星号(*),且不允许空Referer,则只有Referer属于白名单的请求被允许,其他请求(包括Referer为空的请求)会被拒绝。
- 如果Referer白名单不为通配符星号(*),但允许空Referer,则Referer为空的请求和符合白名单的请求会被允许,其他请求都会被拒绝。
云盒Bucket
- 登录OSS管理控制台。
- 在左侧导航栏,单击云盒Bucket,然后单击目标Bucket名称。
- 在左侧导航栏,选择 。
- 在防盗链页面,打开防盗链开关。
- 在Referer输入框中,填写域名或IP地址,支持通配符星号(*)和问号(?),多个Referer以换行分隔。示例如下:
- 配置为
www.aliyun.com
,可匹配如www.aliyun.com/123、www.aliyun.com.cn等以www.aliyun.com为前缀的地址。 - 通配符星号(*)表示使用星号代替0个或多个字符。例如配置为
*www.aliyun.com/
,可匹配如http://www.aliyun.com/和https://www.aliyun.com/地址。配置为*.aliyun.com
,可匹配如help.aliyun.com、www.aliyun.com等地址。 - 通配符问号(?)表示使用问号代替一个字符。
- 支持带端口的域名或IP地址,例如www.example.com:8080、10.10.10.10:8080等地址。
- 配置为
- 在空Referer区域,选择是否允许Referer为空。
空Referer表示HTTP或HTTPS请求中,不带Referer字段或Referer字段为空。
如果不允许空Referer,则只有HTTP或HTTPS Header中包含Referer字段的请求才能访问OSS资源。
说明 当您使用OSS的云盒Bucket域名(例如examplebucket.cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox-control.aliyuncs.com)预览MP4文件时,由于浏览器默认会同时发出两个请求,其中一个为带Referer的请求,另一个为空Referer的请求,因此设置防盗链时必须同时满足在Referer中添加Bucket域名,且允许空Referer的条件。当您使用OSS的Bucket域名预览非MP4文件时,则仅需允许空Referer。 - 在截断QueryString区域,选择是否允许截断QueryString。
- 在Referer输入框中,填写域名或IP地址,支持通配符星号(*)和问号(?),多个Referer以换行分隔。示例如下:
- 单击保存。
使用阿里云SDK
仅支持通过Java SDK设置防盗链,Java SDK要求3.15.0及以上版本。
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.BucketReferer;
import java.util.ArrayList;
import java.util.List;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
public class Demo {
public static void main(String[] args) throws Exception {
// 填写云盒Bucket的数据域名。
String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 填写云盒Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写云盒Bucket所在地域。
String region = "cn-hangzhou";
// 填写云盒ID。
String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
// 创建OSSClient实例。
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
conf.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(new DefaultCredentialProvider(accessKeyId, accessKeySecret))
.clientConfiguration(conf)
.region(region)
.cloudBoxId(cloudBoxId)
.build();
try {
List<String> refererList = new ArrayList<String>();
// 添加Referer白名单。Referer参数支持通配符星号(*)和问号(?)。
refererList.add("http://www.aliyun.com");
refererList.add("http://www.*.com");
refererList.add("http://www.?.aliyuncs.com");
// 设置Referer列表。设置为true表示Referer字段允许为空,设置为false表示Referer字段不允许为空。
BucketReferer br = new BucketReferer(true, refererList);
ossClient.setBucketReferer(bucketName, br);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
使用命令行工具ossutil
关于使用ossutil设置防盗链的具体操作, 请参见添加或修改防盗链配置。
使用REST API
如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketReferer。
更多参考
- 当您需要限定符合特定条件的用户能够访问您云盒Bucket内的全部或部分资源、对资源授予相关操作权限等,建议您使用Bucket Policy。例如您可以通过配置Bucket Policy的来源IP,限制符合指定IP或IP地址段的用户才能访问某个云盒Bucket。关于配置Bucket Policy的具体操作,请参见Bucket Policy。
- 关于验证防盗链是否生效的更多信息,请参见OSS验证防盗链是否生效。
- 关于使用防盗链过程中遇到的常见问题,请参见OSS防盗链(Referer)配置及错误排除。