OSS简介
阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。可以通过阿里云提供的简单的REST接口,在任何时间、任何地点、任何互联网设备上进行上传和下载数据。基于OSS,可以搭建出各种多媒体分享网站、网盘、个人和企业数据备份等基于大规模数据的服务。
sts介绍
阿里云STS(Security Token Service)是阿里云提供的一种临时访问权限管理服务。RAM提供RAM用户和RAM角色两种身份。其中,RAM角色不具备永久身份凭证,而只能通过STS获取可以自定义时效和访问权限的临时身份凭证,即安全令牌(STS Token)。
STS的优势:
- 使用STS Token,减少长期访问密钥(Accesskey)泄露的风险。
- STS Token具有时效性,可以自定义有效期,到期后将自动失效,无需定期轮换。
- 可以为STS Token绑定自定义权限策略,提供更加灵活和精细的云资源授权。
逻辑框图
![图片[1]-上传阿里云OSS最佳实践方案(web直传)-睿冰小站](https://www.r6b.cn/wp-content/uploads/2022/11/21t01.jpg)
代码实现
以下给出两个Java后端接口,分别是获取STS临时令牌接口与生成图像临时访问链接接口。
封装OSS工具类
public class OssUtil {
public static Logger logger = LoggerFactory.getLogger(OssUtil.class);
public static final String ACCESS_KEY_ID = "ACCESS_KEY_ID";
public static final String ACCESS_KEY_SECRET = "ACCESS_KEY_SECRET";
public static final String SECURITY_TOKEN = "SECURITY_TOKEN";
public static final String EXPIRATION = "EXPIRATION";
//这里使用cn-shanghai区域,具体根据实际情况而定
private static final String REGION = "cn-shanghai";
private static final String STS_API_VERSION = "2015-04-01";
/**
* 生成临时访问令牌
* @param userName
* @param roleArn
* @param accessKeyId
* @param accessKeySecret
* @param bucketName
* @return
* @throws ClientException
*/
public static JSONObject getCredit(String userName, String roleArn, String accessKeyId, String accessKeySecret, String bucketName) throws ClientException {
// 用于阿里云后台审计使用的临时名称,可根据实际业务传输,具体内容不影响服务使用
String roleSessionName = userName;
//运行时的策略权限,这里将权限放到了最大,可根据实际情况而定。在运行时,实际权限为这里设置的权限和第一步中角色配置的策略权限的交集
JSONObject policyObject = new JSONObject();
policyObject.fluentPut("Version", "1");
List<JSONObject> statements = new ArrayList<>();
statements.add(new JSONObject().fluentPut("Effect", "Allow").fluentPut("Action", Arrays.asList("oss:PutObject")).fluentPut("Resource", Arrays.asList("acs:oss:*:*:" + bucketName, "acs:oss:*:*:" + bucketName + "/*")));
policyObject.fluentPut("Statement", statements);
logger.info("ali policy:{}", policyObject);
//执行角色授权
IClientProfile profile = DefaultProfile.getProfile(REGION, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setVersion(STS_API_VERSION);
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
// request.setPolicy(policyObject.toJSONString());
//临时授权有效实践,从900到3600
request.setDurationSeconds(900L);
final AssumeRoleResponse response = client.getAcsResponse(request);
JSONObject jsonObject = new JSONObject();
jsonObject.put(ACCESS_KEY_ID, response.getCredentials().getAccessKeyId());
jsonObject.put(ACCESS_KEY_SECRET, response.getCredentials().getAccessKeySecret());
jsonObject.put(SECURITY_TOKEN, response.getCredentials().getBizSecurityToken());
jsonObject.put(EXPIRATION, response.getCredentials().getExpiration());
return jsonObject;
}
/**
* 生成图片的访问路径
* @param key
* @param roleArn
* @param accessKeyId
* @param accessKeySecret
* @param bucketName
* @return
*/
public static URL getImgUrl(String key, String roleArn, String accessKeyId, String accessKeySecret, String bucketName){
OSS client = new OSSClientBuilder().build("oss-cn-shanghai.aliyuncs.com", accessKeyId, accessKeySecret);
return client.generatePresignedUrl(bucketName, key, new Date(new Date().getTime() + 3600L*1000));
}
}
获取临时令牌与临时地址
@RestController
@RequestMapping("/oss")
public class OssController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
//属性注入,在yml配置文件中进行配置
@Value("${oss.region}")
private String ossRegion;
@Value("${oss.bucket}")
private String ossBucket;
@Value("${oss.accesskey.id}")
private String ossAccessKeyId;
@Value("${oss.accesskey.secret}")
private String ossAccessKeySecret;
@Value("${oss.role.arn}")
private String ossRoleArn;
/**
* 获取临时授权信息,进行图片上传操作
*
* @return
* @throws ClientException
*/
@GetMapping("/getCredit")
public ViewResult getCredit() throws ClientException {
JSONObject jsonObject = new JSONObject();
JSONObject creditInfo;
String basePath = "<基路径>";
//获取临时令牌
creditInfo = OssUtil.getCredit("<用户名>", ossRoleArn, ossAccessKeyId, ossAccessKeySecret, ossBucket);
//组装返回信息
//文件存放地域
jsonObject.put("region", ossRegion);
//临时访问accessKey
jsonObject.put("accessKeyId", creditInfo.getString(OssUtil.ACCESS_KEY_ID));
//临时访问accessKeySecret
jsonObject.put("accessKeySecret", creditInfo.getString(OssUtil.ACCESS_KEY_SECRET));
//临时访问token
jsonObject.put("securityToken", creditInfo.getString(OssUtil.SECURITY_TOKEN));
//临时访问过期时间
jsonObject.put("expiration", creditInfo.getString(OssUtil.EXPIRATION));
//bucket名称
jsonObject.put("bucket", ossBucket);
//文件的存放基目录
jsonObject.put("basePath", basePath);
return ViewResult.success(jsonObject);
}
/**
* 获取图片地址
* @param key
* @return
*/
@GetMapping("/geturl")
public ViewResult getUrl(@RequestParam String key){
URL url = OssUtil.getImgUrl(key, ossRoleArn, ossAccessKeyId, ossAccessKeySecret, ossBucket);
return ViewResult.success(url);
}
}
© 版权声明
文章版权归原作者所有,转载请注明出处。
THE END