This commit is contained in:
清晨
2025-04-08 16:37:17 +08:00
commit 0c9d340a05
1659 changed files with 170293 additions and 0 deletions

View File

@@ -0,0 +1,324 @@
package com.ruoyi.controller;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.cos.auth.COSSigner;
import com.ruoyi.response.ResponseData;
import com.ruoyi.system.service.ISysDictDataService;
import com.tencent.cloud.CosStsClient;
import com.tencent.cloud.Policy;
import com.tencent.cloud.Response;
import com.tencent.cloud.Statement;
import com.tencent.cloud.cos.util.Jackson;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* @Author OCS
* @Date 2022/2/8 16:40
*/
@CrossOrigin
@RestController
@Slf4j
@RequestMapping("/api/cos")
@Api(tags = "OCS")
public class ApiOcsController {
@Autowired
private ISysDictDataService iSysDictDataService;
// 根据 github 提供的 maven 集成方法导入 java sts sdk使用 3.1.1 及更高版本
public static void main(String[] args) {
TreeMap<String, Object> config = new TreeMap<String, Object>();
try {
//这里的 SecretId 和 SecretKey 代表了用于申请临时密钥的永久身份(主账号、子账号等),子账号需要具有操作存储桶的权限。
String secretKey = "VXZWQPYaedvMC6vovAU3gJ1ogXXdvO1n";
String secretId = "AKIDSBQuX5mAZvHa2jNwSzWE0lNvNuMjA9gC";
String region = "ap-shanghai";
String bucket = "ddht-1324395003";
// 替换为您的云 api 密钥 SecretId
config.put("secretId", secretId);
// 替换为您的云 api 密钥 SecretKey
config.put("secretKey", secretKey);
// 初始化 policy
Policy policy = new Policy();
// 设置域名:
// 如果您使用了腾讯云 cvm可以设置内部域名
//config.put("host", "sts.internal.tencentcloudapi.com");
// 临时密钥有效时长,单位是秒,默认 1800 秒,目前主账号最长 2 小时(即 7200 秒),子账号最长 36 小时(即 129600
config.put("durationSeconds", 1800);
// 换成您的 bucket
config.put("bucket", bucket);
// 换成 bucket 所在地区
config.put("region", region);
// 开始构建一条 statement
Statement statement = new Statement();
// 声明设置的结果是允许操作
statement.setEffect("allow");
/**
* 密钥的权限列表。必须在这里指定本次临时密钥所需要的权限。
* 权限列表请参见 https://cloud.tencent.com/document/product/436/31923
* 规则为 {project}:{interfaceName}
* project : 产品缩写 cos相关授权为值为cos,数据万象(数据处理)相关授权值为ci
* 授权所有接口用*表示,例如 cos:*,ci:*
* 添加一批操作权限 :
*/
statement.addActions(new String[]{
"cos:PutObject",
// 表单上传、小程序上传
"cos:PostObject",
// 分块上传
"cos:InitiateMultipartUpload",
"cos:ListMultipartUploads",
"cos:ListParts",
"cos:UploadPart",
"cos:CompleteMultipartUpload",
// 处理相关接口一般为数据万象产品 权限中以ci开头
// 创建媒体处理任务
"ci:CreateMediaJobs",
// 文件压缩
"ci:CreateFileProcessJobs"
});
/**
* 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径
* 资源表达式规则分对象存储(cos)和数据万象(ci)两种
* 数据处理、审核相关接口需要授予ci资源权限
* cos : qcs::cos:{region}:uid/{appid}:{bucket}/{path}
* ci : qcs::ci:{region}:uid/{appid}:bucket/{bucket}/{path}
* 列举几种典型的{path}授权场景:
* 1、允许访问所有对象"*"
* 2、允许访问指定的对象"a/a1.txt", "b/b1.txt"
* 3、允许访问指定前缀的对象"a*", "a/*", "b/*"
* 如果填写了“*”,将允许用户访问所有资源;除非业务需要,否则请按照最小权限原则授予用户相应的访问权限范围。
*
* 示例授权examplebucket-1250000000 bucket目录下的所有资源给cos和ci 授权两条Resource
*/
statement.addResources(new String[]{
"qcs::cos:" + region + ":uid/" + bucket.split("-")[1] + ":" + bucket + "/*",
"qcs::ci:" + region + ":uid/" + bucket.split("-")[1] + ":bucket/" + bucket + "/*"});
// String secretKey = "VXZWQPYaedvMC6vovAU3gJ1ogXXdvO1n";
// String secretId = "AKIDSBQuX5mAZvHa2jNwSzWE0lNvNuMjA9gC";
//
// String region = "ap-shanghai";
// String bucket = "ddht-1324395003";
statement.addResources(new String[]{
"qcs::cos:ap-shanghai:uid/1324395003:ddht-1324395003/*",
"qcs::ci:ap-shanghai:uid/1324395003:bucket/ddht-1324395003/*"});
// 把一条 statement 添加到 policy
// 可以添加多条
policy.addStatement(statement);
// 将 Policy 示例转化成 String可以使用任何 json 转化方式,这里是本 SDK 自带的推荐方式
config.put("policy", Jackson.toJsonPrettyString(policy));
Response response = CosStsClient.getCredential(config);
System.out.println(response.credentials.tmpSecretId);
System.out.println(response.credentials.tmpSecretKey);
System.out.println(response.credentials.sessionToken);
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("no valid secret !");
}
}
// 根据 github 提供的 maven 集成方法导入 java sts sdk使用 3.1.1 及更高版本
@PostMapping("/signNew")
public ResponseData signNew() {
TreeMap<String, Object> config = new TreeMap<String, Object>();
try {
String secretKey = "VXZWQPYaedvMC6vovAU3gJ1ogXXdvO1n";
String secretId = "AKIDSBQuX5mAZvHa2jNwSzWE0lNvNuMjA9gC";
String region = "ap-shanghai";
String bucket = "ddht-1324395003";
SysDictData sysDictData = new SysDictData();
sysDictData.setDictType("storing_param");
List<SysDictData> list = iSysDictDataService.selectDictDataList(sysDictData);
for (SysDictData data : list) {
if ("Region".equals(data.getCode())) {
region = data.getDictValue();
}
if ("Bucket".equals(data.getCode())) {
bucket = data.getDictValue();
}
if ("SecretKey".equals(data.getCode())) {
secretKey = data.getDictValue();
}
if ("SecretId".equals(data.getCode())) {
secretId = data.getDictValue();
}
}
// 替换为您的云 api 密钥 SecretId
config.put("secretId", secretId);
// 替换为您的云 api 密钥 SecretKey
config.put("secretKey", secretKey);
// 初始化 policy
Policy policy = new Policy();
// 设置域名:
// 如果您使用了腾讯云 cvm可以设置内部域名
//config.put("host", "sts.internal.tencentcloudapi.com");
// 临时密钥有效时长,单位是秒,默认 1800 秒,目前主账号最长 2 小时(即 7200 秒),子账号最长 36 小时(即 129600
config.put("durationSeconds", 1800);
// 换成您的 bucket
config.put("bucket", bucket);
// 换成 bucket 所在地区
config.put("region", region);
// 开始构建一条 statement
Statement statement = new Statement();
// 声明设置的结果是允许操作
statement.setEffect("allow");
/**
* 密钥的权限列表。必须在这里指定本次临时密钥所需要的权限。
* 权限列表请参见 https://cloud.tencent.com/document/product/436/31923
* 规则为 {project}:{interfaceName}
* project : 产品缩写 cos相关授权为值为cos,数据万象(数据处理)相关授权值为ci
* 授权所有接口用*表示,例如 cos:*,ci:*
* 添加一批操作权限 :
*/
statement.addActions(new String[]{
"cos:PutObject",
// 表单上传、小程序上传
"cos:PostObject",
// 分块上传
"cos:InitiateMultipartUpload",
"cos:ListMultipartUploads",
"cos:ListParts",
"cos:UploadPart",
"cos:CompleteMultipartUpload",
// 处理相关接口一般为数据万象产品 权限中以ci开头
// 创建媒体处理任务
"ci:CreateMediaJobs",
// 文件压缩
"ci:CreateFileProcessJobs"
});
/**
* 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径
* 资源表达式规则分对象存储(cos)和数据万象(ci)两种
* 数据处理、审核相关接口需要授予ci资源权限
* cos : qcs::cos:{region}:uid/{appid}:{bucket}/{path}
* ci : qcs::ci:{region}:uid/{appid}:bucket/{bucket}/{path}
* 列举几种典型的{path}授权场景:
* 1、允许访问所有对象"*"
* 2、允许访问指定的对象"a/a1.txt", "b/b1.txt"
* 3、允许访问指定前缀的对象"a*", "a/*", "b/*"
* 如果填写了“*”,将允许用户访问所有资源;除非业务需要,否则请按照最小权限原则授予用户相应的访问权限范围。
*
* 示例授权examplebucket-1250000000 bucket目录下的所有资源给cos和ci 授权两条Resource
*/
statement.addResources(new String[]{
"qcs::cos:" + region + ":uid/" + bucket.split("-")[1] + ":" + bucket + "/*",
"qcs::ci:" + region + ":uid/" + bucket.split("-")[1] + ":bucket/" + bucket + "/*"});
// 把一条 statement 添加到 policy
// 可以添加多条
policy.addStatement(statement);
// 将 Policy 示例转化成 String可以使用任何 json 转化方式,这里是本 SDK 自带的推荐方式
config.put("policy", Jackson.toJsonPrettyString(policy));
Response response = CosStsClient.getCredential(config);
System.out.println(response.credentials.tmpSecretId);
System.out.println(response.credentials.tmpSecretKey);
System.out.println(response.credentials.sessionToken);
return ResponseData.success(response);
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException("no valid secret !");
}
}
@PostMapping("/sign")
public ResponseData sign(@RequestParam(value = "name") @NotBlank(message = "文件名称不能为空") String name) {
String region = "ap-shanghai";
String bucket = "ddht-1324395003";
String secretKey = "VXZWQPYaedvMC6vovAU3gJ1ogXXdvO1n";
String secretId = "AKIDSBQuX5mAZvHa2jNwSzWE0lNvNuMjA9gC";
SysDictData sysDictData = new SysDictData();
sysDictData.setDictType("storing_param");
List<SysDictData> list = iSysDictDataService.selectDictDataList(sysDictData);
for (SysDictData data : list) {
if ("Region".equals(data.getCode())) {
region = data.getDictValue();
}
if ("Bucket".equals(data.getCode())) {
bucket = data.getDictValue();
}
if ("SecretKey".equals(data.getCode())) {
secretKey = data.getDictValue();
}
if ("SecretId".equals(data.getCode())) {
secretId = data.getDictValue();
}
}
long startTimestamp = System.currentTimeMillis() / 1000;
long endTimestamp = startTimestamp + 30 * 60;
String endTimestampStr = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").
format(endTimestamp * 1000);
String keyTime = startTimestamp + ";" + endTimestamp;
String boundary = "----WebKitFormBoundaryZBPbaoYE2gqeB21N";
// 设置表单的body字段值
Map<String, String> formFields = new HashMap<>();
formFields.put("q-sign-algorithm", "sha1");
formFields.put("key", name);
formFields.put("q-ak", secretId);
formFields.put("q-key-time", keyTime);
// 构造policy参考文档: https://cloud.tencent.com/document/product/436/14690
String policy = "{\n" +
" \"expiration\": \"" + endTimestampStr + "\",\n" +
" \"conditions\": [\n" +
" { \"bucket\": \"" + bucket + "\" },\n" +
" { \"q-sign-algorithm\": \"sha1\" },\n" +
" { \"q-ak\": \"" + secretId + "\" },\n" +
" { \"q-sign-time\":\"" + keyTime + "\" }\n" +
" ]\n" +
"}";
// policy需要base64后算放入表单中
String encodedPolicy = new String(Base64.encodeBase64(policy.getBytes()));
// 设置policy
formFields.put("policy", encodedPolicy);
// 根据编码后的policy和secretKey计算签名
COSSigner cosSigner = new COSSigner();
String signature = cosSigner.buildPostObjectSignature(secretKey,
keyTime, policy);
// 设置签名
formFields.put("q-signature", signature);
String urlStr = "https://" + bucket + ".cos." + region + ".myqcloud.com";
formFields.put("host", urlStr);
formFields.put("bucket", bucket);
formFields.put("region", region);
formFields.put("secretId", secretId);
formFields.put("secretKey", secretKey);
return ResponseData.success(formFields);
}
}