为了能到远方,脚下的每一步都不能少.|

玩单机的零度

园龄:2年2个月粉丝:1关注:8

📂工作
🔖java
2023-02-09 11:02阅读: 147评论: 0推荐: 0

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;
}

参考使用STS临时访问凭证访问OSS

本文作者:玩单机的零度

本文链接:https://www.cnblogs.com/cxyfyf/p/17104555.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   玩单机的零度  阅读(147)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起