临时密钥生成及使用指引

最近更新时间:2024-08-28 09:55:41

我的收藏
密钥是向 COS 发起请求时的身份认证凭证,包括临时密钥和永久密钥。临时密钥 适用于前端直传等临时授权场景,永久密钥 适用于受信任的用户,安全性高的场景。本文将为您介绍如何使用临时密钥。

临时密钥简介

临时密钥(临时访问凭证) 是通过 CAM 云 API 提供的接口,获取到权限受限的密钥。当需要发起 COS API 请求时,需要用到获取临时密钥接口返回信息中 的 TmpSecretId、TmpSecretKey 和 Token 三个字段,用于计算签名。有关临时密钥的权限介绍,请参见 使用临时密钥访问 COS
注意:
在使用临时密钥授权访问时,请务必根据业务需要,按照最小权限原则进行授权。
您直接授予所有资源(resource:*),或者所有操作(action:*)权限,存在由于权限范围过大导致的数据安全风险。
您在申请临时密钥时,指定了 action 权限范围,那么申请到的临时密钥也只能在权限范围内进行操作。例如您在申请临时密钥时,指定了可以往存储桶 examplebucket-1-1250000000 上传文件的权限范围,那么申请到的密钥不能将文件上传到 examplebucket-2-1250000000,也不能从 examplebucket-1-1250000000 中下载文件。

生成临时密钥方式

在申请临时密钥过程中,可以通过设置权限策略 policy 字段,限制操作和资源,将权限限制在指定的范围内。
有关 COS API 授权策略,可参见:
临时密钥是通过如下两种方式生成:
方式一:COS STS SDK ,适用于开发语言场景。
方式二:STS 云 API ,适用于用户更方便快捷的生成密钥。

方式一:COS STS SDK

COS 针对 STS 提供了 SDK 和样例,目前已有 Java、Nodejs、PHP、Python、Go 等多种语言的样例。可以通过提供的 COS STS SDK 方式获取临时密钥。各个 SDK 的使用说明请参见 Github 上的 README 和样例。各语言 GitHub 地址如下表格所示:
语言类型
代码安装地址
代码示例地址
Java
.NET
Go
NodeJS
PHP
Python
注意:
STS SDK 为了屏蔽 STS 接口本身版本间的差异性,返回参数结构不一定与 STS 接口完全一致,详情请参见 Java SDK 文档

方式二:STS 云 API

通过 STS 云 API 获取临时密钥,请求参数请参见 获取联合身份临时访问凭证 。示例参数如下:
输入参数
参考值
说明
必选
Region
华北地区(北京)ap-beijing
操作的资源所属的地域为北京
Name
test
自定义调用方的英文名称为 test。
Policy
{"version":"2.0","statement":[{"effect":"allow","action":["name/cos:PutObject","name/cos:DeleteObject"],"resource":"*"}]}
描述策略语法版本 version 为“2.0”。
描述声明产生的结果 effect 是“允许”
描述允许的操作 action 为"name/cos:PutObject"(上传对象)、"name/cos:DeleteObject"(删除对象),更多接口请参见 支持 CAM 的对象存储业务接口
描述授权的具体数据 resource,授予操作 action 的所有资源的操作权限
DurationSeconds
3600
指定临时证书的有效期 3600秒,不指定默认为1800秒。
在输入参数中选择或输入参考值后,点击发起请求后,可获得 TmpSecretId、TmpSecretKey、Token。




生成临时密钥代码示例

