相关链接:
osss授权访问API
访问控制AssumeRole API
STSJava示例 API
RAM配置
配置RAM账号
创建ram账号,类型选错后面会报错,一定选阿里云账号,这样的RAM账号为用户角色
找到自己添加的RAM账号后授权(前两个为系统策略,第三个账号为自定义的,添加方式如下)
添加自定义策略
{
“Version”: “1”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “oss:",
“Resource”: [
"acs:oss:😗:backet名称”
]
}
]
}
相关代码
AssumedRoleUser
package com.luntek.commons.utils.oss;
import lombok.Data;
import java.io.Serializable;
/**
* OSS的sts对象
* @description:
* @author: Czw
* @create: 2021-07-08 17:36
**/
@Data
public class AssumedRoleUser implements Serializable {
private static final long serialVersionUID = 6634691446546687825L;
//该角色临时身份的用户ID
private String assumedRoleId;
//指定角色的ARN。格式:acs:ram::$accountID:role/$roleName/$RoleSessionName 。
private String arn;
}
Credentials
package com.luntek.commons.utils.oss;
import lombok.Data;
import java.io.Serializable;
/**
* oss的sts证书对象
*
* @description:
* @author: Czw
* @create: 2021-07-08 17:33
**/
@Data
public class Credentials implements Serializable {
private static final long serialVersionUID = 7835637697691853544L;
//失效时间
private String expiration;
//安全令牌
private String securityToken;
//访问密钥
private String accessKeySecret;
//访问密钥标识
private String accessKeyId;
}
生成临时网址方法
/**
* 为私有权限桶的资源生成预签名网址,时长默认3600分钟
* 注意:由于RAM账号中角色sts-user-role只授予了读权限,所以无法使用此账号下载
* 阿里云服务器中配置RAM的用户角色(不能使用服务角色),为角色授权STS、OSS、配置自定义sts-access-bucket权限策略对应服务权限
* 权限策略配置为,如果想获取其他bucket中连接,可以在resource中添加bucket的连接:
* {
* "Version": "1",
* "Statement": [
* {
* "Effect": "Allow",
* "Action": "oss:*",
* "Resource": [
* "acs:oss:*:*:bucketName"
* ]
* }
* ]
* }
* 使用SDK获取获取到的JSON信息,转成StsInfo对象
* 使用StsInfo临时的accessId生成访问路径
* 可以通过expiration变量修改时长
*
* @param bucketName 资源所在的bucket
* @param objectName 资源名称
* @return 临时访问的网址路径
* @auther Czw
*/
public static String generatePresignedUrl(String bucketName, String objectName) {
String stsInfo = getStsInfo();
StsInfo info = JsonUtil.jsonToObject(stsInfo, StsInfo.class);
if (info == null) {
throw new BusinessException(CommonExEnum.OSS_STS_TRANSFORM_ERR);
}
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
String accessKeyId = info.getCredentials().getAccessKeyId();
String accessKeySecret = info.getCredentials().getAccessKeySecret();
// 从STS服务获取的安全令牌(SecurityToken)。
String securityToken = info.getCredentials().getSecurityToken();
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
// 设置签名URL过期时间为3600秒(1小时)。
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
// 关闭OSSClient。
ossClient.shutdown();
return url.toString();
}
获取sts信息
/**
* 获取sts的相关json信息
* 阿里云账号中RAM账号对应授权的角色名称:sts-user-role
* api地址:https://help.aliyun.com/document_detail/28786.html?spm=a2c4g.11186623.6.904.76ae3bdbheVce4
* <p>
* 响应示例:
* {
* "requestId": "2B4D7917-56F1-4EE6-A339-577022985C5C",
* "credentials": {
* "securityToken": "CAIS5QF1q6Ft5B2yfSjIr5fnJILc27dg5baJcV/CozIkONpCga74ujz2IH9PfXRrCewZtf8wlW1R5v4Zlqx6T55OSBQa4BC1LtMFnzm6aq/t5uaXj9Vd+rDHdEGXDxnkprywB8zyUNLafNq0dlnAjVUd6LDmdDKkLTfHWN/z/vwBVNkMWRSiZjdrHcpfIhAYyPUXLnzML/2gQHWI6yjybBEw4lUg0jgh08nlnJ3AsCi5pUbh1+oYq772JpWZdMR2NP99KYzqh7UrLfqdj3ULtEkXrfcu17Yh4ivc+8yGDkMU+RKCPvpcUR4JGoABgPcVwfez8/aG1w9P/057F4pPF9wWMK/FqDelQhzy/7Hl9NHRaNfiu0QZRmS1LBy91pITi9db/VMgQmAXkUM35V0PvJNWmtJ54BmyPLYf6YVXdYBxHJRqr0Bw4ByNlzSQNpSAyJ7/0AL3hGmEmlUDlADkTVwGVZH2k9ZV7+2Ks8Y\u003d",
* "accessKeySecret": "H1YBCopp6DuVcFdtpVPYoFM8pQ1bLNu9jMQNVWYn7M2Q",
* "accessKeyId": "STS.NTRo8h6hARtbsysG2q4UnnkSX",
* "expiration": "2021-07-08T10:32:21Z"
* },
* "assumedRoleUser": {
* "arn": "acs:ram::30074336:role/sts-user-role/alice",
* "assumedRoleId": "373153847337951803:alice"
* }
* }
*
* @return sts的json信息
* @auther Czw
*/
public static String getStsInfo() {
//构建一个阿里云客户端,用于发起请求。
//构建阿里云客户端时需要设置AccessKey ID和AccessKey Secret。
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
IAcsClient client = new DefaultAcsClient(profile);
//构造请求,设置参数。关于参数含义和设置方法,请参见API参考。
AssumeRoleRequest request = new AssumeRoleRequest();
request.setRegionId("cn-hangzhou");
//值为阿里云账号中RAM账号对应值,且sts-user-role账号“信任策略管理”中必须为RAM,即阿里云账号类型的RAM账号
request.setRoleArn("acs:ram::AcountId:role/RAM-ROLE");
request.setRoleSessionName("alice");
//发起请求,并得到响应。
try {
AssumeRoleResponse response = client.getAcsResponse(request);
return (new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
throw new BusinessException(CommonExEnum.OSS_STS_ERR);
} catch (ClientException e) {
e.printStackTrace();
log.error("ErrCode:{}", e.getErrCode());
log.error("ErrMsg:{}", e.getErrMsg());
log.error("RequestId:{}", e.getRequestId());
throw new BusinessException(CommonExEnum.OSS_STS_ERR);
}
}
JsonUtil json转换的类
package com.luntek.commons.utils;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
/**
* @author Marsj
* @description: 基于jackson 的json 工具类
* @date 2019/3/27
*/
public class JsonUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
/**
* 1.json转换成对象
*
* @param src json字符串
* @param clazz 类对象
* @return T 类型的obj
*/
public static <T> T jsonToObject(String src, Class<T> clazz) {
if (StringUtils.isEmpty(src) || clazz == null) {
return null;
}
try {
return clazz.equals(String.class) ? (T) src : objectMapper.readValue(src, clazz);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 2.对象转换成json
*
* @param obj 对象
* @param <T> json
* @return json
*/
public static <T> String objectToJson(T obj) {
if (obj == null) {
return null;
}
try {
return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* JSON字符串转List
*
* @param type 泛型对象
* @param listString 需要转换的字符串
* @return 对象列表
*/
public static <T> List<T> jsonToList(Class<T> type, String listString) {
return JSONObject.parseArray(listString, type);
}
}
代码有些地方需要修改,例如自己的账号信息还有ram信息等
访问效果,访问后直接下载图片