All Products
Search
Document Center

Object Storage Service:Authorize access by using OSS SDK for C

Last Updated:Jun 14, 2024

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

Important

A validity period must be specified for STS 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 uploads and downloads, 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.

Usage notes

  • In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS from other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about OSS regions and endpoints, see Regions and endpoints.

  • In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Initialization.

Use STS to authorize temporary access

You can use 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 temporary access credentials that have a custom validity period and custom permissions to a third-party application or a RAM user that is managed by you. For more information about STS, see What is STS?.

STS has the following benefits:

  • You need to only generate a temporary access token and send the access token to a third-party application. You do not need to provide 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 ends. Therefore, you do not need to manually revoke the access permissions of a token.

To access OSS by using temporary access credentials provided by STS, perform the following operations:

  1. Obtain temporary access credentials.

    Temporary access credentials include a security token and a temporary AccessKey pair that 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.

    You can use one of the following methods to obtain temporary access credentials:

    • Method 1

      Call the AssumeRole operation to obtain temporary access credentials.

    • Method 2

      Use STS SDKs to obtain temporary access credentials. For more information, see STS SDK overview.

  2. Use temporary credentials obtained from STS to create a signed request.

    • 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";
      /* Before you run the sample code, make sure that the YOUR_ACCESS_KEY_ID and YOUR_ACCESS_KEY_SECRET environment variables are configured based on temporary access credentials obtained from STS. */  
      const char *access_key_id = getenv("OSS_ACCESS_KEY_ID");
      const char *access_key_secret = getenv("OSS_ACCESS_KEY_SECRET");
      /* 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. Do not include the bucket name in the full path. 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 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);
          /* Specify whether to use CNAME. 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 network and memory resources. */
          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;
          /* Recreate a memory pool. The second parameter is NULL, which indicates that the pool does not inherit any other memory pool. */
          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 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 memory resources allocated for the request. */
          aos_pool_destroy(pool);
      
          /* Release the allocated global resources. */
          aos_http_io_deinitialize();
      
          return 0;
      }            
    • 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";
      /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */  
      const char *access_key_id = getenv("OSS_ACCESS_KEY_ID");
      const char *access_key_secret = getenv("OSS_ACCESS_KEY_SECRET");
      /* 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. Do not include the bucket name in the full path. Example: 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);
          /* Use a char* string to initialize 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);
          /* Specify whether to use CNAME. The value 0 indicates that CNAME is not used. */
          options->config->is_cname = 0;
          /* Specify 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 network and memory resources. */
          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 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 *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);
          /* Download the object to the local memory. */
          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");
              /* Copy the downloaded content to the 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");  
          }
          /* Release the memory pool. This operation releases 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 authorize temporary access

Usage notes

  • When you use an OSS SDK to generate a signed URL, the OSS SDK uses a specific algorithm based on the key information stored in the local computer to calculate a signature and adds the signature to a URL to ensure the validity and security of the URL. The operations performed to calculate and construct the URL are completed on the client. You do not need to send requests to the server over the network. This way, you do not need to grant specific permissions to the caller when you generate the signed URL. However, to allow third-party users to perform relevant operations on the resources authorized by the signed URL, you must make sure that the principal that calls the API operations to generate the signed URL has the corresponding permissions.

    For example, if a principal wants to upload an object by using a signed URL, you must grant the oss:PutObject permission to the principal. If a principal wants to download or preview an object by using a signed URL, you must grant the oss:GetObject permission to the principal.

  • 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 specific data.

  • To generate a signed URL that is used to access resources over HTTPS, set the protocol in the endpoint to HTTPS.

  • The signed URL generated by using the following sample code may contain a plus sign (+). In this case, replace the plus sign (+) in the URL with %2B. Otherwise, the signed URL may not be used to access the object as expected.

Generate a signed URL and use the signed URL to upload a file

  1. Generate a signed URL.

    #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 name of the bucket. Example: examplebucket. */
    const char *bucket_name = "examplebucket";
    /* Specify the full path of the object. Do not include the bucket name in the full path. 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 aos_string_t. */
        aos_str_set(&options->config->endpoint, endpoint);
        /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
        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"));
        /* Specify whether to use CNAME. 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 network and memory resources. */
        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 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_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(); 
        /* Specify the validity period. 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);    
        /* Release the memory pool. This operation releases memory resources allocated for the request. */
        aos_pool_destroy(pool);
        /* Release the allocated global resources. */
        aos_http_io_deinitialize();
        return 0;
    }
  2. Upload a local file by using the signed URL

    You can refer to OSS SDK for Android mobile devices. For more information, see Upload an object by using the signed URL.

Generate a signed URL and use the signed URL to download the object

  1. Generate a signed URL.

    #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 name of the bucket. Example: examplebucket. */
    const char *bucket_name = "examplebucket";
    /* Specify the full path of the object. Do not include the bucket name in the full path. 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 aos_string_t. */
        aos_str_set(&options->config->endpoint, endpoint);
        /* Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. */
        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"));
        /* Specify whether to use CNAME. 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 network and memory resources. */
        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 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_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();  
        /* Specify the validity period. 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("Temporary download URL: %s\n", url_str);     
        /* Release the memory pool. This operation releases memory resources allocated for the request. */
        aos_pool_destroy(pool);
        /* Release the allocated global resources. */
        aos_http_io_deinitialize();
        return 0;
    }
  2. Download an object by using the signed URL

    You can refer to OSS SDK for Android mobile devices. For more information, see Download an object by using the signed URL.