Trabalhando com Amazon Web Services S3
Criando Buckets, pastas, upload e download de arquivos via .Net Framework
Ter uma interface em sua aplicação (seja web ou desktop) que possibilita o armazenamento de arquivos na AWS S3,
se torna mais usual (e seguro) do que gerenciar usuários via IAM e disponibilizar acessos ao console.aws.
Em resumo... os usuários acessam a sua aplicação, e a sua aplicação que acessa o S3.
Sendo assim, criaremos um console em .Net Framework (ou .Net core), na qual irá:
- Criar 5 arquivos no diretório Documentos no Windows
- Instanciar conexão ao S3
- Criar 1 Bucket
- Realizar o upload dos arquivos
- Listar todos os Buckets criados
- Listar arquivos do Bucket
- Fazer o download do arquivo, e acessando via URL
Código-fonte:
using System;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.SecurityToken;
using System.Diagnostics;
namespace ConsoleAws
{
class Program
{
private static string DIRETORIO_DOCUMENTOS =
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
+ @"\Documents\";
private static string CHAVE_ACESSO = "COLOQUE O SEU ACCESS KEY AQUI";
private static string CHAVE_ACESSO_SECRETA = "COLOQUE A SUA SECRET KEY AQUI";
private static RegionEndpoint REGION = RegionEndpoint.SAEast1;
private List<string> Arquivos { get; set; }
private AmazonS3Client Client { get; set; }
private string Bucket { get; set; }
static void Main(string[] args)
{
Program program = new Program();
program.Inicializar();
}
private void Inicializar()
{
this.CriarArquivos();
this.Conectar();
this.CriarBucket();
this.Upload();
this.ListarBuckets();
}
/// <summary>
/// Faz a criação de 5 arquivos no diretório Documentos do usuário
/// </summary>
/// <returns></returns>
private void CriarArquivos()
{
Console.WriteLine("Criando os arquivos abaixo no diretório "
+ DIRETORIO_DOCUMENTOS + "...");
string[] rand = { "gato", "cachorro", "macaco", "tartaruga", "canario" };
string arquivo = null;
this.Arquivos = new List<string>();
for (int i = 0; i < 5; i++)
{
arquivo = rand[i] + "teste-amazon-s3.txt";
Console.Write(arquivo);
File.WriteAllText(DIRETORIO_DOCUMENTOS + arquivo,
"Exemplo de arquivo armazenado na Amazon S3");
Arquivos.Add(arquivo);
Thread.Sleep(500);
Console.WriteLine("\t\tSucesso!");
}
Thread.Sleep(2000);
}
private void Conectar()
{
Console.WriteLine("\n\nConectando ao Amazon S3...");
Thread.Sleep(2000);
BasicAWSCredentials credentials = new BasicAWSCredentials(CHAVE_ACESSO,
CHAVE_ACESSO_SECRETA);
this.Client = new AmazonS3Client(credentials, REGION);
Console.WriteLine("Conexão realizada com sucesso!");
Thread.Sleep(3000);
}
private void CriarBucket()
{
this.Bucket = "meu-bucket" + DateTime.Now.ToString("yyyyMMddHHmmss");
Console.WriteLine("\n\nCriando o bucket " + this.Bucket + "...");
Thread.Sleep(2000);
PutBucketRequest request = new PutBucketRequest();
request.CannedACL = S3CannedACL.Private;
PutBucketResponse response = new PutBucketResponse();
request.BucketName = this.Bucket;
response = Client.PutBucket(request);
Console.WriteLine("Bucket criado com sucesso!");
Thread.Sleep(2000);
}
private void Upload()
{
Console.WriteLine("\n\nEfetuando o upload dos arquivos abaixo...");
Thread.Sleep(2000);
for (int i = 0; i < Arquivos.Count; i++)
{
UploadPartRequest request = new UploadPartRequest
{
BucketName = this.Bucket,
FilePath = DIRETORIO_DOCUMENTOS + Arquivos[i],
Key = Arquivos[i].Substring(0, 1) + "/" + Arquivos[i]
};
Console.Write(Arquivos[i]);
UploadPartResponse response = this.Client.UploadPart(request);
//Habilita o acesso do arquivo via url
this.Client.PutACL(new PutACLRequest
{
BucketName = this.Bucket,
Key = Arquivos[i].Substring(0, 1) + "/" + Arquivos[i],
CannedACL = S3CannedACL.PublicRead
});
Console.WriteLine("\t\tSucesso!");
Thread.Sleep(500);
}
Thread.Sleep(2500);
}
private void ListarBuckets()
{
Console.WriteLine("\n\nRecuperando a lista de Buckets ...");
Thread.Sleep(1000);
ListBucketsResponse response = null;
response = Client.ListBuckets();
int i = 1;
foreach (S3Bucket bucket in response.Buckets)
{
Console.WriteLine("# " + i + "\t" + bucket.BucketName);
i++;
}
try
{
Console.Write("Informe o ID do Bucket que deseja listar os arquivos: ");
Thread.Sleep(500);
int id = Convert.ToInt32(Console.ReadLine());
this.ListarArquivos(response.Buckets[id - 1].BucketName);
}
catch (Exception ex)
{
Console.WriteLine("ID inválido:");
Thread.Sleep(500);
this.ListarBuckets();
return;
}
}
private void ListarArquivos(string bucket)
{
Console.WriteLine("\n\nListando arquivos do Bucket " + bucket + "...");
Thread.Sleep(2000);
ListObjectsRequest request = new ListObjectsRequest();
request.BucketName = bucket;
ListObjectsResponse response = Client.ListObjects(request);
int i = 1;
foreach (S3Object obj in response.S3Objects)
{
Console.WriteLine("# " + i + "\t" + obj.Key);
i++;
}
Console.Write("Informe o ID do arquivo que deseja acessar: ");
try
{
int id = Convert.ToInt32(Console.ReadLine());
this.AcessarArquivo(response.S3Objects[id - 1]);
}
catch (Exception ex)
{
Console.WriteLine("ID inválido:");
Thread.Sleep(500);
this.ListarArquivos(bucket);
return;
}
}
private void AcessarArquivo(S3Object obj)
{
Console.WriteLine("\n\nComo deseja abrir o arquivo " + obj.Key + " ?");
Console.WriteLine("# 1 \t Download");
Console.WriteLine("# 2 \t Abrir no navegador");
try
{
int id = Convert.ToInt32(Console.ReadLine());
if (id.Equals(1))
this.Download(obj);
else if (id.Equals(2))
this.Navegar(obj);
else
throw new Exception();
}
catch
{
Console.WriteLine("Opção inválida:");
Thread.Sleep(500);
this.AcessarArquivo(obj);
return;
}
}
private void Download(S3Object obj)
{
Console.WriteLine("\n\nEfetuando o download do arquivo " + obj.Key);
GetObjectRequest objectRequest = new GetObjectRequest();
objectRequest.BucketName = obj.BucketName;
objectRequest.Key = obj.Key;
GetObjectResponse objectResponse = Client.GetObject(objectRequest);
objectResponse.WriteResponseStreamToFile(DIRETORIO_DOCUMENTOS
+ @"download-" + obj.Key);
Process.Start(DIRETORIO_DOCUMENTOS + @"download-" + obj.Key);
this.ListarBuckets();
}
private void Navegar(S3Object obj)
{
Console.WriteLine("\n\nAbrindo o arquivo " + obj.Key + " no navegador...");
string url = string.Format("https://{0}.s3-{1}.amazonaws.com/{2}",
obj.BucketName, REGION.SystemName, obj.Key);
Process.Start(url);
this.ListarBuckets();
}
}
}
Ao compilar o e executar o código acima, deverá exibir um console interativo conforme imagens abaixo. No final do console, você poderá fazer o download do arquivo bem como acessá-lo no navegador.


