阿里云STS临时令牌操作OSS云存储

隐身守侯 提交于 2019-12-23 18:04:02

阿里云STS临时令牌操作OSS云存储

参考:官方文档1官方文档2

STS获取临时令牌操作OSS云存储

项目集成了swagger2自动接口文档,如未集成,需要将@Api、@ApiOperation等注解去掉

为什么要使用sts去操作?

直接使用账号的权限去操作OSS,账号拥有所有权限,使用RAM创建账号子用户,分离部分权限出来,提高OSS安全性能。

前期准备

阿里云控制台操作步骤

通过OSS SDK与STS SDK的结合使用,实现使用STS临时授权访问OSS。假设有一个名为qizy-test的Bucket用于存储用户数据,现将利用用户子账号结合STS实现OSS权限控制访问。

  • 创建用户子账号。
  1. 云账号登录RAM控制台。
  2. 在左侧导航栏的人员管理菜单下,单击用户。
  3. 单击新建用户。
  4. 输入登录名称和显示名称。
  5. 在访问方式区域下,选择编程访问。
  6. 单击确定,然后单击复制保存访问密钥(AccessKeyID 和 AccessKeySecret)。
  7. 勾选目标RAM用户,单击添加权限,被授权主体会自动填入。
  8. 在添加权限页面,为已创建子账号添加AliyunSTSAssumeRoleAccess权限。
  9. 为已创建子账号添加AliyunOSSFullAccess权限。
    在这里插入图片描述
  • 创建权限策略。
  1. 云账号登录RAM控制台。
  2. 在左侧导航栏的权限管理菜单下,单击权限策略管理。
  3. 单击新建权限策略。
  4. 填写策略名称和备注。
  5. 配置模式选择可视化配置或脚本配置。
    以脚本配置为例,对ram-test添加ListObjects与GetObject等只读权限,在策略内容中配置脚本示例如下:
#我的Bucket名:“qizy-test”
{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                    "oss:ListBuckets",
                    "oss:GetBucketStat",
                    "oss:GetBucketInfo",
                    "oss:GetBucketAcl" 
                      ],    
            "Resource": "acs:oss:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                    "oss:Get*",
                    "oss:Put*",
                    "oss:List*",
                    "oss:DeleteObject"
                    ],
            "Resource": "acs:oss:*:*:qizy-test"
        },
        {
            "Effect": "Allow",
            "Action": [
                    "oss:Get*",
                    "oss:Put*",
                    "oss:List*",
                    "oss:DeleteObject"
            ],
            "Resource": "acs:oss:*:*:qizy-test/*"
        }
    ]
}
# 脚本讲解:
#    第一段的意思是允许用户登录,
#    第二段允许操作bucket,
#    第三段允许操作bucket内的资源。
# 这样我们的子用户控制Oss某个Bucket配置就完成了,开发时只需要用到子用户的AccessKey ID和Access Key Secret
# 如果需要对权限进行限制,可以对以上代码进行修改。
  • 创建角色并记录角色ARN。
  1. 云账号登录RAM控制台。
  2. 在左侧导航栏,单击RAM角色管理。
  3. 单击新建RAM角色,选择可信实体类型为阿里云账号,单击下一步。
  4. 在新建RAM角色页面,填写RAM角色名称和备注,本示例RAM角色名称为RamOssTest。
  5. 选择云账号为当前云账号。
  6. 单击完成。
  7. 单击为角色授权,被授权主体会自动填入。
  8. 在添加权限页面,选择自定义权限策略,添加步骤2中创建的权限策略。
  9. 记录角色的ARN。
    添加权限策略后,页面如下图所示:在这里插入图片描述
  • 获取临时访问凭证STS AK与SecurityToken。
    具体java中进行实现
    详见下面的步骤

代码中集成

依赖

# pom.xml
<!-- aliyun  STS -->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-sts</artifactId>
    <version>3.0.0</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>4.1.1</version>
</dependency>

配置文件

#sts.properties
#阿里云STS配置
sts.endpoint=sts.cn-hangzhou.aliyuncs.com
sts.accessKeyId=LTAI4FrLPBGyB2KYrp******
sts.accessKeySecret=WJPEEnybNOhsjksVHyq******
sts.roleArn=acs:ram::1373540******9:role/ra******test
# 取个名称 用以唯一性标识
sts.roleSessionName=test-sts-securityToken

代码实现-获取accessToken

工具类
# STSUtil.java
package com.learning.ssm_swagger.util;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
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.learning.ssm_swagger.entity.ali.STSToken;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

