使用Amazon S3预签名 URL - Amazon SDK for Java
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

现在,您可以使用Amazon S3转移经理(开发人员预览版)中的Amazon SDK for Java2.x 用于加速文件传输。试试一下然后告诉我们您的想法!顺便说一句,Amazon SDK for Java正在招聘团队软件开发工程师

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用Amazon S3预签名 URL

您可以使用S3Presigner要签署的对象Amazon S3 SdkRequest以便在不需要调用者身份验证的情况下执行该函数。例如,假设 Alice 有权访问 S3 对象,并希望临时与 Bob 共享对该对象的访问权限。Alice 可以生成预签名的 GetObjectRequest 对象以确保与 Bob 共享,这样 Bob 就可以下载该对象而无需访问 Alice 的凭证。

生成预签名 URL 并上传对象

构建表示客户端对象的 S3Presigner 对象。接下来创建一个可以在以后执行的 PuregnedputjectSequest 对象,而不需要额外的签名或身份验证。创建此对象时,您可以指定存储桶名称和密钥名称。此外,您还可以通过调用 signatureDuration 方法(如以下代码示例所示),指定可以在不使用凭证的情况下访问存储桶的时间(以分钟为单位)。

您可以通过调用 PresignedPutObjectRequest 对象的 url 方法来获取 URL。

导入

import java.io.IOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.time.Duration; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;

代码

以下 Java 代码示例将内容上传到预签名的 S3 存储桶。

public static void signBucket(S3Presigner presigner, String bucketName, String keyName) { try { PutObjectRequest objectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(keyName) .contentType("text/plain") .build(); PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder() .signatureDuration(Duration.ofMinutes(10)) .putObjectRequest(objectRequest) .build(); PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest); String myURL = presignedRequest.url().toString(); System.out.println("Presigned URL to upload a file to: " +myURL); System.out.println("Which HTTP method needs to be used when uploading a file: " + presignedRequest.httpRequest().method()); // Upload content to the Amazon S3 bucket by using this URL URL url = presignedRequest.url(); // Create the connection and use it to upload the new object by using the presigned URL HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestProperty("Content-Type","text/plain"); connection.setRequestMethod("PUT"); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream()); out.write("This text was uploaded as an object by using a presigned URL."); out.close(); connection.getResponseCode(); System.out.println("HTTP response code is " + connection.getResponseCode()); } catch (S3Exception e) { e.getStackTrace(); } catch (IOException e) { e.getStackTrace(); } }

请参阅 GitHub 上的完整示例

获取预签名对象

构建表示客户端对象的 S3Presigner 对象。接下来,创建一个 GetObjectSequest 对象并指定存储桶名称和密钥名称。此外,创建一个可以在以后执行的 GetObjectPresignRequest 对象,而不需要额外的签名或身份验证。当您创建此对象时,您可以通过调用 signatureDuration 方法(如以下代码示例所示)指定可以在不使用凭证的情况下访问存储桶的时间(以分钟为单位)。

调用presignGetObject属于S3Presigner要创建的对象PresignedPutObjectRequest对象。您可以调用此对象的 url 方法来获取要使用的 URL。获得 URL 后,您可以使用标准 HTTP Java 逻辑读取存储桶的内容,如以下 Java 代码示例所示。

导入

import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.time.Duration; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.S3Exception; import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.utils.IoUtils;

代码

以下 Java 代码示例从预签名 S3 存储桶中读取内容。

public static void getPresignedUrl(S3Presigner presigner, String bucketName, String keyName ) { try { GetObjectRequest getObjectRequest = GetObjectRequest.builder() .bucket(bucketName) .key(keyName) .build(); GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder() .signatureDuration(Duration.ofMinutes(10)) .getObjectRequest(getObjectRequest) .build(); // Generate the presigned request PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest); // Log the presigned URL System.out.println("Presigned URL: " + presignedGetObjectRequest.url()); HttpURLConnection connection = (HttpURLConnection) presignedGetObjectRequest.url().openConnection(); presignedGetObjectRequest.httpRequest().headers().forEach((header, values) -> { values.forEach(value -> { connection.addRequestProperty(header, value); }); }); // Send any request payload that the service needs (not needed when isBrowserExecutable is true) if (presignedGetObjectRequest.signedPayload().isPresent()) { connection.setDoOutput(true); try (InputStream signedPayload = presignedGetObjectRequest.signedPayload().get().asInputStream(); OutputStream httpOutputStream = connection.getOutputStream()) { IoUtils.copy(signedPayload, httpOutputStream); } } // Download the result of executing the request try (InputStream content = connection.getInputStream()) { System.out.println("Service returned response: "); IoUtils.copy(content, System.out); } } catch (S3Exception e) { e.getStackTrace(); } catch (IOException e) { e.getStackTrace(); } }

请参阅 GitHub 上的完整示例