All Products
Search
Document Center

Object Storage Service:Authorize access

Last Updated:Oct 08, 2023

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 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 the temporary access credentials that are provided by STS to 1,200 seconds and the validity period of the signed URL generated by using the credentials to 3,600 seconds. In this case, you cannot use the signed URL to upload objects after the temporary access credentials expire, even if the signed URL is within the validity period.

Usage notes

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

  • In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.

  • 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 for temporary access authorization

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 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 the validity period of the access token.

  • The access token automatically expires after the validity period. Therefore, you do not need to revoke the access permissions of an access token.

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

  1. Obtain temporary access credentials.

    The temporary access credentials consist of an 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.

    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. Access OSS by using temporary access credentials provided by STS.

    • Upload an object by using the temporary access credentials obtained from STS

      package main
      
      import (
          "fmt"
          "github.com/aliyun/aliyun-oss-go-sdk/oss"
          "os"
      )
      
      func main() {
          // Obtain temporary access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, and OSS_SESSION_TOKEN environment variables are configured. 
          provider, err := oss.NewEnvironmentVariableCredentialsProvider()
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          // Create an OSSClient instance. 
          // 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. Specify your actual endpoint. 
          client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          // Specify the name of the bucket. Example: examplebucket. 
          bucketName := "examplebucket"
          // Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
          objectName := "exampledir/exampleobject.txt"
          // Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. 
          filepath := "D:\\localpath\\examplefile.txt"
          bucket,err := client.Bucket(bucketName)
          // Use the temporary access credentials obtained from STS to grant the third-party user permissions to upload objects. 
          err = bucket.PutObjectFromFile(objectName,filepath)
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          fmt.Println("upload success")
      }
    • Download an object by using the temporary access credentials obtained from STS

      package main
      
      import (
          "fmt"
          "github.com/aliyun/aliyun-oss-go-sdk/oss"
          "os"
      )
      
      func main() {
          // Obtain temporary access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, and OSS_SESSION_TOKEN environment variables are configured. 
          provider, err := oss.NewEnvironmentVariableCredentialsProvider()
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          // Create an OSSClient instance. 
          // 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. Specify your actual endpoint. 
          client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          // Specify the name of the bucket. Example: examplebucket. 
          bucketName := "examplebucket"
          // Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
          objectName := "exampledir/exampleobject.txt"
          // Specify the full path of the local file. Example: D:\\localpath\\examplefile.txt. 
          filepath := "D:\\localpath\\examplefile.txt"
          bucket,err := client.Bucket(bucketName)
          // Use the temporary access credentials obtained from STS to grant the third-party user permissions to download objects. 
          err = bucket.GetObjectToFile(objectName,filepath)
          if err != nil {
              fmt.Println("Error:", err)
              os.Exit(-1)
          }
          fmt.Println("download success")
      }

Use a signed URL to authorize temporary access

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 the object.

Important

The signed URL generated by using the following sample code may contain a plus sign (+). In this case, you must replace + in the URL with %2B. Otherwise, the signed URL may be inaccessible.

This section provides examples on how to generate a signed URL to authorize temporary access to OSS. For the complete code that is used to authorize temporary access by using a signed URL, visit GitHub.

