STS临时授权访问OSS

STS临时授权访问OSS需要配合RAM子账号一起使用

具体使用流程参考:STS临时授权访问OSS

这里我列出我的代码,以备以后复制使用。

后端代码

依赖

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.2.2</version>
</dependency>

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-sts</artifactId>
    <version>3.0.0</version>
</dependency>

Controller

package com.jdcloud.provider.web.sts;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.jdcloud.provider.model.vo.OssTokenVO;
import com.jdcloud.util.wrapper.WrapMapper;
import com.jdcloud.util.wrapper.Wrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * 阿里云OSS STS
 *
 * @author leigq
 */
@Slf4j
@RestController
@RequestMapping("/aliyun/sts")
public class AliyunStsController {

    /**
     * 获取 OSS 签名授权
     *
     * @return
     * @author leigq
     * @date 2018-12-17 15:08:55
     **/
    @GetMapping("/oss/tokens")
    public Wrapper getOssToken() {
        // 创建阿里云 OSS 临时token
        AssumeRoleResponse ossToken = createOssToken();
        if (Objects.isNull(ossToken)) {
            return WrapMapper.error("获取 OSS 签名授权失败!");
        }
        // 阿里 OSS 配置
        AssumeRoleResponse.Credentials credentials = ossToken.getCredentials();
        // 构建 OSS token 返回给前端
        OssTokenVO ossTokenVO = OssTokenVO.builder()
                // region每个地方不一样,下面是深圳的:shenzhen
                .region("oss-cn-shenzhen")
                .accessKeyId(credentials.getAccessKeyId())
                .accessKeySecret(credentials.getAccessKeySecret())
                .securityToken(credentials.getSecurityToken())
                .expiration(credentials.getExpiration())
                // OSS bucket名称
                .bucket("leigq-bucket")
                .build();
        return WrapMapper.ok(ossTokenVO);
    }

    /**
     * 创建阿里云 OSS 临时token
     * @author leigq
     * @return
     */
    private AssumeRoleResponse createOssToken() {
        /*
         * 子账号的 accessKeyId、accessKeySecret、roleArn,注意:子账号需赋予 AliyunSTSAssumeRoleAccess(调用STS服务AssumeRole接口的权限)权限
         * */
        String accessKeyId = "LTAIEYh****o1Ukv";
        String accessKeySecret = "7JjHqPaGKGfXH****KEFqB3oys8Gv4";
        String roleArn = "acs:ram::1915198****60148:role/tst-test";

        //roleSessionName时临时Token的会话名称,自己指定用于标识你的用户,或者用于区分Token颁发给谁
        //要注意roleSessionName的长度和规则,不要有空格,只能有'-'和'_'字母和数字等字符
        String roleSessionName = "session-name";
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            DefaultProfile.addEndpoint("", "", "Sts", "sts.aliyuncs.com");
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            //POST请求
            request.setMethod(MethodType.POST);
            //https协议
            request.setProtocol(ProtocolType.HTTPS);
            //持续时间, 只能设置 15min - 1hr 之间
            request.setDurationSeconds(900L);
            //角色id
            request.setRoleArn(roleArn);
            //应用程序标识(自己定义)
            request.setRoleSessionName(roleSessionName);
            // 发起请求,并得到response
            AssumeRoleResponse acsResponse = client.getAcsResponse(request);
            return acsResponse;
        } catch (ClientException e) {
            log.error("创建阿里云 OSS 临时token异常", e);
        }
        return null;
    }
}

上面用到的OssTokenVO实体:

package com.jdcloud.provider.model.vo;

import lombok.Builder;
import lombok.Data;

/**
 * 阿里OSS Token VO
 *
 * @author leigq
 */
@Data
@Builder
public class OssTokenVO {

    private String region;

    private String accessKeyId;

    private String accessKeySecret;

    private String securityToken;

    private String bucket;

    private String expiration;

}

用浏览器请求此接口,结果如下:
在这里插入图片描述
tips:每次请求数据都会发生变化。

前端代码

前端先请求上面的接口,获取到region、accessKeyId、accessKeySecret、stsToken,就可以上传图片了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <input type="file" name="picFieldName" id="picFieldId" onchange="uploadPic(this)" />
    <!-- 引入在线资源 -->
    <script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-5.3.0.min.js"></script>
    <script>
        var client = new OSS.Wrapper({
            region: 'oss-cn-shenzhen',
            accessKeyId: 'STS.NKR9sKxWY****bVpecXJq2Ujc',
            accessKeySecret: 'H2hC2kT7tyEt5B5****HHV7MJdovTweDx1ugoK5BYZXc',
            stsToken: 'CAIS8gF1q6Ft5B2yfSjIr4jncsn/lYh47oqdW0TnlGU2VMVd3ZDBgTz2IHpOfnNsCeAWsvUxnm1V5vsflqVoRoReREvCKM1565kPX7o+nVqE6aKP9rUhpMCPOwr6UmzWvqL7Z+H+U6muGJOEYEzFkSle2KbzcS7YMXWuLZyOj+wMDL1VJH7aCwBLH9BLPABvhdYHPH/KT5aXPwXtn3DbATgD2GM+qxsmtvvnm5bCsUKF1QGhkbREnemrfMj4NfsLFYxkTtK40NZx****yyNK43BIjvws1vYepWeX7o3MXQMMvkXbbvC79cZ0aRRlfbj54HDgGy0G/hqAARZcV0zbN+Tm9xpy6qrS7Bw/tw1Sn/zG+/hImKRSTdxz7GjLc/CvnefWQQ47bu1cK9Z38pm8kfo+etFY06j89hz+yNiDd+xjEPkgm3rIA/lvAn4oHSN0z0PGjFzxDTCcupEDd7/MJcReo7aQFuRVbO0We/jGobAqNNXGSY5/l9QD',
            bucket: 'bitrade-sz-oss'
        });
        function uploadPic(obj) {
            // 获取文件流
            var file = obj.files[0];
            // 路径
            var storeAs = "studio_course/" + file.name;
            console.log(file.name + ' => ' + storeAs);
            client.put(storeAs, file).then(function (result) {
                console.log(result);
            }).catch(function (err) {
                console.log(err);
            });
        }
    </script>
</body>
</html>

上传测试

在这里插入图片描述
在这里插入图片描述
正常上传!

遇到的问题

posted @ 2019-06-23 19:32  leigq  阅读(627)  评论(0编辑  收藏  举报