/**
 * @Author Qizy
 * @Date 2019/12/12 17:32
 * @Version 1.0
 **/
@Getter
@Setter
@Component
@Configuration
@PropertySource(value = { "classpath:sts.properties" })
public class STSUtil {
    @Value("${sts.accessKeyId}")
    public String accessKeyId;

    @Value("${sts.accessKeySecret}")
    public String accessKeySecret;

    @Value("${sts.endpoint}")
    public String endpoint;

    @Value("${sts.roleArn}")
    public String roleArn;

    @Value("${sts.roleSessionName}")
    public String roleSessionName;

    public STSToken getSecurityToken(){
        STSToken stsToken = new STSToken();
        /*String policy = "{\n" +
                "    \"Version\": \"1\", \n" +
                "    \"Statement\": [\n" +
                "        {\n" +
                "            \"Action\": [\n" +
                "                \"oss:*\"\n" +
                "            ], \n" +
                "            \"Resource\": [\n" +
                "                \"acs:oss:*:*:*\" \n" +
                "            ], \n" +
                "            \"Effect\": \"Allow\"\n" +
                "        }\n" +
                "    ]\n" +
                "}";*/
        try {
            // 添加endpoint(直接使用STS endpoint,前两个参数留空,无需添加region ID)
            DefaultProfile.addEndpoint("", "", "Sts", endpoint);
            // 构造default profile(参数留空,无需添加region ID)
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            // 用profile构造client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setMethod(MethodType.POST);
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            // 若policy为空,则用户将获得该角色下所有权限
            //request.setPolicy(policy);
            // 设置凭证有效时间
            request.setDurationSeconds(1000L);
            final AssumeRoleResponse response = client.getAcsResponse(request);
            System.out.println("Expiration: " + response.getCredentials().getExpiration());
            System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
            stsToken.setStsAccessKeyId(response.getCredentials().getAccessKeyId());
            System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
            stsToken.setStsAccessKeySecret(response.getCredentials().getAccessKeySecret());
            System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
            stsToken.setSecurityToken(response.getCredentials().getSecurityToken());
            System.out.println("RequestId: " + response.getRequestId());
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return stsToken;
    }
}
实体类
package com.learning.ssm_swagger.entity.ali;

/**
 * @Author Qizy
 * @Date 2019/12/13 12:02
 * @Version 1.0
 **/
public class STSToken {

    private String securityToken="";
    private String stsAccessKeyId="";
    private String stsAccessKeySecret="";

    public String getSecurityToken() {
        return securityToken;
    }

    public void setSecurityToken(String securityToken) {
        this.securityToken = securityToken;
    }

    public String getStsAccessKeyId() {
        return stsAccessKeyId;
    }

    public void setStsAccessKeyId(String stsAccessKeyId) {
        this.stsAccessKeyId = stsAccessKeyId;
    }

    public String getStsAccessKeySecret() {
        return stsAccessKeySecret;
    }

    public void setStsAccessKeySecret(String stsAccessKeySecret) {
        this.stsAccessKeySecret = stsAccessKeySecret;
    }
}

OSSUtil.java 这个工具类中的initClient()方法实现了使用access密钥进行获取OSS实例。
相比于不使用sts的oss工具类,只需要修改initClient方法即可。

# OSSUtil.java
package com.learning.ssm_swagger.util;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.learning.ssm_swagger.entity.ali.STSToken;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Component
@Configuration
@PropertySource(value = { "classpath:oss.properties" })
public class OSSUtil {

    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OSSUtil.class);

    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    @Value("${oss.accessKeyId}")
    public String accessKeyId;

    @Value("${oss.accessKeySecret}")
    public String accessKeySecret;

    @Value("${oss.endpoint}")
    public String endpoint;

    @Value("${oss.bucketName}")
    public String bucketName;

    private OSSClient client;

    @Autowired
    private STSUtil stsUtil;

    /**************************************************************************
     ************************      oss对象相关      ****************************
     *************************************************************************/
    /**
     * 初始化oss对象
     * @return
     */
    private OSSClient initClient() {
        if (null == client) {
            ClientConfiguration conf = new ClientConfiguration();
            conf.setConnectionTimeout(5000);
            conf.setMaxErrorRetry(10);
            STSToken stsToken = stsUtil.getSecurityToken();
//            conf.setProxyHost("127.0.0.1");
//            conf.setProxyPort(8080);
            client = new OSSClient(endpoint, stsToken.getStsAccessKeyId(), stsToken.getStsAccessKeySecret(), stsToken.getSecurityToken(), conf);
        }
        return client;
    }

