This topic describes how to use temporary access credentials provided by Security Token Service (STS) or a signed URL to temporarily access Object Storage Service (OSS) resources.

Notice A validity period must be specified for temporary access credentials and a signed URL. When you use temporary access credentials to generate a signed URL that is used to perform operations such as object upload and download, the minimum validity period takes precedence. For example, you can set the validity period of your temporary access credentials to 1,200 seconds and the validity period of the signed URL generated by using the credentials to 3,600 seconds. In this case, the signed URL cannot be used to upload objects after the STS temporary access credentials expire, even if the signed URL is within its validity period.

Use STS for temporary access authorization

You can use Alibaba Cloud STS to authorize temporary access to OSS. STS is a web service that provides temporary access tokens for users. You can use STS to grant a set of temporary access credentials that have a custom validity period and custom permissions to a third-party application or a RAM user managed by you. For more information about STS, see What is STS?

STS provides the following benefits:

  • You need only to generate an access token and send the access token to a third-party application. You do not need to expose your AccessKey pair to the third-party application. You can specify the access permissions and validity period of this token.
  • The token automatically expires after the validity period. Therefore, you do not need to manually revoke the access permissions of a token.
Notice For more information about how to configure STS, see Use a temporary credential provided by STS to access OSS. You can call the AssumeRole operation or use STS SDKs for various programming languages to obtain temporary access credentials from STS. For more information, see STS SDK overview. The temporary access credentials consist of a temporary AccessKey pair and a security token. The AccessKey pair consists of an AccessKey ID and an AccessKey secret. The minimum validity period of temporary access credentials is 900 seconds. The maximum validity period of temporary access credentials is the maximum session duration specified for the current role. For more information, see Specify the maximum session duration for a RAM role.

The following code provides an example on how to generate a signed request by using credentials that are obtained from STS:

#include "oss_api.h"
#include "aos_http_io.h"
/* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
const char *endpoint = "yourEndpoint";
/* Specify the temporary AccessKey pair obtained from STS. The AccessKey pair consists of an AccessKey ID and an AccessKey secret. */
const char *access_key_id = "yourAccessKeyId";
const char *access_key_secret = "yourAccessKeySecret";
/* Specify the security token obtained from STS. 
const char *sts_token = "yourStsToken";
/* Specify the name of the bucket. Example: examplebucket. */
const char *bucket_name = "examplebucket";
/* Specify the full path of the object. The full path cannot contain the bucket name. Example: 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);
    /* Use a char* string to initialize the aos_string_t data type. */
    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);
    /* Specify whether to use CNAME to access OSS. The value 0 indicates that CNAME is not used. */
    options->config->is_cname = 0;
    /* Configure network parameters such as the timeout period. */
    options->ctl = aos_http_controller_create(options->pool, 0);
}

int main(int argc, char *argv[])
{
    /* Call the aos_http_io_initialize method in main() to initialize global resources such as networks and memory. */
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }

    /* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
    aos_pool_t *pool;
    /* Create a memory pool. The value of the second parameter is NULL. This value specifies that the pool does not inherit other memory pools. */
    aos_pool_create(&pool, NULL);
    /* Create and initialize options. This parameter includes global configuration information such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
    oss_request_options_t *oss_client_options;
    /* Allocate the memory resources in the memory pool to the options. */
    oss_client_options = oss_request_options_create(pool);
    /* Initialize oss_client_options. */
    init_options(oss_client_options);

    /* Initialize the parameters. */
    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; 
    /* Assign the char* data to the 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);

    /* Upload the object. */
    resp_status = oss_put_object_from_buffer(oss_client_options, &bucket, &object, &buffer, headers, &resp_headers);
    /* Determine whether the object is uploaded. */
    if (aos_status_is_ok(resp_status)) {
        printf("put object from buffer succeeded\n");
    } else {
        printf("put object from buffer failed\n");      
    }    

    /* Release the memory pool. This operation releases the memory resources allocated for the request. */
    aos_pool_destroy(pool);

    /* Release the allocated global resources. */
    aos_http_io_deinitialize();

    return 0;
}
            

Use a signed URL for temporary access authorization

You can generate a signed URL and provide the URL to a visitor for temporary access. When you generate a signed URL, you can specify the validity period of the URL to limit the period of time during which the visitor can access OSS.

Notice If you use the following code to generate a signed URL that contains the plus sign (+), you may fail to access OSS by using the URL. In this case, you must replace the plus sign (+) in the URL with %2B.