Use a signed URL to upload an object

  1. Generate a signed URL.

    package main
    
    import (
        "fmt"
        "os"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func HandleError(err error) {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    func main() {
    	// 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. 
    	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
    	// Create an OSSClient instance. 
    	// 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. Specify your actual endpoint. 
    	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    	if err != nil {
    		fmt.Println("Error:", err)
    		os.Exit(-1)
    	}
        // Specify the name of the bucket. Example: examplebucket. 
        bucketName := "examplebucket"
        // Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path. 
        objectName := "exampledir/exampleobject.txt"
        bucket, err := client.Bucket(bucketName)
        if err != nil {
            HandleError(err)
        }
        // Generate a signed URL with a specified validity period for uploading the object. In this example, the validity period of the URL is 60 seconds. 
        signedURL, err := bucket.SignURL(objectName, oss.HTTPPut, 60)
        if err != nil {
            HandleError(err)
        }
    
        // To use a signed URL that contains custom parameters to access an object from a browser, make sure that the value of the ContentType parameter contained in the URL is the same as the ContentType value specified in the request. 
        options := []oss.Option{
            oss.Meta("myprop", "mypropval"),
            oss.ContentType("text/plain"),
        }
        
        signedURL, err = bucket.SignURL(objectName, oss.HTTPPut, 60, options...)
        if err != nil {
            HandleError(err)
        }
        fmt.Printf("Sign Url:%s\n", signedURL)
    }
  2. Upload an object 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.

Use signed URLs to upload an object in multipart upload

If you want to use signed URLs to authorize third-party applications to upload a large object in multipart upload, you must initiate a multipart upload task, generate a signed URL for each part, and provide the signed URLs to the third-party applications. Then, the third-party applications can use the signed URLs to upload all parts of the object and combine the parts.

The following sample code provides an example on how to generate signed URLs and use the signed URLs to upload an object in multipart upload:

package main

import (
    "crypto/md5"
    "encoding/base64"
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "github.com/aliyun/aliyun-oss-go-sdk/sample"
    "io/ioutil"
    "os"
    "strconv"
)

func main() {
    // 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. 
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // Create an OSSClient instance. 
    // 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. Specify your actual endpoint. 
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    bucketName := "bucket_name"

    bucket,err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // Specify the full path of the object. Do not include the bucket name in the full path. 
    objectName := "example.txt"
    // Specify the full path of the local file that you want to upload. By default, if you do not specify the full path of the local file, the local file is uploaded from the path of the project to which the sample program belongs. 
    localFile := "D:\\download\\demo.txt"

    // Split the local file into three parts. 
    chunks, err := oss.SplitFileByPartNum(localFile, 3)
    fd, err := os.Open(localFile)
    defer fd.Close()
    // Step 1: Initiate a multipart upload task and set the storage class to Standard. 
    imur, err := bucket.InitiateMultipartUpload(objectName)
    // Step 2: Upload parts. 
    var options []oss.Option

    for _, chunk := range chunks {
        // Verify MD5 encryption. 
        // buf := make([]byte, chunk.Size)
        // fd.ReadAt(buf,chunk.Size)
        // sum := md5.Sum(buf)
        // b64 := base64.StdEncoding.EncodeToString(sum[:])
        // options = []oss.Option{
        //     oss.ContentMD5(b64),
        // }

        options = append(options, oss.AddParam("partNumber", strconv.Itoa(chunk.Number)))
        options = append(options, oss.AddParam("uploadId", imur.UploadID))
        // Generate the signed URL. 
        signedURL, err := bucket.SignURL(objectName, oss.HTTPPut, 60,options)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        fmt.Printf("Signed URL:%s\n", signedURL)
    }
    
    lsRes, err := bucket.ListUploadedParts(imur)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // Traverse the parts and fill the ETag value. 
    var parts []oss.UploadPart
    for _, p := range lsRes.UploadedParts {
        parts = append(parts, oss.UploadPart{XMLName: p.XMLName, PartNumber: p.PartNumber, ETag: p.ETag})
    }

    // Step 3: Complete the multipart upload task. 
    _, err := bucket.CompleteMultipartUpload(imur, parts)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("Uploaded")
}

Use a signed URL to download an object

  1. Generate a signed URL.

    package main
    
    import (
        "fmt"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
        "os"
    )
    
    func HandleError(err error) {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    
    func main() {
        // 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. 
        provider, err := oss.NewEnvironmentVariableCredentialsProvider()
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        // Create an OSSClient instance. 
        // 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. Specify your actual endpoint. 
        client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
    
        // Specify the name of the bucket. Example: examplebucket. 
        bucketName := "examplebucket"
        // Specify the full path of the object. Example: exampledir/exampleobject.txt. Do not include the bucket name in the full path. 
        objectName := "exampledir/exampleobject.txt"
        // Download the object to the specified path on your local computer. If a file that has the same name already exists in the specified path, the downloaded object overwrites the file. Otherwise, the downloaded file is saved in the path. 
        bucket, err := client.Bucket(bucketName)
        if err != nil {
            HandleError(err)
        }
    
        // Generate a signed URL with a specified validity period for downloading the object. In this example, the validity period of the URL is 60 seconds. 
        signedURL, err := bucket.SignURL(objectName, oss.HTTPGet, 60)
        if err != nil {
            HandleError(err)
        }
        fmt.Printf("Sign Url:%s\n", signedURL)
    }
  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.

Generate a signed URL that includes the VersionId header

The following sample code provides an example on how to generate a signed URL that includes the VersionId header:

package main

import (
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"os"
)

func main() {
	// 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. 
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// Create an OSSClient instance. 
	// 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. Specify your actual endpoint. 
	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// Specify the name of the bucket. Example: examplebucket. 
	bucketName := "examplebucket"
	// Specify the full path of the object. Do not include the bucket name in the full path. Example: exampledir/exampleobject.txt. 
	objectName := "exampledir/exampleobject.txt"
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// Specify the version ID of the object. 
	// Generate a signed URL with a specified validity period. In this example, the validity period of the URL is 60 seconds. 
	signedURL, err := bucket.SignURL(objectName, oss.HTTPGet, 60, oss.VersionId("CAEQEhiBgIDmgPf8mxgiIDA1YjZlNDIxY2ZmMzQ1MmU5MTM1Y2M4Yzk4******"))
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	fmt.Printf("Sign Url:%s\n", signedURL)
}