Cada vez que o console é executado, um novo Bucket é criado.

Acessando o último Bucket, podemos visualizar as pastas criadas, e dentro de cada pasta os respectivos arquivos.


Voltando ao console, na opção "Abrir no navegador", você será direcionado para o arquivo via URL.


NOTAS
Dependências / usings
É normal que na primeira compilação apresente diversos erros de referências (using Amazon...).
using Amazon; using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; using Amazon.SecurityToken;
Para corrigir, refaça as referências via NuGet das seguintes bibliotecas:
- AWSSDK.Core
- AWSSDK.S3
- AWSSDK.SecurityToken
Autenticação
As variáveis estáticas CHAVE_ACESSO e CHAVE_ACESSO_SECRETA representam as suas credenciais de segurança (IAM). É uma combinação dos 2 valores para realizar a autenticação de modo seguro.
static string CHAVE_ACESSO = "ABCDEFGHIJKLMNOPQRBRA"; static string CHAVE_ACESSO_SECRETA = "52aac6e452aaf1f5l0PnId7IJn+A2B";
Tais chaves podem ser geradas e consultadas na rota Serviços > IAM > Gerenciar Credenciais de Segurança

Região
Os Buckets foram criados na região America do Sul (São Paulo). Você poderá realizar a troca para a região desejada alterando na variável estática REGION.
static RegionEndpoint REGION = RegionEndpoint.SAEast1;
Acesso público
Os arquivos podem ser carregados na internet por qualquer pessoa que tenha a URL em mãos, representando um alto risco de segurança para informações confidenciais.

Caso queira bloquear este acesso público, comente toda a chamada do método PutACL() abaixo.
this.Client.PutACL(new PutACLRequest
{
BucketName = this.Bucket,
Key = Arquivos[i].Substring(0, 1) + "/" + Arquivos[i],
CannedACL = S3CannedACL.PublicRead
});

E assim o acesso aos arquivos via URL será bloqueado.
Enfim, o código apresentado neste artigo dá um norte em cenários onde possibilita realizar as operações básicas na AWS S3. Existem muito mais funcionalidades que podem ser exploradas no link abaixo: