All Products
Search
Document Center

Object Storage Service:Authorize access

Last Updated:Feb 20, 2025

The Android SDK offers STS authentication mode, self-signed mode, and presigned URL methods to secure mobile terminal access.

Background information

In both STS authentication and self-signed modes, the implemented callback function must return the token and signature results upon invocation. If a network request is needed to retrieve the token and signature from the business server, the network library's synchronous interface is recommended. The callback runs on a subthread initiated by the SDK, preventing main thread blockage.

STS authentication mode

Note

To utilize STS authentication mode, Alibaba Cloud Resource Access Management (RAM) service must be activated first.

Alibaba Cloud STS allows temporary OSS access. STS, a web service, grants temporary access tokens to cloud computing users. You can issue an access credential with custom permissions and a set validity period to a third-party application or a RAM user under your management. For more information about STS, see What is STS.

STS offers several benefits:

  • Your long-term AccessKey pair remains unexposed to third-party applications. Instead, you generate and send an access token with defined permissions and a validity period.

  • There's no need to worry about permission revocation; the access token expires automatically once the validity period ends.

The steps to access OSS with STS temporary access credentials are:

  1. Obtain temporary access credentials

    These credentials include a temporary AccessKey pair and a security token (SecurityToken), with a validity period measured in seconds. The minimum period is 900 seconds, and the maximum is the current role's specified maximum session duration. For more details, see Set the maximum session duration for a RAM role.

    Temporary access credentials can be obtained in two ways:

  2. Initialize the SDK with temporary access credentials.

    String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    
    OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider("StsToken.AccessKeyId", "StsToken.SecretKeyId", "StsToken.SecurityToken");
    
    OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider);                  

    Be mindful of the STS token's validity period when initializing the SDK.

    Here's sample code to update an STS token when its remaining validity is under 5 minutes:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date date = sdf.parse("<StsToken.Expiration>");
    long expiration = date.getTime() / 1000;
    // Update the STS token when its remaining validity period is less than 5 minutes.
    if (DateUtil.getFixedSkewedTimeMillis() / 1000 > expiration - 5 * 60) {
        oss.updateCredentialProvider(new OSSStsTokenCredentialProvider("StsToken.AccessKeyId", "StsToken.SecretKeyId", "StsToken.SecurityToken"));
    }
    • Manually update the STS token

      To update an expiring STS token, create a new OSSClient instance or update CredentialProvider with the following command:

      oss.updateCredentialProvider(new OSSStsTokenCredentialProvider("StsToken.AccessKeyId", "StsToken.SecretKeyId", "StsToken.SecurityToken"));                   
    • Automatically update the STS token

      Implement a callback in your app for the SDK to automatically update the STS token. The callback retrieves a federation token (STS token) and returns it to the SDK, which uses it to generate signatures. The SDK invokes the callback for a new token when needed.

      String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
      
      OSSCredentialProvider credentialProvider = new OSSFederationCredentialProvider() {
      
          @Override
          public OSSFederationToken getFederationToken() {
          // Obtain a federation token, construct the token, and then return the token as an OSSFederationToken object. If no federation token is obtained, null is returned.
      
              OSSFederationToken token;
              // Obtain a federation token from your server.
              return token;
          }
      };
      
      OSS oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider);                    
      Note

      If you obtain all fields required for an STS token elsewhere, directly return the token in the callback. Remember to manually update the token and reconfigure OSSCredentialProvider of the OSSClient instance.

      For a server URL like http://localhost:8080/distribute-token.json, expect a sample response as follows:

      {
          "StatusCode": 200,
          "AccessKeyId":"STS.iA645eTOXEqP3cg3****",
          "AccessKeySecret":"rV3VQrpFQ4BsyHSAvi5NVLpPIVffDJv4LojU****",
          "Expiration":"2015-11-03T09:52:59Z",
          "SecurityToken":"CAES7QIIARKAAZPlqaN9ILiQZPS+JDkS/GSZN45RLx4YS/p3OgaUC+oJl3XSlbJ7StKpQ****"}                    

      Below is sample code to implement OSSFederationCredentialProvider:

      OSSCredentialProvider credetialProvider = new OSSFederationCredentialProvider() {
          @Override
          public OSSFederationToken getFederationToken() {
              try {
                  URL stsUrl = new URL("http://localhost:8080/distribute-token.json");
                  HttpURLConnection conn = (HttpURLConnection) stsUrl.openConnection();
                  InputStream input = conn.getInputStream();
                  String jsonText = IOUtils.readStreamAsString(input, OSSConstants.DEFAULT_CHARSET_NAME);
                  JSONObject jsonObjs = new JSONObject(jsonText);
                  String ak = jsonObjs.getString("AccessKeyId");
                  String sk = jsonObjs.getString("AccessKeySecret");
                  String token = jsonObjs.getString("SecurityToken");
                  String expiration = jsonObjs.getString("Expiration");
                  return new OSSFederationToken(ak, sk, token, expiration);
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return null;
          }
      };                    

Presigned URL

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.

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

Here are common scenarios for temporary authorization using a presigned URL:

Generate a presigned URL and upload a file by using the presigned URL

  1. Generate a presigned URL for uploads.

    // Specify the bucket name. Example: examplebucket.
    String bucketName = "examplebucket";
    // Specify the full path of the source object. Do not include the bucket name. Example: exampleobject.txt.
    String objectKey = "exampleobject.txt";
    // Set the content type.
    String contentType = "application/octet-stream";
    String url = null;
    try {
        // Generate a presigned URL for uploading a file.
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
        // Set the expiration time of the presigned URL to 30 minutes.
        request.setExpiration(30*60);
        request.setContentType(contentType);    
        request.setMethod(HttpMethod.PUT);
        url = oss.presignConstrainedObjectURL(request);
        Log.d("url", url);
    } catch (ClientException e) {
        e.printStackTrace();
    }
  2. Upload a file using the presigned URL.

    // Specify the generated presigned URL.
    String url = "";
    // Specify the full path of the local file.
    String localFile = "/storage/emulated/0/oss/examplefile";
    // Set the content type.
    String contentType = "application/octet-stream";
    // Upload a file by using the presigned URL.
    OkHttpClient client = new OkHttpClient();
    Request putRequest = new Request.Builder()
            .url(url)
            .put(RequestBody.create(MediaType.parse(contentType), new File(localFile)))
            .build();
    client.newCall(putRequest).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d("response", response.body().string());
        }
    });