假设您使用的是 Java SDK,请先下载 Java SDK,然后运行如下获取临时密钥示例:
// 根据 github 提供的 maven 集成方法导入 java sts sdk,使用 3.1.1 及更高版本 import java.util.TreeMap; 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; public class demo { public static void main(String[] args) { TreeMap<String, Object> config = new TreeMap<String, Object>(); try { //这里的 SecretId 和 SecretKey 代表了用于申请临时密钥的永久身份(主账号、子账号等),子账号需要具有操作存储桶的权限。 String secretId = System.getenv("secretId");//用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 String secretKey = System.getenv("secretKey");//用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140 // 替换为您的云 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", "examplebucket-1250000000"); // 换成 bucket 所在地区 config.put("region", "ap-chongqing"); // 开始构建一条 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:ap-chongqing:uid/1250000000:examplebucket-1250000000/*", "qcs::ci:ap-chongqing:uid/1250000000:bucket/examplebucket-1250000000/*"}); // 把一条 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 !"); } } }
有关配置参数介绍如下:
字段
参考值
说明
必选
secretId
以获取到实际的 SecretId 为准
子账号密钥获取可参见 子账号访问密钥管理
secretKey
以获取到实际的 SecretKey 为准
子账号密钥获取可参见 子账号访问密钥管理
durationSeconds
1800
指定临时证书的有效期 1800秒。
bucket
examplebucket-1250000000
以实际的存储桶名称为准。
region
ap-guangzhou
以实际的存储桶所在地域为准。
allowPrefixes
"*"
允许访问所有对象,除非业务需要,否则请按照最小权限原则授予用户相应的访问权限范围。
allowActions
"cos:PutObject",
"cos:PostObject",
"cos:InitiateMultipartUpload",
"cos:ListMultipartUploads",
"cos:ListParts",
"cos:UploadPart",
"cos:CompleteMultipartUpload",
// 处理相关接口一般为数据万象产品 权限中以ci开头
"ci:CreateMediaJobs",
"ci:CreateFileProcessJobs"
PutObject:上传对象
PostObject:表单上传对象
InitiateMultipartUpload:初始化分块上传任务
ListMultipartUploads:查询分块上传任务
ListParts:查询已上传的分块
UploadPart:上传对象分块
CompleteMultipartUpload:完成分块上传任务
CreateMediaJobs:创建媒体处理任务
CreateFileProcessJobs:文件压缩
更多接口请参见 cos actionci action

应用案例:使用临时密钥访问 COS

COS API 使用临时密钥访问 COS 服务时,通过 x-cos-security-token 字段传递临时 sessionToken,通过临时 SecretId 和 SecretKey 计算签名。
以 COS Java SDK 为例,使用临时密钥访问 COS 示例如下:
说明:
运行如下示例前,请前往 Github 项目 获取 cos-java-sdk-v5 安装包。
// 根据 github 提供的 maven 集成方式导入 cos xml java sdk
import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.auth.BasicSessionCredentials; import com.qcloud.cos.auth.COSCredentials; import com.qcloud.cos.exception.CosClientException; import com.qcloud.cos.exception.CosServiceException; import com.qcloud.cos.model.ObjectMetadata; import com.qcloud.cos.model.PutObjectRequest; import com.qcloud.cos.model.PutObjectResult; import com.qcloud.cos.region.Region; import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {

// 用户基本信息
String tmpSecretId = "COS_SECRETID"; // 替换为 STS 接口返回给您的临时 SecretId
String tmpSecretKey = "COS_SECRETKEY"; // 替换为 STS 接口返回给您的临时 SecretKey
String sessionToken = "Token"; // 替换为 STS 接口返回给您的临时 Token

// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicSessionCredentials(tmpSecretId, tmpSecretKey, sessionToken);
// 2 设置 bucket 区域,详情请参见 COS 地域 https://cloud.tencent.com/document/product/436/6224
ClientConfig clientConfig = new ClientConfig(new Region("ap-guangzhou"));
// 3 生成 cos 客户端
COSClient cosclient = new COSClient(cred, clientConfig);
// bucket 名需包含 appid
String bucketName = "examplebucket-1250000000";

String key = "exampleobject";
// 上传 object, 建议 20M 以下的文件使用该接口
File localFile = new File("src/test/resources/text.txt");
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);

// 设置 x-cos-security-token header 字段
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setSecurityToken(sessionToken);
putObjectRequest.setMetadata(objectMetadata);

try {
PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
// 成功:putobjectResult 会返回文件的 etag
String etag = putObjectResult.getETag();
} catch (CosServiceException e) {
//失败,抛出 CosServiceException
e.printStackTrace();
} catch (CosClientException e) {
//失败,抛出 CosClientException
e.printStackTrace();
}

// 关闭客户端
cosclient.shutdown();

}
}
有关配置参数介绍如下:
字段
参考值
说明
COS_SECRETID
以获取到实际的 SecretId 为准
替换为 STS 接口返回给您的临时 SecretId
COS_SECRETKEY
以获取到实际的 SecretKey 为准
替换为 STS 接口返回给您的临时 SecretKey
Token
以获取到实际的 Token 为准
替换为 STS 接口返回给您的临时 Token
new Region
ap-guangzhou
以实际的存储桶所在地域为准
bucketName
examplebucket-1250000000
以实际的存储桶名称为准
key
exampleobject
如:/test/demo.txt,上传后的对象位置在/test,名为 demo.txt
new File
src/test/resources/text.txt
上传对象所在本地的位置为 src/test/resources/,文件名为test,格式是txt

常见问题

JSONObject 包冲突导致 NoSuchMethodError?

答:使用3.1.0及以后的版本。