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

使用STS进行临时授权

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

STS的优势如下:

  • 您无需透露您的长期密钥(AccessKey)给第三方应用,只需生成一个访问令牌并将令牌交给第三方应用。您可以自定义这个令牌的访问权限及有效期限。
  • 您无需关心权限撤销问题,访问令牌过期后自动失效。

使用STS访问OSS的流程请参见开发指南中的STS临时授权访问OSS

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

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
String endpoint = "yourEndpoint";
// 从STS服务获取的临时访问凭证。临时访问凭证包括临时访问密钥(AccessKeyId和AccessKeySecret)和安全令牌(SecurityToken)。
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
String securityToken = "yourSecurityToken";
// 填写Bucket名称。
//String bucketName = "examplebucket";
// 填写不包含Bucket名称在内的Object完整路径。
//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临时账号的有效时长设置为1200s、签名URL设置为3600s时,当有效时长超过1200s后,您无法使用此STS临时账号生成的签名URL上传文件。
  • 生成签名URL

    您可以将生成的签名URL提供给访客进行临时访问。生成签名URL时,您可以通过指定URL的过期时间来限制访客的访问时长。

    有关如何在URL中加入签名信息,以便将该URL转给第三方实现授权访问,详情请参见在URL中包含签名

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

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

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = "yourEndpoint";
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = "yourAccessKeyId";
    String accessKeySecret = "yourAccessKeySecret";
    // 填写Bucket名称。
    String bucketName = "examplebucket";
    // 填写不包含Bucket名称在内的Object完整路径。
    String objectName = "exampleobject.txt";
    
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // 设置URL过期时间为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();
                        
  • 生成以其他HTTP方法访问的签名URL

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

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = "yourEndpoint";
    // 从STS服务获取的临时访问凭证。临时访问凭证包括临时访问密钥(AccessKeyId和AccessKeySecret)和安全令牌(SecurityToken)。
    String accessKeyId = "yourAccessKeyId";
    String accessKeySecret = "yourAccessKeySecret";
    String securityToken = "yourSecurityToken";
    // 填写Bucket名称。
    String bucketName = "examplebucket";
    // 填写不包含Bucket名称在内的Object完整路径。
    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过期时间为1小时。
    Date expiration = new Date(new Date().getTime() + 3600 * 1000);
    request.setExpiration(expiration);
    // 设置ContentType。
    request.setContentType(DEFAULT_OBJECT_CONTENT_TYPE);
    // 设置自定义元信息。
    request.addUserMetadata("author", "aliy");
    
    // 生成签名URL。
    URL signedUrl = ossClient.generatePresignedUrl(request);
    
    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");
    
    // 使用签名URL上传文件。
    ossClient.putObject(signedUrl, new ByteArrayInputStream("Hello OSS".getBytes()), -1, requestHeaders, true);
    
    // 关闭OSSClient。
    ossClient.shutdown();
                        

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

  • 生成指定参数的签名URL

    以下代码用于生成指定参数的签名URL。

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = "yourEndpoint";
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = "yourAccessKeyId";
    String accessKeySecret = "yourAccessKeySecret";
    // 填写Bucket名称。
    String bucketName = "examplebucket";
    // 填写不包含Bucket名称在内的Object完整路径。
    String objectName = "exampleobject.txt";
    
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    
    // 创建请求。
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
    // 设置HttpMethod为PUT。
    generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
    // 添加用户自定义元信息。
    generatePresignedUrlRequest.addUserMetadata("author", "baymax");
    // 设置ContentType。
    generatePresignedUrlRequest.setContentType("application/txt");
    // 设置URL过期时间为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上传文件

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

      // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
      String endpoint = "yourEndpoint";
      // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 填写Bucket名称。
      String bucketName = "examplebucket";
      // 填写不包含Bucket名称在内的Object完整路径。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
      
      // 填写签名URL的过期时间。
      Date expiration = DateUtil.parseRfc822Date("Wed, 18 Mar 2022 14:20:00 GMT");
      // 生成签名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 = new FileInputStream(f);
      // 添加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";
      // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
      String accessKeyId = "yourAccessKeyId";
      String accessKeySecret = "yourAccessKeySecret";
      // 填写Bucket名称。
      String bucketName = "examplebucket";
      // 填写不包含Bucket名称在内的Object完整路径。
      String objectName = "exampleobject.txt";
      
      // 创建OSSClient实例。
      OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
      
      // 填写签名URL的过期时间。
      Date expiration = DateUtil.parseRfc822Date("Wed, 18 Mar 2022 14:20:00 GMT");
      // 生成签名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();