    /**
     * 获取OSS对象
     * @return
     */
    public OSSClient getClientObject(){
        return initClient();
    }


    /**************************************************************************
     ************************       bucket相关      ****************************
     *************************************************************************/
    /**
     * 创建bucket存储空间
     * @param bucketName 存储空间名称
     * @return Boolean
     */
    public Boolean createBucket(String bucketName){
        Boolean back = false;
        OSSClient ossClient = null;
        try {
            ossClient = initClient();

            //判断bucket是否存在
            if(doesBucketExist(bucketName)){
                return  back;
            }

            // 创建CreateBucketRequest对象。
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);

            // 如果创建存储空间的同时需要指定存储类型以及数据容灾类型, 可以参考以下代码。
            // 此处以设置存储空间的存储类型为标准存储为例。
            // createBucketRequest.setStorageClass(StorageClass.Standard);
            // 默认情况下,数据容灾类型为本地冗余存储,即DataRedundancyType.LRS。如果需要设置数据容灾类型为同城冗余存储,请替换为DataRedundancyType.ZRS。
            // createBucketRequest.setDataRedundancyType(DataRedundancyType.ZRS)

            // 创建存储空间。
            ossClient.createBucket(createBucketRequest);
            back = true;
        } catch (OSSException oe) {
            oe.printStackTrace();
            return null;
        } catch (ClientException ce) {
            ce.printStackTrace();
            return null;
        }  finally {
            ossClient.shutdown();
            client = null;
        }