Generate a presigned URL and download a file by using the presigned URL

  1. Generate a presigned URL for downloads.

    // Specify the bucket name. Example: examplebucket.
    String bucketName = "examplebucket";
    // Specify the full path of the source object. Do not include the bucket name. Example: exampleobject.txt.
    String objectKey = "exampleobject.txt";
    String url = null;
    try {
        // Generate a presigned URL for downloading a file.
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
        // Set the expiration time of the presigned URL to 30 minutes.
        request.setExpiration(30*60);
        request.setMethod(HttpMethod.GET);
        url = oss.presignConstrainedObjectURL(request);
        Log.d("url", url);
    } catch (ClientException e) {
        e.printStackTrace();
    }
  2. Download a file using the presigned URL.

    // Specify the generated presigned URL.
    String url = "";
    OkHttpClient client = new OkHttpClient();
    // Download a file by using the presigned URL.
    Request getRequest = new Request.Builder()
            .url(url)
            .get()
            .build();
    client.newCall(getRequest).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.code() == 203 || response.code() >= 300) {
                Log.d("download", "fail");
                Log.d("download", response.body().string());
                return;
            }
            // The request is successful.
            InputStream inputStream = response.body().byteStream();
    
            byte[] buffer = new byte[2048];
            int len;
    
            while ((len = inputStream.read(buffer)) != -1) {
                // Process the downloaded data. For example, display the image or perform a write operation on the object.
            }
        }
    });