本文介绍如何使用STS以及签名URL临时授权访问OSS资源。

说明 如果需要生成HTTPS协议的签名URL,请将Endpoint中的通信协议设置为HTTPS。

使用STS进行临时授权

OSS可以通过阿里云STS(Security Token Service)进行临时授权访问。阿里云STS是为云计算用户提供临时访问令牌的Web服务。通过STS,您可以为第三方应用或子用户(即用户身份由您自己管理的用户)颁发一个自定义时效和权限的访问凭证。关于STS的更多信息,请参见STS介绍

STS的优势如下:

  • 您无需透露您的长期密钥(AccessKey)给第三方应用,只需生成一个访问令牌并将令牌交给第三方应用。您可以自定义这个令牌的访问权限及有效期限。
  • 您无需关心权限撤销问题,访问令牌过期后自动失效。
说明 关于搭建STS服务的具体操作,请参见开发指南中的使用STS临时访问凭证访问OSS。您可以通过调用STS服务的AssumeRole接口或者使用各语言STS SDK来获取临时访问凭证。临时访问凭证包括临时访问密钥(AccessKeyId和AccessKeySecret)和安全令牌(SecurityToken)。临时访问凭证有效时间单位为秒,最小值为900,最大值以当前角色设定的最大会话时间为准。更多信息,请参见设置角色最大会话时间

以下代码用于使用STS凭证构造签名请求。

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = "yourEndpoint";
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
// 从STS服务获取的安全令牌(SecurityToken)。
String securityToken = "yourSecurityToken";
// 填写Bucket名称,例如examplebucket。
//String bucketName = "examplebucket";
// 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
//String objectName = "exampleobject.txt";

// 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);

// 执行OSS相关操作,例如上传、下载文件等。
// 上传文件,此处以上传本地文件为例介绍。
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
//PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File("D:\\localpath\\examplefile.txt"));
//ossClient.putObject(putObjectRequest);

// 下载OSS文件到本地文件。如果指定的本地文件存在则覆盖,不存在则新建。
// 如果未指定本地路径,则下载后的文件默认保存到示例程序所属项目对应本地路径中。
//ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File("D:\\localpath\\examplefile.txt"));

// 关闭OSSClient。
ossClient.shutdown();

使用签名URL进行临时授权

以下介绍使用签名URL临时授权的常见示例。

