alioss直传获取sts临时授权凭据
🧀前言
公司使用的是阿里oss资源服务器,由于要上传大文件几百mb甚至几gb,考虑到普通上传接口走后台存在网络压力,且跟服务器带宽有着直接关联,所以考虑使用前端直传阿里oss的方式上传大文件,前端想要访问oss服务器,一般采用后端获取sts临时授权凭证的方法。前提需要有阿里oss服务器,所有的配置均来自这里。
相关pom依赖如下:
<!-- 阿里 OSS存储 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.15.1</version>
</dependency>
<!-- lombok工具 在父级pom 进行全局引入 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
后台实现方法
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Service
@RefreshScope
public class AliServiceImpl {
@Resource
private AliOssStsConfig stsConfig;
@Resource
private RedisService redisService;
/**
* 获取ali oss 直传 sts临时授权凭据 <br/>
* tips:凭据缓存一小时,一小时后重新获取,若上传时间超过一小时,此时前端凭据失效,需要前端重新拉取
* @date: 2022年12月27日09:26:16
*/
@Override
public StsTokenVO getStsToken() {
// 缓存标识
String cacheStsFlag = "Ali-OSS:STS-token";
// 若本地sts凭据不为空
if (redisService.exists(cacheStsFlag)) {
// 获取缓存
Object cache = redisService.get(cacheStsFlag);
if (Objects.nonNull(cache)) {
// 转对象
StsTokenVO stsTokenVO = Po2DtoUtil.convertor(cache , StsTokenVO.class);
// token不为空返回对象
if (StringUtils.isNotBlank(stsTokenVO.getSecurityToken())) return stsTokenVO;
}
}
StsTokenVO tokenVO = new StsTokenVO();
try {
// 添加endpoint(直接使用STS endpoint,前两个参数留空,无需添加region ID)
DefaultProfile.addEndpoint("", "Sts", stsConfig.getStsEndpoint());
// 进行角色授权 构造default profile(参数留空,无需添加region ID)
IClientProfile profile = DefaultProfile.getProfile("", stsConfig.getStsAccessKeyId(), stsConfig.getStsAccessKeySecret());
// 用profile构造client
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setSysMethod(MethodType.POST);
request.setRoleArn(stsConfig.getStsRoleArn()); // role-Arn
request.setRoleSessionName(stsConfig.getStsRoleSessionName());
request.setDurationSeconds(3600L); // 会话持续时间1小时
// 针对该临时权限可以根据该属性赋予规则,格式为json,没有特殊要求,默认为空
// request.setPolicy(policy); // Optional
// 获取响应中的身份凭据对象
final AssumeRoleResponse response = client.getAcsResponse(request);
AssumeRoleResponse.Credentials credentials = response.getCredentials();
tokenVO.setAccessKeyId(credentials.getAccessKeyId()); // 临时访问密钥标识
tokenVO.setAccessKeySecret(credentials.getAccessKeySecret()); // 临时访问密钥
tokenVO.setSecurityToken(credentials.getSecurityToken()); // 临时安全令牌
tokenVO.setBucketName(stsConfig.getStsBucketName());
tokenVO.setRegion(stsConfig.getStsRegion());
// token过期时间 当前时间 + 1小时 时间戳格式
tokenVO.setExpiration(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() + 3600 * 1000);
// 缓存sts凭据,有效期1小时
redisService.add(cacheStsFlag, tokenVO, 3600L);
return tokenVO;
} catch (ClientException e) {
throw new RuntimeException("获取阿里云STS临时授权权限失败,错误信息:" +e);
}
}
}
dto
采用nacos或yaml文件里面oss服务器的配置,使用@value进行注入
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
* 描述 oss前端直传 sts临时授权凭证
*
* @author fyf
* Create by 2022/12/27 9:06
*/
@Getter
@Setter
@Component
@RefreshScope
public class AliOssStsConfig {
/** sts端点 */
@Value("${ali.stsEndpoint}")
private String stsEndpoint;
/** sts资源桶 */
@Value("${ali.stsBucketName}")
private String stsBucketName;
/** sts账号key */
@Value("${ali.stsAccessKeyId}")
private String stsAccessKeyId;
/** sts账号密钥 */
@Value("${ali.stsAccessKeySecret}")
private String stsAccessKeySecret;
/** 权限标识 */
@Value("${ali.stsRoleArn}")
private String stsRoleArn;
/** sts会话标识 */
@Value("${ali.stsRoleSessionName}")
private String stsRoleSessionName;
/** sts资源区域 */
@Value("${ali.stsRegion}")
private String stsRegion;
}
本文作者:玩单机的零度
本文链接:https://www.cnblogs.com/cxyfyf/p/17104555.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步