<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.12.0</version> </dependency>
package com.gbps.biz.file.controller.oss;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.BucketReferer;
import com.aliyuncs.exceptions.ClientException;
import com.gbps.biz.file.FileEnum.GetOssObject;
import com.gbps.biz.file.FileEnum.GetPermission;
import com.gbps.biz.file.error.demo1.BaseError;
import com.gbps.biz.file.service.impl.oss.OssServiceImpl;
import com.gbps.biz.file.verification.AdminAuthorize;
import com.gbps.biz.file.verification.AdminXAuthToken;
import com.gbps.biz.user.api.UserRpcService;
import com.gbps.commonapiversion.ApiVersion;
import com.gbps.commoncolaexception.ExFactory;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.net.URL;
import java.util.Date;
import java.util.List;
/**
* @author: xxy
*/
@Slf4j
@RestController
@Tag(name = "OssController", description = "OssController")
@RequestMapping("/{apiVersion}/oss")
@Validated
@ApiVersion(1)
public class OssController {
@Value("${aliCloud.OSS.region}")
private String ossRegion;
@Value("${aliCloud.OSS.bucket}")
private String ossBucket;
@Value("${AccessKeyID}")
private String ossAccessKeyId;
@Value("${AccessKeySecret}")
private String ossAccessKeySecret;
@Value("${aliCloud.OSS.roleArn}")
private String ossRoleArn;
@Value("${aliCloud.OSS.end_point}")
private String endPoint;
@Value("${aliCloud.OSS.objectName}")
private String objectName;
/**
* 获取授权信息
* @return
* @throws ClientException
*/
@PostMapping("/getCredit/{type}/{path}")
@Operation(summary = "获取OSS临时凭证", tags = "OSS文件管理")
public JSONObject getCredit(@PathVariable("type") Integer type ,@PathVariable("path") String path) {
long userId = AdminXAuthToken.getUserId();
JSONObject jsonObject = new JSONObject();
JSONObject creditInfo = null;
try {//"sessionName"
creditInfo = OssServiceImpl.getCredit(String.valueOf(userId), ossRoleArn, ossAccessKeyId, ossAccessKeySecret, this.ossBucket);
}catch (ClientException e){
log.info(e.getErrMsg());
throw ExFactory.bizException(BaseError.FAILED_TO_GET_VISA);
}
//文件存放地域
jsonObject.put("region", ossRegion);
//临时访问accessKey
jsonObject.put("accessKeyId", creditInfo.getString(OssServiceImpl.ACCESS_KEY_ID));
//临时访问accessKeySecret
jsonObject.put("accessKeySecret", creditInfo.getString(OssServiceImpl.ACCESS_KEY_SECRET));
//临时访问安全token
jsonObject.put("securityToken", creditInfo.getString(OssServiceImpl.SECURITY_TOKEN));
//临时访问过期时间
jsonObject.put("expiration", creditInfo.getString(OssServiceImpl.EXPIRATION));
//bucket名称
jsonObject.put("bucket", this.ossBucket);
//endpoint地址
jsonObject.put("endPoint",this.endPoint);
//文件的存目录
String folder = GetPermission.findByKey(type)+ GetOssObject.findByKey(path);
jsonObject.put("basePath", String.format(objectName+"/%s", folder));
return jsonObject;
}
/**
* 获取授权信息
* @param objectName 文件名
*/
@GetMapping("/getUrl")
@Operation(summary = "根据存放的文件名获取私密文件url , tags = "OSS文件管理")
public String getURL(String objectName, HttpServletRequest request){
//获取referer
String currentReferer = request.getHeader("Referer");
long userId = AdminXAuthToken.getUserId();
JSONObject creditInfo = null;
try {
creditInfo = OssServiceImpl.getCredit(String.valueOf(userId), ossRoleArn, ossAccessKeyId, ossAccessKeySecret, this.ossBucket);
}catch (ClientException e){
log.info(e.getErrMsg());
return e.getErrMsg();
}
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
String accessKeyId = creditInfo.getString(OssServiceImpl.ACCESS_KEY_ID);
String accessKeySecret = creditInfo.getString(OssServiceImpl.ACCESS_KEY_SECRET);
// 从STS服务获取的安全令牌(SecurityToken)。
String securityToken = creditInfo.getString(OssServiceImpl.SECURITY_TOKEN);
// 创建OSSClient实例,用于返回访问的网址。
OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret, securityToken);
//创建ossGetReferer用于访问获取referer白名单
OSS ossGetReferer = new OSSClientBuilder().build(endPoint, ossAccessKeyId, ossAccessKeySecret);
try { //验证referer
// 获取存储空间Referer白名单列表。
BucketReferer br = ossGetReferer.getBucketReferer(ossBucket);
List<String> refererList = br.getRefererList();
for (String referer : refererList) {
if (currentReferer.equals(referer)){
// 设置签名URL过期时间为3600秒(1小时),返回的是毫秒数。
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
URL url = ossClient.generatePresignedUrl(ossBucket, objectName, expiration);
//可替换成加速地址
return url.toString();
}
}
} catch (OSSException oe) {
log.info("Error Message:" + oe.getErrorMessage()+"" +"Error Code:" + oe.getErrorCode());
return "BaseError.ACCESS_DENIED_BY_AUTHORIZERS_POLICY";
} finally {
if (ossClient != null) {
// 关闭OSSClient。
ossClient.shutdown();
// 关闭ossGetReferer。
ossGetReferer.shutdown();
}
}
return "BaseError.ACCESS_DENIED_BY_AUTHORIZERS_POLICY";
}
}
package com.gbps.biz.file.service.impl.oss;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author: Arthur
* @date: 2021/12/20 10:59
*/
public class OssServiceImpl {
public static Logger logger = LoggerFactory.getLogger(OssServiceImpl.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 REGION = "cn-shanghai";
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","oss:GetObject","oss:GetObjectAcl","oss:PutObjectAcl")).fluentPut("Resource", Arrays.asList("acs:oss:*:*:" + bucketName, "acs:oss:*:*:" + bucketName + "/*")));
policyObject.fluentPut("Statement", statements);
//logger.info("ali policy:{}", policyObject.toString());
//执行角色授权
IClientProfile profile = DefaultProfile.getProfile(REGION, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(policyObject.toJSONString());
//临时授权有效时间,从900到3600s
request.setDurationSeconds(3600L);
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().getSecurityToken());
jsonObject.put(EXPIRATION, response.getCredentials().getExpiration());
return jsonObject;
}
}
策略语法:
{
"Version": "1",
"Statement": [{
"Effect": "Allow",
"Action": [
"oss:PutObject",
"oss:GetObject",
"oss:GetObjectAcl",
"oss:PutObjectAcl"
],
"Principal": [
"*"
],
"Resource": [
"acs:oss:*:1111111111111:test/acs:oss:*:1111111111111:test",
"acs:oss:*:1111111111111:test/acs:oss:*:1111111111111:test/*"
]
}]
}