使用STS臨時(shí)訪問憑證訪問OSS
本文中含有需要您注意的重要提示信息,忽略該信息可能對(duì)您的業(yè)務(wù)造成影響,請(qǐng)務(wù)必仔細(xì)閱讀。
您可以通過STS服務(wù)為其他用戶頒發(fā)一個(gè)臨時(shí)訪問憑證,用戶通過臨時(shí)訪問憑證可以在限定的有效期內(nèi),以符合策略規(guī)定的權(quán)限訪問OSS資源。超過有效期后,該憑證自動(dòng)失效,無法繼續(xù)通過該憑證訪問OSS資源,確保了訪問控制的靈活性和時(shí)效性。
操作視頻
觀看以下視頻快速了解如何快速使用STS臨時(shí)訪問憑證訪問OSS。
前提條件
已創(chuàng)建Bucket。具體操作,請(qǐng)參見創(chuàng)建存儲(chǔ)空間。
步驟一:創(chuàng)建RAM用戶
登錄RAM控制臺(tái)。
在左側(cè)導(dǎo)航欄,選擇身份管理>用戶。
單擊創(chuàng)建用戶。
輸入登錄名稱和顯示名稱。
在訪問方式區(qū)域下,選擇OpenAPI調(diào)用訪問,然后單擊確定。
根據(jù)界面提示,完成安全驗(yàn)證。
復(fù)制訪問密鑰(AccessKey ID和AccessKey Secret)。
重要RAM用戶的AccessKey Secret只在創(chuàng)建時(shí)顯示,后續(xù)不支持查看,請(qǐng)妥善保管。
步驟二:為RAM用戶授予請(qǐng)求AssumeRole的權(quán)限
創(chuàng)建RAM用戶后,您需要授予RAM用戶通過扮演角色來調(diào)用STS服務(wù)的權(quán)限。
單擊已創(chuàng)建RAM用戶右側(cè)對(duì)應(yīng)的添加權(quán)限。
在新增授權(quán)頁面,選擇AliyunSTSAssumeRoleAccess系統(tǒng)策略。
說明授予RAM用戶調(diào)用STS服務(wù)AssumeRole接口的固定權(quán)限是AliyunSTSAssumeRoleAccess,與后續(xù)獲取臨時(shí)訪問憑證以及通過臨時(shí)訪問憑證發(fā)起OSS請(qǐng)求所需權(quán)限無關(guān)。
單擊確認(rèn)新增授權(quán)。
步驟三:創(chuàng)建RAM角色
您需要?jiǎng)?chuàng)建RAM角色,用于定義RAM角色被扮演時(shí),可以獲得OSS服務(wù)的哪些訪問權(quán)限。
在左側(cè)導(dǎo)航欄,選擇身份管理>角色。
單擊創(chuàng)建角色,選擇可信實(shí)體類型為阿里云賬號(hào),單擊下一步。
在創(chuàng)建角色對(duì)話框,角色名稱填寫為RamOssTest,選擇信任的云賬號(hào)為當(dāng)前云賬號(hào)。
單擊完成。角色創(chuàng)建完成后,單擊關(guān)閉。
在角色頁面,搜索框輸入角色名稱RamOssTest,然后單擊RamOssTest。
單擊ARN右側(cè)的復(fù)制,保存角色的ARN。
步驟四:為RAM角色授予上傳文件的權(quán)限
為RAM角色附加一個(gè)或多個(gè)權(quán)限策略,明確RAM角色在被扮演時(shí)所能擁有的OSS資源訪問權(quán)限。例如,如果希望RAM用戶在扮演該角色后只能向OSS指定Bucket上傳文件,則需要為角色添加寫入權(quán)限的策略。
創(chuàng)建上傳文件的自定義權(quán)限策略。
在左側(cè)導(dǎo)航欄,選擇權(quán)限管理>權(quán)限策略。
在權(quán)限策略頁面,單擊創(chuàng)建權(quán)限策略。
在創(chuàng)建權(quán)限策略頁面,單擊腳本編輯,然后在策略文檔輸入框中賦予角色上傳文件到examplebucket的權(quán)限。具體配置示例如下。
警告以下示例僅供參考。您需要根據(jù)實(shí)際需求配置更細(xì)粒度的授權(quán)策略,防止出現(xiàn)權(quán)限過大的風(fēng)險(xiǎn)。關(guān)于更細(xì)粒度的授權(quán)策略配置詳情,請(qǐng)參見通過RAM或STS服務(wù)向其他用戶授權(quán)。
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "oss:PutObject" ], "Resource": [ "acs:oss:*:*:examplebucket/*" ] } ] }
說明RAM角色所擁有的OSS權(quán)限取決于Action的配置,例如授予oss:PutObject權(quán)限,則RAM用戶在扮演RAM角色時(shí)可以對(duì)指定Bucket執(zhí)行簡(jiǎn)單上傳、表單上傳、追加上傳、分片上傳、斷點(diǎn)續(xù)傳上傳等操作。更多信息,請(qǐng)參見OSS Action說明。
策略配置完成后,單擊繼續(xù)編輯基本信息。
在基本信息區(qū)域,填寫策略名稱為RamTestPolicy,然后單擊確定。
為RAM角色RamOssTest授予自定義權(quán)限策略。
在左側(cè)導(dǎo)航欄,選擇
。在角色頁面,找到目標(biāo)RAM角色RamOssTest。
單擊RAM角色RamOssTest右側(cè)的新增授權(quán)。
在添加權(quán)限頁面下的自定義策略頁簽,選擇已創(chuàng)建的自定義權(quán)限策略RamTestPolicy。
單擊確定。
步驟五:使用RAM用戶扮演RAM角色獲取臨時(shí)訪問憑證
為角色授予上傳文件的權(quán)限后,RAM用戶需要通過扮演角色來獲取臨時(shí)訪問憑證。臨時(shí)訪問憑證包括安全令牌(SecurityToken)、臨時(shí)訪問密鑰(AccessKeyId和AccessKeySecret)以及過期時(shí)間(Expiration)。
使用STS SDK
您可以使用STS SDK來獲取臨時(shí)訪問憑證。
本文以Java為例,說明如何使用STS SDK獲取具有簡(jiǎn)單上傳(oss:PutObject
)權(quán)限的臨時(shí)訪問憑證。關(guān)于更多語言的STS SDK示例,請(qǐng)參見STS SDK概覽。關(guān)于STS服務(wù)接入點(diǎn)的更多信息,請(qǐng)參見服務(wù)接入點(diǎn)。
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.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
public class StsServiceSample {
public static void main(String[] args) {
// STS服務(wù)接入點(diǎn),例如sts.cn-hangzhou.aliyuncs.com。您可以通過公網(wǎng)或者VPC接入STS服務(wù)。
String endpoint = "sts.cn-hangzhou.aliyuncs.com";
// 從環(huán)境變量中獲取步驟1生成的RAM用戶的訪問密鑰(AccessKey ID和AccessKey Secret)。
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// 從環(huán)境變量中獲取步驟3生成的RAM角色的RamRoleArn。
String roleArn = System.getenv("OSS_STS_ROLE_ARN");
// 自定義角色會(huì)話名稱,用來區(qū)分不同的令牌,例如可填寫為SessionTest。
String roleSessionName = "yourRoleSessionName";
// 臨時(shí)訪問憑證將獲得角色擁有的所有權(quán)限。
String policy = null;
// 臨時(shí)訪問憑證的有效時(shí)間,單位為秒。最小值為900,最大值以當(dāng)前角色設(shè)定的最大會(huì)話時(shí)間為準(zhǔn)。當(dāng)前角色最大會(huì)話時(shí)間取值范圍為3600秒~43200秒,默認(rèn)值為3600秒。
// 在上傳大文件或者其他較耗時(shí)的使用場(chǎng)景中,建議合理設(shè)置臨時(shí)訪問憑證的有效時(shí)間,確保在完成目標(biāo)任務(wù)前無需反復(fù)調(diào)用STS服務(wù)以獲取臨時(shí)訪問憑證。
Long durationSeconds = 3600L;
try {
// 發(fā)起STS請(qǐng)求所在的地域。建議保留默認(rèn)值,默認(rèn)值為空字符串("")。
String regionId = "";
// 添加endpoint。適用于Java SDK 3.12.0及以上版本。
DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
// 添加endpoint。適用于Java SDK 3.12.0以下版本。
// DefaultProfile.addEndpoint("",regionId, "Sts", endpoint);
// 構(gòu)造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
// 構(gòu)造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());
} catch (ClientException e) {
System.out.println("Failed:");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
System.out.println("RequestId: " + e.getRequestId());
}
}
}
如果您希望臨時(shí)訪問憑證在獲得角色擁有的權(quán)限后,進(jìn)一步限制權(quán)限范圍,例如角色被授予了上傳文件到examplebucket的權(quán)限,您需要限制臨時(shí)訪問憑證只能向該Bucket下的某個(gè)目錄上傳文件,您可以通過參考以下示例設(shè)置policy。
// 以下Policy用于限制僅允許使用臨時(shí)訪問憑證向examplebucket下的src目錄上傳文件。
// 臨時(shí)訪問憑證最后獲得的權(quán)限是步驟4設(shè)置的角色權(quán)限和該P(yáng)olicy設(shè)置權(quán)限的交集,即僅允許將文件上傳至examplebucket下的src目錄。
String policy = "{\n" +
" \"Version\": \"1\", \n" +
" \"Statement\": [\n" +
" {\n" +
" \"Action\": [\n" +
" \"oss:PutObject\"\n" +
" ], \n" +
" \"Resource\": [\n" +
" \"acs:oss:*:*:examplebucket/src/*\" \n" +
" ], \n" +
" \"Effect\": \"Allow\"\n" +
" }\n" +
" ]\n" +
"}";
使用REST API
您可以通過調(diào)用STS服務(wù)的AssumeRole - 獲取扮演角色的臨時(shí)身份憑證接口來獲取臨時(shí)訪問憑證。
步驟六:使用臨時(shí)訪問憑證上傳文件至OSS
在臨時(shí)訪問憑證有效期(Expiration)到期之前,使用臨時(shí)訪問憑證上傳文件至OSS。
臨時(shí)訪問憑證過期時(shí)間格式是UTC,與北京時(shí)間有8小時(shí)的時(shí)差。例如,臨時(shí)訪問憑證過期時(shí)間是2024-04-18T11:33:40Z,說明臨時(shí)訪問憑證將在北京時(shí)間2024年4月18日19時(shí)33分40秒之前過期。
臨時(shí)訪問憑證沒有明確的使用次數(shù)限制。在有效期到期之前,您可以重復(fù)調(diào)用上傳接口上傳多個(gè)文件,也可以將要上傳的多個(gè)文件壓縮后上傳,最終達(dá)到批量上傳的目的。
本文以Java SDK 3.12.0版本為例,將本地D:\\localpath
路徑下的exampletest.txt文件上傳至examplebucket的示例代碼如下。關(guān)于其他SDK使用臨時(shí)訪問憑證上傳文件到OSS的代碼示例,請(qǐng)參見簡(jiǎn)介。
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyuncs.exceptions.ClientException;
import java.io.File;
public class Demo {
public static void main(String[] args) throws ClientException {
// OSS訪問域名。以華東1(杭州)地域?yàn)槔顚憺閔ttps://oss-cn-hangzhou.aliyuncs.com。其它Region請(qǐng)按實(shí)際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環(huán)境變量中獲取步驟5生成的臨時(shí)訪問密鑰AccessKey ID和AccessKey Secret,非阿里云賬號(hào)AccessKey ID和AccessKey Secret。
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// 從環(huán)境變量中獲取步驟5生成的安全令牌SecurityToken。
String securityToken = System.getenv("OSS_SESSION_TOKEN");
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
// 將本地文件exampletest.txt上傳至examplebucket。
PutObjectRequest putObjectRequest = new PutObjectRequest("examplebucket", "exampletest.txt", new File("D:\\localpath\\exampletest.txt"));
// ObjectMetadata metadata = new ObjectMetadata();
// 上傳文件時(shí)設(shè)置存儲(chǔ)類型。
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// 上傳文件時(shí)設(shè)置讀寫權(quán)限ACL。
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
try {
// 上傳文件。
ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
常見問題
報(bào)錯(cuò)You are not authorized to do this action. You should be authorized by RAM.如何處理?
步驟五中使用RAM用戶扮演RAM角色獲取臨時(shí)訪問憑證時(shí),必須使用RAM用戶的訪問密鑰(AccessKey ID和AccessKey Secret),不能使用阿里云賬號(hào)的訪問密鑰發(fā)起請(qǐng)求。
報(bào)錯(cuò)The Min/Max value of DurationSeconds is 15min/1hr.如何處理?
報(bào)錯(cuò)原因是設(shè)置的臨時(shí)訪問憑證有效期超出允許的時(shí)間范圍。請(qǐng)遵循以下原則設(shè)置有效期:
如果沒有自定義角色最大會(huì)話時(shí)間,則當(dāng)前角色會(huì)話時(shí)間默認(rèn)值為3600秒。此時(shí),通過durationSeconds設(shè)置的臨時(shí)訪問憑證有效時(shí)間允許的最小值為900秒,最大值為3600秒。
如果自定義了角色最大會(huì)話時(shí)間,則通過durationSeconds設(shè)置的臨時(shí)訪問憑證有效時(shí)間的最小值為900秒,最大值以角色最大會(huì)話時(shí)間為準(zhǔn)。角色會(huì)話時(shí)間允許設(shè)置的取值范圍為3600秒~43200秒。
您可以通過RAM控制臺(tái)查看角色最大會(huì)話時(shí)間。具體步驟,請(qǐng)參見查看RAM角色。
報(bào)錯(cuò)The security token you provided is invalid.如何處理?
請(qǐng)確保完整填寫步驟五獲取到的SecurityToken。
報(bào)錯(cuò)The OSS Access Key Id you provided does not exist in our records.如何處理?
臨時(shí)訪問憑證已過期,過期后自動(dòng)失效。請(qǐng)使用臨時(shí)訪問密鑰(AccessKeyId和AccessKeySecret)向App服務(wù)器申請(qǐng)新的臨時(shí)訪問憑證。具體操作,請(qǐng)參見步驟五。
報(bào)錯(cuò)AccessDenied : Anonymous access is forbidden for this operation.如何處理?
報(bào)錯(cuò)NoSuchBucket如何處理?
出現(xiàn)該報(bào)錯(cuò)的原因是指定的Bucket不存在。請(qǐng)檢查并配置正確的Bucket名稱。
通過臨時(shí)訪問憑證操作OSS資源時(shí)報(bào)錯(cuò)You have no right to access this object because of bucket acl.如何處理?
出現(xiàn)該報(bào)錯(cuò)通常是Policy設(shè)置錯(cuò)誤。關(guān)于Policy中涉及各元素的填寫要求,請(qǐng)參見RAM Policy。如果您需要獲取具有分片上傳、追加上傳等權(quán)限的臨時(shí)訪問憑證,您需要通過Policy中的Action元素授予對(duì)應(yīng)權(quán)限。關(guān)于OSS Action的更多信息,請(qǐng)參見OSS Action分類。
通過臨時(shí)訪問憑證操作OSS資源時(shí)報(bào)錯(cuò)Access denied by authorizer's policy.如何處理?
出現(xiàn)該報(bào)錯(cuò)通常是無權(quán)限執(zhí)行相關(guān)操作。申請(qǐng)臨時(shí)訪問憑證之前,需要?jiǎng)?chuàng)建用于獲取臨時(shí)訪問憑證的RAM角色并完成角色授權(quán)(本文檔步驟四)。向STS服務(wù)器發(fā)起扮演該角色的請(qǐng)求,以獲取臨時(shí)訪問憑證時(shí)可以通過policy參數(shù)進(jìn)一步限制臨時(shí)訪問憑證的權(quán)限(本文檔步驟五)。
如果設(shè)置policy,則臨時(shí)訪問憑證最終的權(quán)限是RAM角色權(quán)限策略與policy權(quán)限策略的交集。
示例1
如下圖所示,A代表RAM角色的權(quán)限,B代表通過policy參數(shù)設(shè)置的權(quán)限,C代表臨時(shí)訪問憑證最終的權(quán)限。
示例2
如下圖所示,A代表RAM角色權(quán)限,B代表通過policy參數(shù)設(shè)置的權(quán)限,且policy參數(shù)設(shè)置的權(quán)限是RAM角色權(quán)限的子集。因此,B代表臨時(shí)訪問憑證的最終權(quán)限。
如果不設(shè)置policy,則臨時(shí)訪問憑證具有與RAM角色相同的權(quán)限策略。
報(bào)錯(cuò)The bucket you are attempting to access must be addressed using the specified endpoint.如何處理?
出現(xiàn)該報(bào)錯(cuò)的原因是步驟六中的Endpoint參數(shù)填寫錯(cuò)誤。您需要根據(jù)Bucket所在Region填寫對(duì)應(yīng)的Endpoint。關(guān)于Region與Endpoint對(duì)應(yīng)關(guān)系的說明,請(qǐng)參見訪問域名和數(shù)據(jù)中心。
是否支持同時(shí)獲取多個(gè)臨時(shí)訪問憑證?
支持。發(fā)起一次請(qǐng)求僅返回一個(gè)臨時(shí)訪問憑證。如果您希望獲取多個(gè)臨時(shí)訪問憑證,您需要發(fā)起多次請(qǐng)求。在有效期內(nèi),您可以同時(shí)使用獲取到的多個(gè)臨時(shí)訪問憑證。
報(bào)錯(cuò)時(shí)間格式不正確如何處理?
如果調(diào)用時(shí)報(bào)錯(cuò)時(shí)間格式不正確,可能是由于Timestamp參數(shù)中間多余空格,請(qǐng)排查修改。
請(qǐng)求的時(shí)間戳日期格式按照ISO8601標(biāo)準(zhǔn)表示,并需要使用UTC時(shí)間。格式為:YYYY-MM-DDThh:mm:ssZ。例如,2014-05-26T12:00:00Z(為北京時(shí)間2014年5月26日20點(diǎn)0分0秒)。
返回0003-0000301怎么處理?
返回0003-0000301原因是臨時(shí)訪問憑證不具有執(zhí)行OSS相關(guān)操作的權(quán)限,解決方案請(qǐng)參見0003-00000301。
相關(guān)文檔
如果您希望從服務(wù)端獲取STS臨時(shí)訪問憑證后,通過客戶端上傳文件,且上傳文件時(shí)需要限制上傳的文件大小、上傳的文件類型、上傳到Bucket的具體路徑等,請(qǐng)參見客戶端直傳。
通過STS臨時(shí)訪問憑證授權(quán)上傳文件到OSS后,您可以通過簽名URL的方式將文件分享給第三方用戶進(jìn)行預(yù)覽或者下載。具體操作,請(qǐng)參見使用文件URL分享文件。