提交
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user