阿里云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构造clientDefaultAcsClient 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;@Autowiredprivate 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){//默认nullString url = null;OSSClient ossClient = null;try {ossClient = initClient();InputStream input = new FileInputStream(file);// 创建上传Object的MetadataObjectMetadata 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获取bucketNameString bucketName = getBucketName(fileUrl);//根据url获取fileNameString 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获取bucketNameString bucketName = getBucketName(fileUrls.get(0));//根据url获取fileNameList<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获取bucketNameString bucketName = getBucketName(fileUrl);//根据url获取fileNameString 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获取bucketNameString bucketName = getBucketName(fileUrl);//根据url获取fileNameString 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";@Autowiredprivate STSUtil stsUtil;@ApiOperation(value = "STS-获取安全令牌", notes = "STS-获取安全令牌", httpMethod = "POST")@RequestMapping(value = "/getScurityToken", method = RequestMethod.POST)@ResponseBodypublic 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

阿里云STS临时令牌操作OSS云存储相关推荐

  1. 阿里云OSS对象存储-图文详解

    阿里云OSS对象存储 认识OSS 一.创建Bucket 二.后台服务接口编写 三.接口测试 认识OSS 在实际的项目中,经常要用到上传图片的地方,阿里云的OSS对象存储,可以很好的将我们上传的图片存储 ...

  2. 阿里云STS认证,golang版本

    记录一下生成sts临时令牌的过程: package mainimport ("fmt""github.com/aliyun/alibaba-cloud-sdk-go/se ...

  3. 使用STS临时访问凭证访问OSS

    假设您是一个移动App开发者,希望使用阿里云OSS服务来保存App的终端用户数据,并且要保证每个App用户之间的数据隔离.此时,您可以使用STS授权用户直接访问OSS. 阿里云OSS官网文档地址:使用 ...

  4. 阿里云OSS开启Sts临时访问控制

    阿里云OSS开启Sts临时访问控制 第一步.信息整理汇总 下面是整个过程中需要记录的数据,以及位置 其中AccessKey需要创建成功后,及时的记录,因为后续只会展示一个AccessKeyId,另外一 ...

  5. 阿里云OSS获取STS临时访问凭证

    参考阿里云官网地址:使用STS临时访问凭证访问OSS 细节记录 RAM Policy Editor生成授权策略 策略生成器工具:RAM Policy Editor STS接入地址 sts.开头 Str ...

  6. 使用前端JS上传文件到阿里云的OSS服务器,PHP生成STS临时访问凭证

    官方教程地址:https://help.aliyun.com/document_detail/383950.html?spm=a2c4g.383952.0.0 这篇文章主要是指出官方教程没有说明的地方 ...

  7. Java实现操作阿里云OSS云存储详解,含配置和完整代码

    最近使用java代码操作阿里云存储,分享给大家 目录 1.OSS云存储配置 2.获取accessKeyId和accessKeySecret 3.编写SpringBoot代码 3.1pom.xml文件引 ...

  8. 实现获取阿里云STS上传token

    一 配置概述 移动端配置 快速搭建移动应用直传服务 (aliyun.com)https://help.aliyun.com/document_detail/31920.html        配置获取 ...

  9. 阿里云OSS对象存储服务购买与基础使用指南

    对象存储服务(Object Storage Service,简称OSS),是基于阿里云飞天分布式系统的海量.安全和高可靠的云存储服务.简单来说,OSS就是一个可以上传.下载.分享文件的服务,这一点从实 ...

最新文章

  1. 关于Talend的Patch分支对应Eclipse开发环境的配置总结.
  2. 使用vue-cli快速构建项目--vue.js学习笔记1
  3. 1192 约瑟夫问题(1)
  4. java 课后习题 找零钱
  5. F#基本类型——Records
  6. 【codevs1026】逃跑的拉尔夫,广搜的胜利
  7. 99乘法表 (输入一个数,以该数为行数输出乘法表)
  8. 如何理解封装java_理解 Java 的三大特性之封装
  9. tag 和branch的区别
  10. 软件开发中如何评估工作量
  11. 适合于图像处理方向的SCI期刊杂志列表
  12. top1-Accuracy,top5-Accuracy举例精析
  13. Juniper SRX密码恢复
  14. 远程桌面蓝屏解决办法
  15. Ambarella面试小结
  16. 关闭英文拼写检查,关闭xml验证
  17. 前端背景图放置_CSS 背景图片排版
  18. AB测试的介绍与实施
  19. DOSBox简单指令
  20. 深度学习之upsampling downsampling

热门文章

  1. UI设计师在哪些就业方向受欢迎呢?
  2. 本地blast与nr/nt库
  3. qt 通过ODBC链接MYSQL
  4. Revit二次开发 ---->创建revit选项卡
  5. 天涯社区:寒门难出贵子
  6. android高仿京东秒杀,Android通过实现GridView的横向滚动实现仿京东秒杀效果
  7. 免费的webservice接口(天气预报/IP查询/股票查询/手机归属地等)
  8. 微信小程序——弹窗组件
  9. win10共享打印机怎么设置_win10、win7与XP如何共享文件和打印机(下)
  10. Lambda预主网接入视频教程