目录
一、OSS 访问
1、OSS 文件上传
1)引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
2)编写文件上传逻辑代码
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
@Service
public class OssService {
/**
* OSS域名节点
*/
private final String endpoint = "<your-endpoint>";
/**
* OSS秘钥ID
*/
private final String accessKeyId = "<your-accessKeyId>";
/**
* OSS秘钥
*/
private final String accessKeySecret = "<your-accessKeySecret>";
/**
* OSS存储空间
*/
private final String bucketName = "<your-bucketName>";
/**
* 文件上传 OSS
* @param file 文件流
* @return 文件访问地址
*/
public String uploadFile(MultipartFile file) {
try {
// 创建OSS实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 生成文件名:文件名需要唯一,否则会覆盖
String filename = file.getOriginalFilename();
if (StringUtils.isNotEmpty(filename)) {
String ext = filename.substring(filename.lastIndexOf('.'));
filename = UUID.randomUUID().toString().replaceAll("-", "") + ext;
}
// 上传文件
PutObjectRequest request = new PutObjectRequest(bucketName, filename, file.getInputStream());
ossClient.putObject(request);
// 关闭OSSClient
ossClient.shutdown();
// 返回OSS文件访问路径
return "https://" + bucketName + "." + endpoint + "/" + filename;
} catch (Exception e) {
e.printStackTrace();
return "Upload OSS failed.";
}
}
}
- 上传的文件名可以包含分级路径,比如,文件名为 /example/example.jpg 则会自动创建 example 文件夹;
- 文件上传后的访问 URL 的格式为:
https://BucketName.Endpoint/ObjectName
,更多详细规则可以参考官方文档介绍:上传Object后如何获取访问URL
3)编写测试接口
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private OssService ossService;
@PostMapping("/file")
public String upload(MultipartFile file) {
return ossService.uploadFile(file);
}
}
更多文件上传功能,可以参考官方文档:https://help.aliyun.com/document_detail/84778.html
2、OSS 文件下载
/**
* 下载OSS文件
*/
public void downloadFile() {
// 创建OSS实例
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// 下载文件
String objectName = "d33cdc3968c8475daf87c1216ff8dcfb.jpg";
GetObjectRequest request = new GetObjectRequest(bucketName, objectName);
ossClient.getObject(request, new File("D:\\" + objectName));
//关闭OSSClient
ossClient.shutdown();
}
- objectName 为不包含 Bucket 名称在内的 Object 完整路径;
- getObject() 方法中,如果未指定本地路径,则下载后的文件默认保存到程序所属项目对应本地路径中。
本例以下载到本地文件为例,如果想要了解更多的下载功能可以参考官方文档:https://help.aliyun.com/document_detail/84822.html
二、STS 授权
1、STS 介绍
阿里云提供的 权限管理系统 或 访问控制服务 主要包含两部分,RAM(Resource Access Management)和 STS(Security Token Service):
- RAM 主要的作用是控制账号系统的权限,你可以使用 RAM 在主账号的权限范围内创建子用户,给不同的子用户分配不同的权限从而达到授权管理的目的;
- STS 是一个安全凭证(Token)的管理系统,你可以使用 STS 来完成对于临时用户的访问授权。
RAM 和 STS 解决的一个核心问题是在不暴露主账号的 AccessKey 的情况下安全的授权别人访问,因为一旦主账号的 AccessKey 暴露出去的话会带来极大的安全风险,别人可以随意操作该账号下所有的资源,盗取重要信息等:
- RAM 提供一种 长期有效 的权限控制机制,通过分出不同权限的 子账号,将不同的权限分给不同的用户,这样一旦子账号泄露也不会造成全局的信息泄露;
- STS 提供的是一种 临时访问授权 。通过 STS 可以返回 临时的 AccessKey 和 Token,这些信息可以直接发给临时用户用来访问 OSS。
2、STS 授权实战
1)准备工作
准备工作包括:创建 RAM 用户、为RAM用户授予请求 AssumeRole 的权限、创建用于获取临时访问凭证的角色、为角色授予上传文件的权限。具体过程可以参考官方给出的流程:https://help.aliyun.com/document_detail/100624.html
2)引入依赖
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
3)编写获取 STS 临时访问凭证
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import org.springframework.stereotype.Service;
@Service
public class OssService {
/**
* OSS秘钥ID
*/
private final String accessKeyId = "<your-accessKeyId>";
/**
* OSS秘钥
*/
private final String accessKeySecret = "<your-accessKeySecret>";
/**
* RAM角色的ARN
*/
private final String roleArn = "<your-roleArn>";
/**
* STS对应的域名节点
*/
private final String stsEndpoint = "<your-stsEndpoint>";
/**
* 获取STS访问凭证
*/
public Credentials getStsToken() {
try {
// 设置OSS相关信息
String regionId = "";
String sessionName = "PC";
DefaultProfile.addEndpoint("", regionId, "Sts", stsEndpoint);
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
// 构造 Client
DefaultAcsClient client = new DefaultAcsClient(profile);
AssumeRoleRequest request = new AssumeRoleRequest();
request.setMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName(sessionName);
request.setDurationSeconds(900L);
// 获取STS授权凭证
AssumeRoleResponse response = client.getAcsResponse(request);
return response.getCredentials();
} catch (ClientException e) {
e.printStackTrace();
return null;
}
}
}
注意:
- 和 OSS 直接访问不同的是,STS 获取授权凭证,除了需要 accessKeyId 和 accessKeySecret 以外,还需要 roleArn (RAM 角色的 ARN),并且 endpoint 不再使用普通的 OSS 域名节点,而是使用 STS 专属的 endpoint,不同域名对应点 STS 域名可以参考官方文档:STS 接入地址 ;
- regionId 表示 RAM 的地域 ID,以华东1(杭州)地域为例,regionId 填写为 cn-hangzhou,也可以保留默认值,默认值为空字符串;
- sessionName 表示角色会话名称,用来区分不同的令牌。
4)使用临时授权访问 OSS
/**
* 使用 STS 凭证上传文件
*/
public void uploadByStsToken() {
// 调用获取STS凭证
Credentials credentials = getStsToken();
String accessKeyId = credentials.getAccessKeyId();
String accessKeySecret = credentials.getAccessKeySecret();
String securityToken = credentials.getSecurityToken();
String ossEndpoint = <your-endpoint>
// 构建 Client,上传文件
OSS ossClient = new OSSClientBuilder().build(ossEndpoint, accessKeyId, accessKeySecret, securityToken);
String objectName = "demo/demo.jpg";
PutObjectRequest request = new PutObjectRequest(bucketName, objectName, new File("D:\\demo.jpg"));
ossClient.putObject(request);
// 关闭 Client
ossClient.shutdown();
}
注意:
- 1、使用 STS 进行访问 OSS 时,需要使用凭证返回的 accessKeyId 和 accessKeySecret;
- 2、访问的 endpoint 为所访问的 bucket 所属的 OSS 常规 endpoint 域名节点,并非 STS 对应的 endpoint。