本文介紹如何使用STS以及簽名URL臨時授權訪問OSS資源。
由于STS臨時賬號以及簽名URL均需設置有效時長,當您使用STS臨時賬號生成簽名URL執行相關操作(例如上傳、下載文件)時,以最小的有效時長為準。例如您的STS臨時賬號的有效時長設置為1200秒、簽名URL設置為3600秒時,當有效時長超過1200秒后,您無法使用此STS臨時賬號生成的簽名URL上傳文件。
注意事項
使用STS臨時授權
OSS可以通過阿里云STS(Security Token Service)進行臨時授權訪問。阿里云STS是為云計算用戶提供臨時訪問令牌的Web服務。通過STS,您可以為第三方應用或子用戶(即用戶身份由您自己管理的用戶)頒發一個自定義時效和權限的訪問憑證。關于STS的更多信息,請參見STS介紹。
STS的優勢如下:
您無需透露您的長期密鑰(AccessKey)給第三方應用,只需生成一個訪問令牌并將令牌交給第三方應用。您可以自定義這個令牌的訪問權限及有效期限。
您無需關心權限撤銷問題,訪問令牌過期后自動失效。
通過STS臨時授權訪問OSS的步驟如下:
獲取臨時訪問憑證
臨時訪問憑證包括臨時訪問密鑰(AccessKey ID和AccessKey Secret)和安全令牌(SecurityToken)。臨時訪問憑證有效時間單位為秒,最小值為900,最大值以當前角色設定的最大會話時間為準。更多信息,請參見設置RAM角色最大會話時間。
您可以通過以下兩種方式獲取臨時訪問憑證。
方式一
通過調用STS服務的AssumeRole接口獲取臨時訪問憑證。
方式二
通過各語言STS SDK獲取臨時訪問憑證。
使用STS憑證構造簽名請求。
#include "oss_api.h" #include "aos_http_io.h" /* yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/ const char *endpoint = "yourEndpoint"; /* 運行本代碼示例之前,請確保已使用STS服務獲取的臨時訪問密鑰設置環境變量YOUR_ACCESS_KEY_ID和YOUR_ACCESS_KEY_SECRET。*/ const char *access_key_id = getenv("OSS_ACCESS_KEY_ID"); const char *access_key_secret = getenv("OSS_ACCESS_KEY_SECRET"); /* 從STS服務獲取的安全令牌(SecurityToken)。*/ const char *sts_token = "yourStsToken"; /* 填寫Bucket名稱,例如examplebucket。*/ const char *bucket_name = "examplebucket"; /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/ const char *object_name = "exampledir/exampleobject.txt"; const char *object_content = "More than just cloud."; void init_options(oss_request_options_t *options) { options->config = oss_config_create(options->pool); /* 用char*類型的字符串初始化aos_string_t類型。*/ aos_str_set(&options->config->endpoint, endpoint); aos_str_set(&options->config->access_key_id, access_key_id); aos_str_set(&options->config->access_key_secret, access_key_secret); aos_str_set(&options->config->sts_token, sts_token); /* 是否使用CNAME訪問OSS服務。0表示不使用。*/ options->config->is_cname = 0; /* 設置網絡相關參數,例如超時時間等。*/ options->ctl = aos_http_controller_create(options->pool, 0); } int main(int argc, char *argv[]) { /* 在程序入口調用aos_http_io_initialize方法來初始化網絡、內存等全局資源。*/ if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { exit(1); } /* 用于內存管理的內存池(pool),等價于apr_pool_t。其實現代碼在apr庫中。*/ aos_pool_t *pool; /* 重新創建一個內存池,第二個參數是NULL,表示沒有繼承其他內存池。*/ aos_pool_create(&pool, NULL); /* 創建并初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/ oss_request_options_t *oss_client_options; /* 在內存池中分配內存給options。*/ oss_client_options = oss_request_options_create(pool); /* 初始化Client的選項oss_client_options。*/ init_options(oss_client_options); /* 初始化參數。*/ aos_string_t bucket; aos_string_t object; aos_list_t buffer; aos_buf_t *content = NULL; aos_table_t *headers = NULL; aos_table_t *resp_headers = NULL; aos_status_t *resp_status = NULL; /* 將類型為char*的數據賦值給bucket。*/ aos_str_set(&bucket, bucket_name); aos_str_set(&object, object_name); aos_list_init(&buffer); content = aos_buf_pack(oss_client_options->pool, object_content, strlen(object_content)); aos_list_add_tail(&content->node, &buffer); /* 上傳文件。*/ resp_status = oss_put_object_from_buffer(oss_client_options, &bucket, &object, &buffer, headers, &resp_headers); /* 判斷文件是否上傳成功。*/ if (aos_status_is_ok(resp_status)) { printf("put object from buffer succeeded\n"); } else { printf("put object from buffer failed\n"); } /* 釋放內存池,相當于釋放了請求過程中各資源分配的內存。*/ aos_pool_destroy(pool); /* 釋放之前分配的全局資源。*/ aos_http_io_deinitialize(); return 0; }
#include "oss_api.h" #include "aos_http_io.h" /* yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/ const char *endpoint = "yourEndpoint"; /* 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/ const char *access_key_id = getenv("OSS_ACCESS_KEY_ID"); const char *access_key_secret = getenv("OSS_ACCESS_KEY_SECRET"); /* 從STS服務獲取的安全令牌(SecurityToken)。*/ const char *sts_token = "yourStsToken"; /* 填寫Bucket名稱,例如examplebucket。*/ const char *bucket_name = "examplebucket"; /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/ const char *object_name = "exampledir/exampleobject.txt"; void init_options(oss_request_options_t *options) { options->config = oss_config_create(options->pool); /* 用char*類型的字符串初始化aos_string_t類型。*/ aos_str_set(&options->config->endpoint, endpoint); aos_str_set(&options->config->access_key_id, access_key_id); aos_str_set(&options->config->access_key_secret, access_key_secret); aos_str_set(&options->config->sts_token, sts_token); /* 是否使用了CNAME。0表示不使用。*/ options->config->is_cname = 0; /* 用于設置網絡相關參數,比如超時時間等。*/ options->ctl = aos_http_controller_create(options->pool, 0); } int main(int argc, char *argv[]) { /* 在程序入口調用aos_http_io_initialize方法來初始化網絡、內存等全局資源。*/ if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { exit(1); } /* 用于內存管理的內存池(pool),等價于apr_pool_t。其實現代碼在apr庫中。*/ aos_pool_t *pool; /* 重新創建一個內存池,第二個參數是NULL,表示沒有繼承其它內存池。*/ aos_pool_create(&pool, NULL); /* 創建并初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/ oss_request_options_t *oss_client_options; /* 在內存池中分配內存給options。*/ oss_client_options = oss_request_options_create(pool); /* 初始化Client的選項oss_client_options。*/ init_options(oss_client_options); /* 初始化參數。*/ aos_string_t bucket; aos_string_t object; aos_list_t buffer; aos_buf_t *content = NULL; aos_table_t *params = NULL; aos_table_t *headers = NULL; aos_table_t *resp_headers = NULL; aos_status_t *resp_status = NULL; char *buf = NULL; int64_t len = 0; int64_t size = 0; int64_t pos = 0; aos_str_set(&bucket, bucket_name); aos_str_set(&object, object_name); aos_list_init(&buffer); /* 下載文件到本地內存。*/ resp_status = oss_get_object_to_buffer(oss_client_options, &bucket, &object, headers, params, &buffer, &resp_headers); if (aos_status_is_ok(resp_status)) { printf("get object to buffer succeeded\n"); /* 將下載內容拷貝到buffer中。*/ len = aos_buf_list_len(&buffer); buf = aos_pcalloc(pool, len + 1); buf[len] = '\0'; aos_list_for_each_entry(aos_buf_t, content, &buffer, node) { size = aos_buf_size(content); memcpy(buf + pos, content->pos, size); pos += size; } } else { printf("get object to buffer failed\n"); } /* 釋放內存池,相當于釋放了請求過程中各資源分配的內存。*/ aos_pool_destroy(pool); /* 釋放之前分配的全局資源。*/ aos_http_io_deinitialize(); return 0; }
使用簽名URL臨時授權
注意事項
生成簽名URL過程中,SDK利用本地存儲的密鑰信息,根據特定算法計算出簽名(signature),然后將其附加到URL上,以確保URL的有效性和安全性。這一系列計算和構造URL的操作都是在客戶端完成,不涉及網絡請求到服務端。因此,生成簽名URL時不需要授予調用者特定權限。但是,為避免第三方用戶無法對簽名URL授權的資源執行相關操作,需要確保調用生成簽名URL接口的身份主體被授予對應的權限。
例如,通過簽名URL上傳文件時,需要授予oss:PutObject權限。通過簽名URL下載或預覽文件時,需要授予oss:GetObject權限。
您可以將生成的簽名URL提供給訪客進行臨時訪問。生成簽名URL時,您可以自定義URL的過期時間來限制訪客的訪問時長。
如果需要生成HTTPS協議的簽名URL,請將Endpoint中的通信協議設置為HTTPS。
通過以下示例生成的簽名URL中如果包含特殊符號
+
,可能出現無法正常訪問該簽名URL的現象。如需正常訪問該簽名URL,請將簽名URL中的+
替換為%2B
。
生成簽名URL并通過簽名URL上傳文件
生成用于上傳的簽名URL
#include "oss_api.h" #include "aos_http_io.h" /* yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/ const char *endpoint = "yourEndpoint"; /* 填寫Bucket名稱,例如examplebucket。*/ const char *bucket_name = "examplebucket"; /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/ const char *object_name = "exampledir/exampleobject.txt"; /* 填寫本地文件的完整路徑。*/ const char *local_filename = "yourLocalFilename"; void init_options(oss_request_options_t *options) { options->config = oss_config_create(options->pool); /* 用char*類型的字符串初始化aos_string_t類型。*/ aos_str_set(&options->config->endpoint, endpoint); /* 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/ aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID")); aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET")); /* 是否使用CNAME訪問OSS服務。0表示不使用。*/ options->config->is_cname = 0; /* 設置網絡相關參數,例如超時時間等。*/ options->ctl = aos_http_controller_create(options->pool, 0); } int main(int argc, char *argv[]) { /* 在程序入口調用aos_http_io_initialize方法來初始化網絡、內存等全局資源。*/ if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { exit(1); } /* 用于內存管理的內存池(pool),等價于apr_pool_t。其實現代碼在apr庫中。*/ aos_pool_t *pool; /* 重新創建一個內存池,第二個參數是NULL,表示沒有繼承其它內存池。*/ aos_pool_create(&pool, NULL); /* 創建并初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/ oss_request_options_t *oss_client_options; /* 在內存池中分配內存給options。*/ oss_client_options = oss_request_options_create(pool); /* 初始化Client的選項oss_client_options。*/ init_options(oss_client_options); /* 初始化參數。*/ aos_string_t bucket; aos_string_t object; aos_string_t file; aos_http_request_t *req; apr_time_t now; char *url_str; aos_string_t url; int64_t expire_time; int one_hour = 3600; aos_str_set(&bucket, bucket_name); aos_str_set(&object, object_name); aos_str_set(&file, local_filename); expire_time = now / 1000000 + one_hour; req = aos_http_request_create(pool); req->method = HTTP_PUT; now = apr_time_now(); /* 單位:微秒 */ expire_time = now / 1000000 + one_hour; /* 生成簽名URL。*/ url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req); aos_str_set(&url, url_str); printf("臨時上傳URL: %s\n", url_str); /* 釋放內存池,相當于釋放了請求過程中各資源分配的內存。*/ aos_pool_destroy(pool); /* 釋放之前分配的全局資源。*/ aos_http_io_deinitialize(); return 0; }
通過簽名URL上傳文件
您可以參考移動端Android SDK通過簽名URL上傳文件。更多信息,請參見通過簽名URL上傳文件。
生成簽名URL并通過簽名URL下載文件
生成用于下載的簽名URL
#include "oss_api.h" #include "aos_http_io.h" /* yourEndpoint填寫Bucket所在地域對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/ const char *endpoint = "yourEndpoint"; /* 填寫Bucket名稱,例如examplebucket。*/ const char *bucket_name = "examplebucket"; /* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/ const char *object_name = "exampledir/exampleobject.txt"; /* 填寫本地文件的完整路徑。*/ const char *local_filename = "yourLocalFilename"; void init_options(oss_request_options_t *options) { options->config = oss_config_create(options->pool); /* 用char*類型的字符串初始化aos_string_t類型。*/ aos_str_set(&options->config->endpoint, endpoint); /* 從環境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設置環境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/ aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID")); aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET")); /* 是否使用CNAME訪問OSS服務。0表示不使用。*/ options->config->is_cname = 0; /* 設置網絡相關參數,例如超時時間等。*/ options->ctl = aos_http_controller_create(options->pool, 0); } int main(int argc, char *argv[]) { /* 在程序入口調用aos_http_io_initialize方法來初始化網絡、內存等全局資源。*/ if (aos_http_io_initialize(NULL, 0) != AOSE_OK) { exit(1); } /* 用于內存管理的內存池(pool),等價于apr_pool_t。其實現代碼在apr庫中。*/ aos_pool_t *pool; /* 重新創建一個內存池,第二個參數是NULL,表示沒有繼承其它內存池。*/ aos_pool_create(&pool, NULL); /* 創建并初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/ oss_request_options_t *oss_client_options; /* 在內存池中分配內存給options。*/ oss_client_options = oss_request_options_create(pool); /* 初始化Client的選項oss_client_options。*/ init_options(oss_client_options); /* 初始化參數。*/ aos_string_t bucket; aos_string_t object; aos_string_t file; aos_http_request_t *req; apr_time_t now; char *url_str; aos_string_t url; int64_t expire_time; int one_hour = 3600; aos_str_set(&bucket, bucket_name); aos_str_set(&object, object_name); aos_str_set(&file, local_filename); expire_time = now / 1000000 + one_hour; req = aos_http_request_create(pool); req->method = HTTP_GET; now = apr_time_now(); /* 單位:微秒 */ expire_time = now / 1000000 + one_hour; /* 生成簽名URL。*/ url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req); aos_str_set(&url, url_str); printf("臨時下載URL: %s\n", url_str); /* 釋放內存池,相當于釋放了請求過程中各資源分配的內存。*/ aos_pool_destroy(pool); /* 釋放之前分配的全局資源。*/ aos_http_io_deinitialize(); return 0; }
通過簽名URL下載文件
您可以參考移動端Android SDK通過簽名URL下載文件。更多信息,請參見通過簽名URL下載文件。