使用预签名 URL 共享对象 - Amazon Simple Storage Service
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

欢迎使用新的 Amazon S3 用户指南! Amazon S3 用户指南结合了以下三个已停用的指南中的信息和说明:Amazon S3 开发人员指南Amazon S3 控制台用户指南Amazon S3 入门指南

使用预签名 URL 共享对象

默认情况下,所有的对象都为私有。只有对象所有者具有访问这些对象的权限。但是,对象所有者可以选择使用自己的安全凭证来创建预签名的 URL,以授予有限时间内的下载对象权限,从而与其他用户共享对象。

当您为对象创建预签名的 URL 时,必须提供安全凭证、指定存储桶名称和对象键、指定 HTTP 方法(指定为 GET 以下载对象)和过期日期和时间。预签名 URL 仅在指定的持续时间内有效。

然后,收到预签名 URL 的任何人都可以访问对象。例如,如果您在存储桶中具有一段视频,并且存储桶和对象均为私有,您可以通过生成预签名的 URL 来与其他用户共享视频。

注意
  • 具有有效安全凭证的任何人都可以创建预签名 URL。然而,为了成功地访问对象,必须由拥有执行预签名 URL 所基于的操作权限的人创建预签名 URL。

  • 可用于创建预签名 URL 的凭证包括:

    • IAM 实例配置文件:有效期最多 6 小时

    • AWS Security Token Service:在使用永久凭证(例如,AWS 账户根用户或 IAM 用户的凭证)签名时,有效期长达 36 小时

    • IAM 用户:在使用 AWS Signature Version 4 时,有效期长达 7 天

      要创建有效期长达 7 天的预签名 URL,请先为所使用的开发工具包指定 IAM 用户凭证(访问密钥和秘密访问密钥)。然后,使用 AWS 签名版本 4 生成预签名 URL。

  • 如果您已使用临时令牌创建预签名 URL,则此 URL 将在令牌过期时过期,即使创建的 URL 的过期时间更晚也是如此。

  • 由于预签名 URL 将访问 Amazon S3 存储桶的权限授予任何具有 URL 的人,我们建议您适当地保护它们。有关保护预签名 URL 的更多详细信息,请参阅限制预签名 URL 功能

生成预签名 URL

您可以使用 REST APIAWS 命令行界面以及适用于 Java、.NET、RubyPHPNode.jsPythonGo 的 AWS 开发工具包以编程方式生成预签名 URL。

如果您使用的是 Visual Studio,可以使用适用于 Visual Studio 的 AWS Explorer 为对象生成预签名 URL,而不需要编写任何代码。具有该 URL 的任何人均可下载对象。有关详细信息,请参阅从 AWS Explorer 使用 Amazon S3

有关安装 AWS Explorer 的说明,请参阅 使用 AWS 开发工具包和浏览器进行 Amazon S3 开发

以下示例将生成预签名 URL,您可以将其提供给其他用户,以便他们可以检索对象。有关更多信息,请参阅 使用预签名 URL 共享对象

Java

以下示例将生成预签名 URL,您可以将其提供给其他用户,以便他们可以从 S3 存储桶中检索对象。有关更多信息,请参阅 使用预签名 URL 共享对象

有关创建和测试有效示例的说明,请参阅测试 Amazon S3 Java 代码示例

import com.amazonaws.AmazonServiceException; import com.amazonaws.HttpMethod; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; import java.io.IOException; import java.net.URL; public class GeneratePresignedURL { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String objectKey = "*** Object key ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withRegion(clientRegion) .withCredentials(new ProfileCredentialsProvider()) .build(); // Set the presigned URL to expire after one hour. java.util.Date expiration = new java.util.Date(); long expTimeMillis = expiration.getTime(); expTimeMillis += 1000 * 60 * 60; expiration.setTime(expTimeMillis); // Generate the presigned URL. System.out.println("Generating pre-signed URL."); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectKey) .withMethod(HttpMethod.GET) .withExpiration(expiration); URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest); System.out.println("Pre-Signed URL: " + url.toString()); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }
.NET

以下示例将生成预签名 URL,您可以将其提供给其他用户,以便他们可以检索对象。有关更多信息,请参阅 使用预签名 URL 共享对象

有关如何创建和测试有效示例的说明,请参阅 运行 Amazon S3 .NET 代码示例

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; namespace Amazon.DocSamples.S3 { class GenPresignedURLTest { private const string bucketName = "*** bucket name ***"; private const string objectKey = "*** object key ***"; // Specify how long the presigned URL lasts, in hours private const double timeoutDuration = 12; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 s3Client; public static void Main() { s3Client = new AmazonS3Client(bucketRegion); string urlString = GeneratePreSignedURL(timeoutDuration); } static string GeneratePreSignedURL(double duration) { string urlString = ""; try { GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest { BucketName = bucketName, Key = objectKey, Expires = DateTime.UtcNow.AddHours(duration) }; urlString = s3Client.GetPreSignedURL(request1); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } return urlString; } } }
Go

您可以使用适用于 Go 的开发工具包上传对象。您可以发送 PUT 请求以在单个操作中上传数据。有关更多信息,请参阅适用于 Go 的 AWS 开发工具包开发人员指南中的为具有特定负载的 Amazon S3 PUT 操作生成预签名 URL

PHP

如需详细了解使用适用于 PHP 的 AWS 开发工具包版本 3 生成预签名 URL,请参阅适用于 PHP 开发人员指南的 AWS 开发工具包中的使用适用于 PHP 的 AWS 开发工具包版本 3 的 Amazon S3 预签名 URL