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: