|
|
@@ -0,0 +1,145 @@
|
|
|
+package cn.edu.nju.plagdemo.api.impl;
|
|
|
+
|
|
|
+import cn.edu.nju.plagdemo.api.IOssApi;
|
|
|
+
|
|
|
+import cn.edu.nju.plagdemo.exception.DefinitionException;
|
|
|
+import cn.edu.nju.plagdemo.model.dto.plag.OssNameAndLinkDTO;
|
|
|
+import cn.edu.nju.plagdemo.model.vo.OssInfoVO;
|
|
|
+import cn.edu.nju.plagdemo.model.vo.OssTokenVO;
|
|
|
+import cn.edu.nju.plagdemo.utils.SimpleCache;
|
|
|
+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 lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * ali oss临时授权访问
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class OssApiImpl implements IOssApi {
|
|
|
+ // STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
|
|
|
+ @Value("${oss.endpoint}")
|
|
|
+ String endpoint = "";
|
|
|
+
|
|
|
+ // 填写步骤1生成的RAM用户访问密钥AccessKey ID和AccessKey Secret。
|
|
|
+ @Value("${oss.accesskey.id}")
|
|
|
+ String accessKeyId = "";
|
|
|
+
|
|
|
+ @Value("${oss.accesskey.secret}")
|
|
|
+ String accessKeySecret = "";
|
|
|
+
|
|
|
+ // 填写步骤3获取的角色ARN。
|
|
|
+ @Value("${oss.role.arn}")
|
|
|
+ String roleArn = "";
|
|
|
+
|
|
|
+ // 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
|
|
|
+ @Value("${oss.role.sessionname}")
|
|
|
+ String roleSessionName = "";
|
|
|
+
|
|
|
+ // regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
|
|
|
+ @Value("${oss.region}")
|
|
|
+ String regionId = "";
|
|
|
+
|
|
|
+ @Value("${oss.bucket}")
|
|
|
+ String bucket = "";
|
|
|
+
|
|
|
+ // 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。
|
|
|
+ // 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。
|
|
|
+ // 如果policy为空,则用户将获得该角色下所有权限。
|
|
|
+ String policy = "{\n" +
|
|
|
+ " \"Version\": \"1\",\n" +
|
|
|
+ " \"Statement\": [\n" +
|
|
|
+ " {\n" +
|
|
|
+ " \"Effect\": \"Allow\",\n" +
|
|
|
+ " \"Action\": [\n" +
|
|
|
+ " \"oss:GetObject\",\n" +
|
|
|
+ " \"oss:GetObjectAcl\",\n" +
|
|
|
+ " \"oss:DeleteObject\",\n" +
|
|
|
+ " \"oss:PutObject\",\n" +
|
|
|
+ " \"oss:PutObjectAcl\",\n" +
|
|
|
+ " \"oss:ListObjects\"\n" +
|
|
|
+ " ],\n" +
|
|
|
+ " \"Resource\": [\n" +
|
|
|
+ " \"acs:oss:*:*:plag-file-bucket/development/basefile/*\",\n" +
|
|
|
+ " \"acs:oss:*:*:plag-file-bucket/development/file/*\"\n" +
|
|
|
+ " ]\n" +
|
|
|
+ " }\n" +
|
|
|
+ " ]\n" +
|
|
|
+ "}";
|
|
|
+ // 设置临时访问凭证的有效时间为3600秒。
|
|
|
+ Long durationSeconds = 3600L;
|
|
|
+
|
|
|
+ private OssTokenVO getSTSToken() {
|
|
|
+ OssTokenVO stsToken = (OssTokenVO) SimpleCache.get("sts_token");
|
|
|
+ if(stsToken != null) return stsToken;
|
|
|
+ try {
|
|
|
+ // 添加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);
|
|
|
+ request.setDurationSeconds(durationSeconds);
|
|
|
+ final AssumeRoleResponse response = client.getAcsResponse(request);
|
|
|
+// System.out.println("Expiration: " + response.getCredentials().getExpiration());
|
|
|
+// System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
|
|
|
+// System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
|
|
|
+// System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
|
|
|
+// System.out.println("RequestId: " + response.getRequestId());
|
|
|
+ stsToken = new OssTokenVO();
|
|
|
+ stsToken.setSecurityToken(response.getCredentials().getSecurityToken());
|
|
|
+ stsToken.setAccessKeyId(response.getCredentials().getAccessKeyId());
|
|
|
+ stsToken.setAccessKeySecret(response.getCredentials().getSecurityToken());
|
|
|
+ SimpleCache.put("sts_token", stsToken, (durationSeconds - 5) * 1000);
|
|
|
+ return stsToken;
|
|
|
+ } catch (ClientException e) {
|
|
|
+ log.error("Failed:" +
|
|
|
+ "\nError code: " + e.getErrCode() +
|
|
|
+ "\nError message: " + e.getErrMsg() +
|
|
|
+ "\nRequestId: " + e.getRequestId(), e);
|
|
|
+ throw new DefinitionException(HttpStatus.INTERNAL_SERVER_ERROR, "获取sts token失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public OssInfoVO getOssClientInfo() { // type == "file" or "basefile"
|
|
|
+ OssTokenVO stsToken = getSTSToken();
|
|
|
+ return OssInfoVO.builder()
|
|
|
+ .token(stsToken)
|
|
|
+ .bucket(bucket)
|
|
|
+ .region(regionId)
|
|
|
+// .ossLink("development/" + type + "/" + fileName + "-" + new Date().getTime() + ".zip")
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
+ public OssNameAndLinkDTO getOssNameAndLink(String type, String fileName) {
|
|
|
+ if(!(type.equals("file") || type.equals("basefile"))) return null;
|
|
|
+ OssNameAndLinkDTO ossNameAndLinkDTO = new OssNameAndLinkDTO();
|
|
|
+ String ossName = fileName + "-" + new Date().getTime();
|
|
|
+ String ossLink = "development/" + type + "/" + ossName + ".zip";
|
|
|
+ ossNameAndLinkDTO.setOssName(ossName);
|
|
|
+ ossNameAndLinkDTO.setOssLink(ossLink);
|
|
|
+ return ossNameAndLinkDTO;
|
|
|
+ }
|
|
|
+}
|