        return back;
    }

    /**
     * 删除指定的bucket
     * @param bucketName 存储空间名称
     * @return
     */
    public Boolean deleteBucket(String bucketName){
        Boolean back = false;
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            // 删除存储空间。
            ossClient.deleteBucket(bucketName);
            back = true;
        } catch (OSSException oe) {
            oe.printStackTrace();
            return null;
        } catch (ClientException ce) {
            ce.printStackTrace();
            return null;
        } finally {
            ossClient.shutdown();
            client = null;
        }

        return back;
    }

    /**
     * 判断存储空间是否存在
     * @param bucketName 存储空间名称
     * @return
     */
    private Boolean doesBucketExist(String bucketName){
        OSSClient ossClient = initClient();
        return ossClient.doesBucketExist(bucketName);
    }

    /**
     * 获取所有存储空间
     * @return 存储空间集合
     */
    public List<Bucket> getAllBuckets(){
        OSSClient ossClient = null;
        List<Bucket> back = new ArrayList<>();
        try {
            ossClient = initClient();
            back = ossClient.listBuckets();
        } catch (OSSException oe) {
            oe.printStackTrace();
            return null;
        } catch (ClientException ce) {
            ce.printStackTrace();
            return null;
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return back;
    }

    /**
     * 根据url获取bucketName
     * @MethodName: getBucketName
     * @Description: 根据url获取bucketName
     * @param fileUrl 文件url
     * @return String bucketName
     */
    public String getBucketName(String fileUrl){
        String http = "http://";
        String https = "https://";
        int httpIndex = fileUrl.indexOf(http);
        int httpsIndex = fileUrl.indexOf(https);
        int startIndex  = 0;
        if(httpIndex==-1){
            if(httpsIndex==-1){
                return null;
            }else{
                startIndex = httpsIndex+https.length();
            }
        }else{
            startIndex = httpIndex+http.length();
        }
        int endIndex = fileUrl.indexOf(".oss-");
        return fileUrl.substring(startIndex, endIndex);
    }


    /**************************************************************************
     ************************       文件读取相关      **************************
     *************************************************************************/
    /**
     * 上传文件到OSS 成功再返回的文件路径
     * @MethodName: putObject
     * @Description: 上传文件 底层方法:PutObjectRequest
     * @param file
     * @param fileType
     * @param fileName
     * @return String
     */
    private String putObject(File file,String fileType,String fileName){
        //默认null
        String url = null;
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            InputStream input = new FileInputStream(file);
            // 创建上传Object的Metadata
            ObjectMetadata meta = new ObjectMetadata();
            // 设置上传内容类型
            meta.setContentType(contentType(fileType));
            // 被下载时网页的缓存行为
            meta.setCacheControl("no-cache");
            //创建上传请求
            PutObjectRequest request = new PutObjectRequest(bucketName, fileName,input,meta);
            ossClient.putObject(request);
            //上传成功再返回的文件路径
            url = endpoint.replaceFirst("http://","http://"+bucketName+".")+"/"+fileName;
        } catch (OSSException oe) {
            oe.printStackTrace();
            return null;
        } catch (ClientException ce) {
            ce.printStackTrace();
            return null;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return url;
    }

    /**
     * OSS单文件上传
     * @MethodName: uploadFile
     * @Description: OSS单文件上传
     * @param file
     * @param fileType 文件后缀
     * @return String 文件地址
     */
    public String uploadFile(File file,String fileType){
        //文件名,根据UUID来
        String fileName = UUID.randomUUID().toString().toUpperCase().replace("-", "")+"."+fileType;
        return putObject(file,fileType,fileName);
    }

    /**
     *
     * @MethodName: updateFile
     * @Description: 更新文件:只更新内容,不更新文件名和文件地址。
     *        (因为地址没变,可能存在浏览器原数据缓存,不能及时加载新数据,例如图片更新,请注意)
     * @param file
     * @param fileType
     * @param oldUrl
     * @return String
     */
    public String updateFile(File file,String fileType,String oldUrl){
        String fileName = getFileName(oldUrl);
        if(fileName==null) {
            return null;
        }
        return putObject(file,fileType,fileName);
    }

    /**
     *
     * @MethodName: replaceFile
     * @Description: 替换文件:删除原文件并上传新文件,文件名和地址同时替换
     *        解决原数据缓存问题,只要更新了地址,就能重新加载数据)
     * @param file
     * @param fileType 文件后缀
     * @param oldUrl 需要删除的文件地址
     * @return String 文件地址
     */
    public String replaceFile(File file,String fileType,String oldUrl){
        //先删除原文件
        boolean flag = deleteFile(oldUrl);
        if(!flag){
            //更改文件的过期时间,让他到期自动删除。
        }
        return uploadFile(file, fileType);
    }

    /**
     * 根据url,单文件删除
     * @MethodName: deleteFile
     * @Description: 单文件删除 底层方法:DeleteObjectsRequest
     * @param fileUrl 需要删除的文件url
     * @return boolean 是否删除成功
     */
    public boolean deleteFile(String fileUrl){
        //根据url获取bucketName
        String bucketName = getBucketName(fileUrl);
        //根据url获取fileName
        String fileName = getFileName(fileUrl);
        if(bucketName==null||fileName==null) {
            return false;
        }
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            GenericRequest request = new DeleteObjectsRequest(bucketName).withKey(fileName);
            ossClient.deleteObject(request);
        } catch (Exception oe) {
            oe.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return true;
    }

    /**
     *
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较慢):适用于不同endPoint和BucketName
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     */
    public int deleteFiles(List<String> fileUrls){
        int count = 0;
        for (String url : fileUrls) {
            if(deleteFile(url)){
                count++;
            }
        }
        return count;
    }

    /**
     *
     * @MethodName: batchDeleteFiles
     * @Description: 批量文件删除(较快):适用于相同endPoint和BucketName
     * @param fileUrls 需要删除的文件url集合
     * @return int 成功删除的个数
     */
    public int batchDeleteFiles(List<String> fileUrls){
        //成功删除的个数
        int deleteCount = 0;
        //根据url获取bucketName
        String bucketName = getBucketName(fileUrls.get(0));
        //根据url获取fileName
        List<String> fileNames = getFileName(fileUrls);
        if(bucketName==null||fileNames.size()<=0) {
            return 0;
        }
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(fileNames);
            DeleteObjectsResult result = ossClient.deleteObjects(request);
            deleteCount = result.getDeletedObjects().size();
        } catch (OSSException oe) {
            oe.printStackTrace();
            throw new RuntimeException("OSS服务异常:", oe);
        } catch (ClientException ce) {
            ce.printStackTrace();
            throw new RuntimeException("OSS客户端异常:", ce);
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return deleteCount;

    }

    /**
     * 根据url获取fileName
     * @MethodName: getFileName
     * @Description: 根据url获取fileName
     * @param fileUrl 文件url
     * @return String fileName
     */
    private String getFileName(String fileUrl){
        String str = "aliyuncs.com/";
        int beginIndex = fileUrl.indexOf(str);
        if(beginIndex==-1) {
            return null;
        }
        return fileUrl.substring(beginIndex+str.length());
    }

    /**
     * 根据url获取fileNames集合
     * @MethodName: getFileName
     * @Description: 根据url获取fileNames集合
     * @param fileUrls 文件url集合
     * @return List<String>  fileName集合
     */
    private List<String> getFileName(List<String> fileUrls){
        List<String> names = new ArrayList<>();
        for (String url : fileUrls) {
            names.add(getFileName(url));
        }
        return names;
    }

    /**
     * 获取文件类型
     * @MethodName: contentType
     * @Description: 获取文件类型
     * @param fileType 文件类型
     * @return String
     */
    private String contentType(String fileType){
        fileType = fileType.toLowerCase();
        String contentType = "";
        switch (fileType) {
            case "bmp":    contentType = "image/bmp";
                break;
            case "gif":    contentType = "image/gif";
                break;
            case "png":
            case "jpeg":
            case "jpg":    contentType = "image/jpeg";
                break;
            case "html":contentType = "text/html";
                break;
            case "txt":    contentType = "text/plain";
                break;
            case "vsd":    contentType = "application/vnd.visio";
                break;
            case "ppt":
            case "pptx":contentType = "application/vnd.ms-powerpoint";
                break;
            case "doc":
            case "docx":contentType = "application/msword";
                break;
            case "xml":contentType = "text/xml";
                break;
            case "mp4":contentType = "video/mp4";
                break;
            default: contentType = "application/octet-stream";
                break;
        }
        return contentType;
    }

    /**
     * 下载文件至本地
     * @param fileUrl 文件oss路径url
     * @param filePath 文件本地存储路径
     * @return
     */
    public boolean downLoadFile(String fileUrl,String filePath){
        //根据url获取bucketName
        String bucketName = getBucketName(fileUrl);
        //根据url获取fileName
        String fileName = getFileName(fileUrl);
        if(bucketName==null||fileName==null) {
            return false;
        }
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            ossClient.getObject(new GetObjectRequest(bucketName, fileName), new File(filePath+fileName));
        } catch (Exception oe) {
            oe.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return true;
    }

    /**
     * 读取文件内容
     * @param fileUrl
     * @return
     */
    public Boolean readFile(String fileUrl){
        //根据url获取bucketName
        String bucketName = getBucketName(fileUrl);
        //根据url获取fileName
        String fileName = getFileName(fileUrl);
        if(bucketName==null||fileName==null) {
            return null;
        }
        OSSClient ossClient = null;
        try {
            ossClient = initClient();
            OSSObject ossObject = ossClient.getObject(bucketName, fileName);
            // 读取文件内容。
            System.out.println("Object content:");
            BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                }
                System.out.println("\n" + line);
            }
        } catch (Exception oe) {
            oe.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
            client = null;
        }
        return true;
    }

}