说明 由于STS临时账号以及签名URL均需设置有效时长,当您使用STS临时账号生成签名URL执行相关操作(例如上传、下载文件)时,以最小的有效时长为准。例如您的STS临时账号的有效时长设置为1200秒、签名URL设置为3600秒时,当有效时长超过1200秒后,您无法使用此STS临时账号生成的签名URL上传文件。
  • 生成签名URL

    您可以将生成的签名URL提供给访客进行临时访问。生成签名URL时,您可以通过指定URL的过期时间来限制访客的访问时长。签名URL的默认过期时间为3600秒,最大值为32400秒。

    在URL中加入签名信息,以便将该URL转给第三方实现授权访问。具体操作,请参见在URL中包含签名

  • 生成以GET方法访问的签名URL

    您可以根据需要一次生成单个或者多个以GET方法访问的签名URL。

    • 生成单个以GET方法访问的签名URL

      以下代码用于一次生成单个以GET方法访问的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
      URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
      System.out.println(url);
      // 关闭OSSClient。
      ossClient.shutdown();                    
    • 生成多个以GET方法访问的签名URL

      以下代码用于一次生成多个以GET方法访问的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
      String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      
      List<URL> urlList = new ArrayList<URL>();
      for(int i=0; i<objectNameList.length; i++){
          URL url = ossClient.generatePresignedUrl(bucketName, objectNameList[i], expiration);
          urlList.add(url);
      }
      // 打印签名URL。
      for(URL url:urlList){
          System.out.println(url);
      }
      // 关闭OSSClient。
      ossClient.shutdown();
  • 生成以其他HTTP方法访问的签名URL

    如果您要授权其他用户临时执行其他操作(例如上传、删除文件等),需要生成对应的签名URL,例如生成以PUT方法访问的签名URL来上传文件。您可以根据需要一次生成单个或者多个以其他HTTP方法访问的签名URL。

    • 生成单个以其他HTTP方法访问的签名URL

      以下代码用于一次生成单个以其他HTTP方法访问的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      String objectName = "exampleobject.txt";
      
      // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      request.setExpiration(expiration);
      // 设置ContentType。
      request.setContentType("text/plain");
      // 设置自定义元信息。
      request.addUserMetadata("author", "aliy");
      
      // 生成签名URL。
      URL signedUrl = ossClient.generatePresignedUrl(request);
      System.out.println(signedUrl);
      
      Map<String, String> requestHeaders = new HashMap<String, String>();
      // 设置ContentType,必须和生成签名URL时设置的ContentType一致。
      requestHeaders.put(HttpHeaders.CONTENT_TYPE, "text/plain");
      // 设置自定义元信息。
      requestHeaders.put(OSS_USER_METADATA_PREFIX + "author", "aliy");
      
      // 使用签名URL上传文件。
      ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);
      
      // 关闭OSSClient。
      ossClient.shutdown();         
    • 生成多个以其他HTTP方法访问的签名URL

      以下代码用于一次生成多个以其他HTTP方法访问的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
      String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
      String upLoadNameArray [] = {"D:\\localpath\\examplefile1.txt","D:\\localpath\\examplefile2.jpg"};
      
      
      // 从STS服务获取临时访问凭证后,您可以通过临时访问密钥和安全令牌生成OSSClient。
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      for(int i=0; i<objectNameList.length; i++){
          GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectNameList[i], HttpMethod.PUT);
          request.setExpiration(expiration);
          // 设置ContentType。
          request.setContentType(DEFAULT_OBJECT_CONTENT_TYPE);
          // 设置自定义元信息。
          request.addUserMetadata("author", "aliy");
      
          // 生成签名URL。
          URL signedUrl = ossClient.generatePresignedUrl(request);
          // 打印签名URL。
          System.out.println(signedUrl);
      
          Map<String, String> requestHeaders = new HashMap<String, String>();
          requestHeaders.put(HttpHeaders.CONTENT_TYPE, DEFAULT_OBJECT_CONTENT_TYPE);
          requestHeaders.put(OSS_USER_METADATA_PREFIX + "author", "aliy");
      
          // 如果要上传字符串,请使用如下方式。
          //ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);
         
          // 使用签名URL上传文件。
          try {
            ossClient.putObject(signedUrl, new FileInputStream(new File(upLoadNameArray[i])), -1, requestHeaders, true);
          } catch (FileNotFoundException e) {
            e.printStackTrace();
          }
      }
      
      // 关闭OSSClient。
      ossClient.shutdown();

    通过传入HttpMethod.PUT参数,访客可以使用生成的签名URL上传文件。

  • 生成带有指定参数的签名URL

    您可以根据需要一次生成单个或者多个带有指定参数的签名URL。

    • 生成单个带有指定参数的签名URL

      以下代码用于一次生成单个带有指定参数的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 创建请求。
      GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
      // 设置HttpMethod为PUT。
      generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
      // 添加用户自定义元信息。
      generatePresignedUrlRequest.addUserMetadata("author", "baymax");
      // 设置ContentType。
      generatePresignedUrlRequest.setContentType("application/txt");
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      generatePresignedUrlRequest.setExpiration(expiration);
      // 生成签名URL。
      URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
      System.out.println(url);
      // 关闭OSSClient。
      ossClient.shutdown();                    
    • 生成多个带有指定参数的签名URL

      以下代码用于一次生成多个带有指定参数的签名URL。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      // 此处请填写多个Object完整路径,用于一次性获取多个Object的签名URL。
      String objectNameList [] = {"exampleobject.txt","exampleimage.jpg"};
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      // 设置签名URL过期时间为3600秒(1小时)。
      Date expiration = new Date(new Date().getTime() + 3600 * 1000);
      for(int i=0; i<objectNameList.length; i++){
          // 创建请求。
          GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectNameList[i]);
          // 设置HttpMethod为PUT。
          generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
          // 添加用户自定义元信息。
          generatePresignedUrlRequest.addUserMetadata("author", "baymax");
          // 设置ContentType。
          generatePresignedUrlRequest.setContentType("application/txt");
          generatePresignedUrlRequest.setExpiration(expiration);
          // 生成签名URL。
          URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
          // 打印签名URL。
          System.out.println(url);
      }
      // 关闭OSSClient。
      ossClient.shutdown();
  • 使用签名URL上传或获取文件
    • 使用签名URL上传文件

      以下代码用于使用签名URL上传文件。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 填写签名URL的过期时间。
      Date expiration = null;
      try {
          expiration = DateUtil.parseRfc822Date("Wed, 18 Mar 2022 14:20:00 GMT");
      } catch (ParseException e) {
          e.printStackTrace();
      }
      // 生成签名URL。
      GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
      // 设置过期时间。
      request.setExpiration(expiration);
      // 设置ContentType。
      request.setContentType("application/txt");
      // 添加用户自定义元信息。
      request.addUserMetadata("author", "aliy");
      // 通过HTTP PUT请求生成签名URL。
      URL signedUrl = ossClient.generatePresignedUrl(request);
      System.out.println("signed url for putObject: " + signedUrl);
      
      // 使用签名URL发送请求。
      // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
      File f = new File("D:\\localpath\\examplefile.txt");
      FileInputStream fin = null;
      try {
          fin = new FileInputStream(f);
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      }
      // 添加PutObject请求头。
      Map<String, String> customHeaders = new HashMap<String, String>();
      customHeaders.put("Content-Type", "application/txt");
      customHeaders.put("x-oss-meta-author", "aliy");
      
      PutObjectResult result = ossClient.putObject(signedUrl, fin, f.length(), customHeaders);
      
      // 关闭OSSClient。
      ossClient.shutdown();                           
    • 使用签名URL获取文件

      以下代码用于使用签名URL获取指定文件。

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 从STS服务获取的安全令牌(SecurityToken)。
      String securityToken = "yourSecurityToken";
      // 填写Bucket名称,例如examplebucket。
      String bucketName = "examplebucket";
      // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
      
      // 填写签名URL的过期时间。
      Date expiration = null;
      try {
          expiration = DateUtil.parseRfc822Date("Wed, 18 Mar 2022 14:20:00 GMT");
      } catch (ParseException e) {
          e.printStackTrace();
      }
      // 生成签名URL。
      GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
      // 设置过期时间。
      request.setExpiration(expiration);
      // 通过HTTP GET请求生成签名URL。
      URL signedUrl = ossClient .generatePresignedUrl(request);
      System.out.println("signed url for getObject: " + signedUrl);
      
      // 使用签名URL发送请求。
      Map<String, String> customHeaders = new HashMap<String, String>();
      // 添加GetObject请求头。
      customHeaders.put("Range", "bytes=100-1000");
      OSSObject object = ossClient.getObject(signedUrl,customHeaders);
      
      // 关闭OSSClient。
      ossClient.shutdown();