|
|
@@ -0,0 +1,188 @@ |
|
|
|
package com.tuoheng.admin.service.impl; |
|
|
|
|
|
|
|
import com.aliyun.oss.OSS; |
|
|
|
import com.aliyun.oss.OSSClientBuilder; |
|
|
|
import com.aliyun.oss.OSSException; |
|
|
|
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.tuoheng.admin.config.AliyuncsVodConfig; |
|
|
|
import com.tuoheng.admin.service.IAliyunOssService; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.net.URL; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Date; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
@Slf4j |
|
|
|
@Service |
|
|
|
public class AliyunOssServiceImpl implements IAliyunOssService { |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取临时访问凭证 |
|
|
|
* |
|
|
|
* @param roleSessionName 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。 |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
public static AssumeRoleResponse.Credentials getSecurityToken(String roleSessionName) { |
|
|
|
// STS接入地址,例如sts.cn-shanghai.aliyuncs.com。 |
|
|
|
String endpoint = "sts.cn-shanghai.aliyuncs.com"; |
|
|
|
// 填写步骤1生成的访问密钥AccessKey ID和AccessKey Secret。 |
|
|
|
String AccessKeyId = AliyuncsVodConfig.accessKeyId; |
|
|
|
String accessKeySecret = AliyuncsVodConfig.accessKeySecret; |
|
|
|
// 填写步骤3获取的角色ARN。 |
|
|
|
String roleArn = AliyuncsVodConfig.roleArn; |
|
|
|
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。 |
|
|
|
// String roleSessionName = "<yourRoleSessionName>"; |
|
|
|
// 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。 |
|
|
|
// 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。 |
|
|
|
String policy = "{\n" + |
|
|
|
" \"Version\": \"1\", \n" + |
|
|
|
" \"Statement\": [\n" + |
|
|
|
" {\n" + |
|
|
|
" \"Action\": [\n" + |
|
|
|
" \"oss:PutObject\"\n" + |
|
|
|
" ], \n" + |
|
|
|
" \"Resource\": [\n" + |
|
|
|
" \"acs:oss:*:*:ta-tech-image/imagedir/*\" \n" + |
|
|
|
" ], \n" + |
|
|
|
" \"Effect\": \"Allow\"\n" + |
|
|
|
" }\n" + |
|
|
|
" ]\n" + |
|
|
|
"}"; |
|
|
|
try { |
|
|
|
// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。 |
|
|
|
String regionId = ""; |
|
|
|
// 添加endpoint。适用于Java SDK 3.12.0及以上版本。 |
|
|
|
DefaultProfile.addEndpoint(regionId, "Sts", endpoint); |
|
|
|
// 添加endpoint。适用于Java SDK 3.12.0以下版本。 |
|
|
|
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint); |
|
|
|
// 构造default profile。 |
|
|
|
IClientProfile profile = DefaultProfile.getProfile(regionId, AccessKeyId, accessKeySecret); |
|
|
|
// 构造client。 |
|
|
|
DefaultAcsClient client = new DefaultAcsClient(profile); |
|
|
|
final AssumeRoleRequest request = new AssumeRoleRequest(); |
|
|
|
// 适用于Java SDK 3.12.0及以上版本。 |
|
|
|
request.setSysMethod(MethodType.POST); |
|
|
|
// 适用于Java SDK 3.12.0以下版本。 |
|
|
|
//request.setMethod(MethodType.POST); |
|
|
|
request.setRoleArn(roleArn); |
|
|
|
request.setRoleSessionName(roleSessionName); |
|
|
|
request.setPolicy(policy); // 如果policy为空,则用户将获得该角色下所有权限。 |
|
|
|
request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。 |
|
|
|
final AssumeRoleResponse response = client.getAcsResponse(request); |
|
|
|
log.info("Expiration: " + response.getCredentials().getExpiration()); |
|
|
|
log.info("Access Key Id: " + response.getCredentials().getAccessKeyId()); |
|
|
|
log.info("Access Key Secret: " + response.getCredentials().getAccessKeySecret()); |
|
|
|
log.info("Security Token: " + response.getCredentials().getSecurityToken()); |
|
|
|
log.info("RequestId: " + response.getRequestId()); |
|
|
|
return response.getCredentials(); |
|
|
|
} catch (ClientException e) { |
|
|
|
log.error("Error code: " + e.getErrCode()); |
|
|
|
log.error("Error message: " + e.getErrMsg()); |
|
|
|
log.error("RequestId: " + e.getRequestId()); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public URL generatePresignedUrl(String objectName) throws Throwable{ |
|
|
|
// Endpoint以华东2(上海)为例,其它Region请按实际情况填写。 |
|
|
|
String endpoint = "https://oss-cn-shanghai.aliyuncs.com"; |
|
|
|
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。 |
|
|
|
String accessKeyId = AliyuncsVodConfig.accessKeyId; |
|
|
|
String accessKeySecret = AliyuncsVodConfig.accessKeySecret; |
|
|
|
// 从STS服务获取的安全令牌(SecurityToken)。 |
|
|
|
AssumeRoleResponse.Credentials credentials = getSecurityToken("SessionTest"); |
|
|
|
String securityToken = credentials.getSecurityToken(); |
|
|
|
// 填写Bucket名称,例如examplebucket。 |
|
|
|
String bucketName = AliyuncsVodConfig.bucketName; |
|
|
|
// 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 |
|
|
|
// String objectName = "exampleobject.txt"; |
|
|
|
|
|
|
|
// 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。 |
|
|
|
// 创建OSSClient实例。 |
|
|
|
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken); |
|
|
|
|
|
|
|
try { |
|
|
|
// 设置签名URL过期时间为3600秒(1小时)。 |
|
|
|
Date expiration = new Date(new Date().getTime() + 3600 * 1000); |
|
|
|
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。 |
|
|
|
URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration); |
|
|
|
return url; |
|
|
|
} catch (OSSException oe) { |
|
|
|
log.error("Caught an OSSException, which means your request made it to OSS, " |
|
|
|
+ "but was rejected with an error response for some reason."); |
|
|
|
log.error("Error Message:" + oe.getErrorMessage()); |
|
|
|
log.error("Error Code:" + oe.getErrorCode()); |
|
|
|
log.error("Request ID:" + oe.getRequestId()); |
|
|
|
log.error("Host ID:" + oe.getHostId()); |
|
|
|
} catch (com.aliyun.oss.ClientException ce) { |
|
|
|
log.error("Caught an ClientException, which means the client encountered " |
|
|
|
+ "a serious internal problem while trying to communicate with OSS, " |
|
|
|
+ "such as not being able to access the network."); |
|
|
|
log.error("Error Message:" + ce.getMessage()); |
|
|
|
} finally { |
|
|
|
if (ossClient != null) { |
|
|
|
ossClient.shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public List<URL> generatePresignedUrls(String[] objectNameList) throws Throwable { |
|
|
|
// Endpoint以华东2(上海)为例,其它Region请按实际情况填写。 |
|
|
|
String endpoint = "https://oss-cn-shanghai.aliyuncs.com"; |
|
|
|
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。 |
|
|
|
String accessKeyId = AliyuncsVodConfig.accessKeyId; |
|
|
|
String accessKeySecret = AliyuncsVodConfig.accessKeySecret; |
|
|
|
// 从STS服务获取的安全令牌(SecurityToken)。 |
|
|
|
AssumeRoleResponse.Credentials credentials = getSecurityToken("SessionTest"); |
|
|
|
String securityToken = credentials.getSecurityToken(); |
|
|
|
// 填写Bucket名称,例如examplebucket。 |
|
|
|
String bucketName = AliyuncsVodConfig.bucketName; |
|
|
|
// 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。 |
|
|
|
// 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。 |
|
|
|
// String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"}; |
|
|
|
|
|
|
|
// 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。 |
|
|
|
// 创建OSSClient实例。 |
|
|
|
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken); |
|
|
|
|
|
|
|
try { |
|
|
|
// 设置签名URL过期时间为3600秒(1小时)。 |
|
|
|
Date expiration = new Date(new Date().getTime() + 3600 * 1000); |
|
|
|
|
|
|
|
List<URL> urlList = new ArrayList<URL>(); |
|
|
|
for(int i=0; i<objectNameList.length; i++){ |
|
|
|
URL url = ossClient.generatePresignedUrl(bucketName, objectNameList[i], expiration); |
|
|
|
urlList.add(url); |
|
|
|
} |
|
|
|
return urlList; |
|
|
|
} catch (OSSException oe) { |
|
|
|
log.error("Caught an OSSException, which means your request made it to OSS, " |
|
|
|
+ "but was rejected with an error response for some reason."); |
|
|
|
log.error("Error Message:" + oe.getErrorMessage()); |
|
|
|
log.error("Error Code:" + oe.getErrorCode()); |
|
|
|
log.error("Request ID:" + oe.getRequestId()); |
|
|
|
log.error("Host ID:" + oe.getHostId()); |
|
|
|
} catch (com.aliyun.oss.ClientException ce) { |
|
|
|
log.error("Caught an ClientException, which means the client encountered " |
|
|
|
+ "a serious internal problem while trying to communicate with OSS, " |
|
|
|
+ "such as not being able to access the network."); |
|
|
|
log.error("Error Message:" + ce.getMessage()); |
|
|
|
} finally { |
|
|
|
if (ossClient != null) { |
|
|
|
ossClient.shutdown(); |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |