Fazer upload de objetos usando pre-signed URLs - Amazon Simple Storage Service

Bem-vindo ao novo Guia do usuário do Amazon S3! O Guia do usuário do Amazon S3 combina informações e instruções de três guias desativados: o Guia do desenvolvedor do Amazon S3, o Guia do usuário do console do Amazon S3 e o Guia de conceitos básicos do Amazon S3.

Fazer upload de objetos usando pre-signed URLs

Um pre-signed URL fornece acesso ao objeto identificado no URL, desde que o criador do pre-signed URL tenha permissões para acessar esse objeto. Isto é, se você receber um pre-signed URL para fazer upload de um objeto, poderá fazer upload do objeto somente se o criador do pre-signed URL tiver as permissões necessárias para fazer upload desse objeto.

Por padrão, todos os objetos e buckets são privados. Os pre-signed URLs serão úteis se você desejar que o usuário/cliente seja capaz de fazer upload de um objeto específico no seu bucket, mas não exigir que ele tenha credenciais ou permissões de segurança da AWS.

Quando cria um pre-signed URL, você deve fornecer as credenciais de segurança, e então especificar um nome de bucket, uma chave de objeto, um método HTTP (PUT para upload de objetos) e data e hora de expiração. Os pre-signed URLs são válidos apenas pela duração especificada. Ou seja, é necessário iniciar a ação antes da data e a hora de expiração. Se a ação consistir em várias etapas, como um multipart upload, todas as etapas devem ser iniciadas antes da expiração, caso contrário, você receberá um erro quando o Amazon S3 tentar iniciar uma etapa com um URL expirado.

É possível usar o pre-signed URL várias vezes, até a data e a hora de expiração.

Acesso à pre-signed URL

Como os URLs pré-assinados concedem acesso aos buckets do Amazon S3 a quem tiver o URL, recomendamos que você os proteja adequadamente. Para obter mais detalhes sobre como proteger pre-signed URLs, consulte Limitar recursos de pre-signed URLs.

Qualquer um com credenciais de segurança válidas pode criar um pre-signed URL. No entanto, para fazer upload de um objeto, o pre-signed URL deve ter sido criado por alguém que tenha permissão para executar a operação na qual o pre-signed URL está baseado.

Gerar um pre-signed URL para upload de objetos

É possível gerar um pre-signed URL de forma programática usando o AWS SDK para Java, .NET, Ruby, PHP, Node.js e Python.

Se você estiver usando o Microsoft Visual Studio, também poderá usar o AWS Explorer para gerar um pre-signed URL de objeto sem gravar nenhum código. Qualquer pessoa que receber um pre-signed URL válido poderá fazer upload de um objeto programaticamente. Para obter mais informações, consulte Usar o Amazon S3 no AWS Explorer. Para obter instruções sobre como instalar o AWS Explorer, consulte Desenvolvimento com o Amazon S3 usando os AWS SDKs e exploradores.

É possível usar o AWS SDK para gerar um URL pré-assinado que você, ou qualquer pessoa a quem você der o URL, poderá usar para fazer upload de um objeto no Amazon S3. Quando você usar o URL para fazer upload de um objeto, o Amazon S3 cria o objeto no bucket especificado. Se um objeto com a mesma chave especificada no pre-signed URL já existir no bucket, o Amazon S3 substituirá o objeto existente pelo objeto obtido por upload.

Exemplos

Os exemplos a seguir mostram como fazer upload de objetos usando URLs pré-assinados.

Java

Para concluir um upload com êxito, você deve fazer o seguinte:

  • Especificar o verbo HTTP PUT ao criar os objetos GeneratePresignedUrlRequest e HttpURLConnection.

  • Interagir com o objeto HttpURLConnection de alguma forma após concluir o upload. O exemplo a seguir faz isso usando o objeto HttpURLConnection para verificar o código de resposta HTTP.

Esse exemplo gera um pre-signed URL e o usa para fazer upload dos dados de amostra como um objeto. Para obter instruções sobre criar e testar um exemplo funcional, consulte Testar exemplos de código Java no Amazon S3.

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 com.amazonaws.services.s3.model.S3Object; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; public class GeneratePresignedUrlAndUploadObject { 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() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Set the pre-signed 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 pre-signed URL. System.out.println("Generating pre-signed URL."); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectKey) .withMethod(HttpMethod.PUT) .withExpiration(expiration); URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest); // Create the connection and use it to upload the new object using the pre-signed URL. HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestMethod("PUT"); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream()); out.write("This text uploaded as an object via presigned URL."); out.close(); // Check the HTTP response code. To complete the upload and make the object available, // you must interact with the connection object in some way. connection.getResponseCode(); System.out.println("HTTP response code: " + connection.getResponseCode()); // Check to make sure that the object was uploaded successfully. S3Object object = s3Client.getObject(bucketName, objectKey); System.out.println("Object " + object.getKey() + " created in bucket " + object.getBucketName()); } 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