简单的测试一下

# STSController.java
package com.learning.ssm_swagger.controller.ali;

import com.learning.ssm_swagger.util.OSSUtil;
import com.learning.ssm_swagger.util.STSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;

/**
 * @Author Qizy
 * @Date 2019/12/11 9:43
 * @Version 1.0
 **/
@Controller
@RequestMapping("/sts")
@Api(value="STS Service Controller", description = "阿里云STS测试")
public class STSController {

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    private static final String TO_PATH="upLoad";
    private static final String RETURN_PATH="success";

    @Autowired
    private STSUtil stsUtil;

    @ApiOperation(value = "STS-获取安全令牌", notes = "STS-获取安全令牌", httpMethod = "POST")
    @RequestMapping(value = "/getScurityToken", method = RequestMethod.POST)
    @ResponseBody
    public String testUpload() throws Exception {
        return stsUtil.getSecurityToken().getSecurityToken();
    }
}
# OSSController.java 不需要修改

控制台结果打印

# console
Expiration: 2019-12-13T07:03:26Z
Access Key Id: STS.NSni************stTju
Access Key Secret: FBwmS7KzJkeJ******************6cpy4qdvJzcbA
Security Token: CAIS/wF1q6Ft5B2yf********************xCAkHQgbeFfm5HBlzz2IHlEfXJpAu0dsvU/n2tQ7voflr9vRoRZAFfYdo5r459K6wK9crbGuMGztQSRJgUiXDr9MQXy+eOPScebJYqvV5XAQlTAkTAJstmeXD6+XlujHISUgJp8FLo+VRW5ajw0b7U/ZHEVyqkgOGDWKOymPzPzn2PUFzAIgAdnjn5l4qnNqa/1qDim1QalkbJJ/9mvc8L7Ppk0ba0SCYnlgLZEEYPayzNV5hRw86N7sbdJ4z+vvKvGWgkIuEzdbrGIo400d1chOvUgebRNqf/njuF1ofDDPjZCDtuC7YsagAGUQMoQJylEAMLeLNAXo0+CO6ZH+xQEltnYlT/1tNtCb4iYayth4erFHOTXSHaqpn/8jUzyaOxQHAtBx5UV0a88ZWxsPCoYwB1JJjE+/dm+*****************************************************
RequestId: ADA**4E7-2**E-4**7-9**3-04E******9A4
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!