This section provides examples on how to generate a signed URL to authorize temporary access to OSS.

  • Use a signed URL to upload an object

    The following code provides an example on how to use a signed URL to upload an object:

    #include "oss_api.h"
    #include "aos_http_io.h"
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    const char *endpoint = "yourEndpoint";
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    const char *access_key_id = "yourAccessKeyId";
    const char *access_key_secret = "yourAccessKeySecret";
    /* Specify the name of the bucket. Example: examplebucket. */
    const char *bucket_name = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    const char *object_name = "exampledir/exampleobject.txt";
    /* Specify the full path of the local file. */
    const char *local_filename = "yourLocalFilename";
    void init_options(oss_request_options_t *options)
    {
        options->config = oss_config_create(options->pool);
        /* Use a char* string to initialize the aos_string_t data type. */
        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);
        /* Specify whether to use CNAME to access OSS. The value 0 indicates that CNAME is not used. */
        options->config->is_cname = 0;
        /* Configure network parameters such as the timeout period. */
        options->ctl = aos_http_controller_create(options->pool, 0);
    }
    int main(int argc, char *argv[])
    {
        /* Call the aos_http_io_initialize method in main() to initialize global resources such as networks and memory. */
        if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
            exit(1);
        }
        /* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
        aos_pool_t *pool;
        /* Create a memory pool. The value of the second parameter is NULL. This value specifies that the pool does not inherit other memory pools. */
        aos_pool_create(&pool, NULL);
        /* Create and initialize options. This parameter includes global configuration information such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
        oss_request_options_t *oss_client_options;
        /* Allocate the memory resources in the memory pool to the options. */
        oss_client_options = oss_request_options_create(pool);
        /* Initialize oss_client_options. */
        init_options(oss_client_options);
        /* Initialize the parameters. */
        aos_string_t bucket;
        aos_string_t object;
        aos_string_t file;
        aos_table_t *headers = NULL;
        aos_table_t *resp_headers = NULL; 
        aos_status_t *resp_status = NULL; 
        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;
        headers = aos_table_make(pool, 0);
        req = aos_http_request_create(pool);
        req->method = HTTP_PUT;
        now = apr_time_now(); /* Unit: microseconds. */
        expire_time = now / 1000000 + one_hour;
        /* Generate a signed URL. */
        url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
        aos_str_set(&url, url_str);
        printf ("The signed URL used to upload the object: %s\n", url_str);
        /* Use the signed URL to upload the object. */
        resp_status = oss_put_object_from_file_by_url(oss_client_options, &url, &file, headers, &resp_headers);
        if (aos_status_is_ok(resp_status)) {
            printf("put objects by signed url succeeded\n");
        } else {
            printf("put objects by signed url failed\n");
        }
        /* Release the memory pool. This operation releases the memory resources allocated for the request. */
        aos_pool_destroy(pool);
        /* Release the allocated global resources. */
        aos_http_io_deinitialize();
        return 0;
    }
  • Use a signed URL to download an object

    The following code provides an example on how to use a signed URL to download an object:

    #include "oss_api.h"
    #include "aos_http_io.h"
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    const char *endpoint = "yourEndpoint";
    /* The AccessKey pair of an Alibaba Cloud account has permissions on all API operations. Using these credentials to perform operations in OSS is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. To create a RAM user, log on to the RAM console. */
    const char *access_key_id = "yourAccessKeyId";
    const char *access_key_secret = "yourAccessKeySecret";
    /* Specify the name of the bucket. Example: examplebucket. */
    const char *bucket_name = "examplebucket";
    /* Specify the full path of the object. The full path cannot contain the bucket name. Example: exampledir/exampleobject.txt. */
    const char *object_name = "exampledir/exampleobject.txt";
    /* Specify the full path of the local file. */
    const char *local_filename = "yourLocalFilename";
    void init_options(oss_request_options_t *options)
    {
        options->config = oss_config_create(options->pool);
        /* Use a char* string to initialize the aos_string_t data type. */
        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);
        /* Specify whether to use CNAME to access OSS. The value 0 indicates that CNAME is not used. */
        options->config->is_cname = 0;
        /* Configure network parameters such as the timeout period. */
        options->ctl = aos_http_controller_create(options->pool, 0);
    }
    int main(int argc, char *argv[])
    {
        /* Call the aos_http_io_initialize method in main() to initialize global resources such as networks and memory. */
        if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
            exit(1);
        }
        /* Create a memory pool to manage memory. aos_pool_t is equivalent to apr_pool_t. The code that is used to create a memory pool is included in the APR library. */
        aos_pool_t *pool;
        /* Create a memory pool. The value of the second parameter is NULL. This value specifies that the pool does not inherit other memory pools. */
        aos_pool_create(&pool, NULL);
        /* Create and initialize options. This parameter includes global configuration information such as endpoint, access_key_id, access_key_secret, is_cname, and curl. */
        oss_request_options_t *oss_client_options;
        /* Allocate the memory resources in the memory pool to the options. */
        oss_client_options = oss_request_options_create(pool);
        /* Initialize oss_client_options. */
        init_options(oss_client_options);
        /* Initialize the parameters. */
        aos_string_t bucket;
        aos_string_t object;
        aos_string_t file;
        aos_table_t *headers = NULL;
        aos_table_t *params = NULL;
        aos_table_t *resp_headers = NULL; 
        aos_status_t *resp_status = NULL; 
        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;
        headers = aos_table_make(pool, 0);
        params = aos_table_make(pool, 0);
        req = aos_http_request_create(pool);
        req->method = HTTP_GET;
        now = apr_time_now(); /* Unit: microseconds. */
        expire_time = now / 1000000 + one_hour;
        /* Generate a signed URL. */
        url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
        aos_str_set(&url, url_str);
        /* Use the signed URL to download the object. */
        resp_status = oss_get_object_to_file_by_url(oss_client_options, &url, headers, params, &file, &resp_headers);
        if (aos_status_is_ok(resp_status)) {
            printf("get object succeeded\n");
        } else {
            printf("get object failed\n");
        }
        /* Release the memory pool. This operation releases the memory resources allocated for the request. */
        aos_pool_destroy(pool);
        /* Release the allocated global resources. */
        aos_http_io_deinitialize();
        return 0;
    }