O exemplo de C# a seguir mostra como usar o AWS SDK para .NET para fazer upload de um objeto para um bucket do S3 usando um pre-signed URL.

Esse exemplo gera um pre-signed URL para um objeto específico e o utiliza para fazer upload de um arquivo. Para obter informações sobre a compatibilidade do exemplo com uma versão específica do AWS SDK para .NET e instruções sobre como criar e testar um exemplo funcional, consulte Executar os exemplos de código do Amazon S3 .NET.

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.IO; using System.Net; namespace Amazon.DocSamples.S3 { class UploadObjectUsingPresignedURLTest { private const string bucketName = "*** provide bucket name ***"; private const string objectKey = "*** provide the name for the uploaded object ***"; private const string filePath = "*** provide the full path name of the file to upload ***"; // 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); var url = GeneratePreSignedURL(timeoutDuration); UploadObject(url); } private static void UploadObject(string url) { HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest; httpRequest.Method = "PUT"; using (Stream dataStream = httpRequest.GetRequestStream()) { var buffer = new byte[8000]; using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { int bytesRead = 0; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) { dataStream.Write(buffer, 0, bytesRead); } } } HttpWebResponse response = httpRequest.GetResponse() as HttpWebResponse; } private static string GeneratePreSignedURL(double duration) { var request = new GetPreSignedUrlRequest { BucketName = bucketName, Key = objectKey, Verb = HttpVerb.PUT, Expires = DateTime.UtcNow.AddHours(duration) }; string url = s3Client.GetPreSignedURL(request); return url; } } }
Ruby

As tarefas a seguir orientam como usar um script do Ruby para fazer upload de um objeto usando um pre-signed URL para SDK para Ruby – Versão 3.

1

Crie uma instância da classe Aws::S3::Resource.

2

Forneça um nome de bucket e uma chave de objeto chamando os métodos #bucket[] e #object[] da instância da classe Aws::S3::Resource.

Gere um pre-signed URL criando uma instância da classe URI e use-a para analisar o método .presigned_url da instância da classe Aws::S3::Resource. Você deve especificar :put como um argumento para .presigned_url e especificar PUT como Net::HTTP::Session#send_request se quiser fazer upload de um objeto.

3

Qualquer pessoa com o pre-signed URL pode fazer upload de um objeto.

O upload cria um objeto ou substitui qualquer objeto existente pela mesma chave especificada no pre-signed URL.

O exemplo de código do Ruby a seguir demonstra as tarefas precedentes para o SDK para Ruby – Versão 3.

require 'aws-sdk-s3' require 'net/http' # Uploads an object to a bucket in Amazon Simple Storage Service (Amazon S3) # by using a presigned URL. # # Prerequisites: # # - An S3 bucket. # - An object in the bucket to upload content to. # # @param s3_client [Aws::S3::Resource] An initialized S3 resource. # @param bucket_name [String] The name of the bucket. # @param object_key [String] The name of the object. # @param object_content [String] The content to upload to the object. # @param http_client [Net::HTTP] An initialized HTTP client. # This is especially useful for testing with mock HTTP clients. # If not specified, a default HTTP client is created. # @return [Boolean] true if the object was uploaded; otherwise, false. # @example # exit 1 unless object_uploaded_to_presigned_url?( # Aws::S3::Resource.new(region: 'us-east-1'), # 'doc-example-bucket', # 'my-file.txt', # 'This is the content of my-file.txt' # ) def object_uploaded_to_presigned_url?( s3_resource, bucket_name, object_key, object_content, http_client = nil ) object = s3_resource.bucket(bucket_name).object(object_key) url = URI.parse(object.presigned_url(:put)) if http_client.nil? Net::HTTP.start(url.host) do |http| http.send_request( 'PUT', url.request_uri, object_content, 'content-type' => '' ) end else http_client.start(url.host) do |http| http.send_request( 'PUT', url.request_uri, object_content, 'content-type' => '' ) end end content = object.get.body puts "The presigned URL for the object '#{object_key}' in the bucket " \ "'#{bucket_name}' is:\n\n" puts url puts "\nUsing this presigned URL to get the content that " \ "was just uploaded to this object, the object\'s content is:\n\n" puts content.read return true rescue StandardError => e puts "Error uploading to presigned URL: #{e.message}" return false end