Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Asp.NET Core – AWS S3 İle Dosya İşlemleri Gerçekleştirme | Upload – Download – Delete Files

Merhaba,

Bu içeriğimizde, Amazon’un nesne depolama alanı olarak sunduğu Amazon Simple Storage Service (Amazon S3)‘i kullanarak dosya yükleme, silme ve indirme operasyonlarını Asp.NET Core uygulaması eşliğinde gerçekleştirecek ve böylece Amazon S3 hakkında hem bilgi sahibi olacak hem de AWS Console, AWS CLI, Credentials Store vs. gibi yeteneklerini tecrübe etmiş olacağız. O halde buyurun başlayalım…

Amazon S3 Nedir?

İlk olarak kullanacağımız bu dev servisin ne olduğunu izah ederek başlayalım.

Amazon S3(Simple Storage Service), Amazon’un dünyaya yayılmış sunucuları sayesinde ultra yüksek kullanılabilirlik ile kişinin depolama ihtiyaçları için süper ölçeklenebilir bir nesne depolama hizmetidir. Bu depolama hizmetinin yanı sıra işletme hedeflerine en uygun şekilde çalışmalar gerçekleştirebilmeniz için depolanan veriler üzerinde optimizasyonların gerçekleştirilebilmesi, güvenceye alınabilmesi ve gerektiği taktirde organize edilebilmesi için türlü yönetimsel özellikle sunmaktadır.

Amazon S3 hakkında daha detaylı bilgi için buraya tıklayınız.

Bu içeriğe verimli bir şekilde devam edebilmek için Amazon S3’ün Buckets, Objects ve Permissions kavramları hakkında temel bilgilere sahip olunması gerekmektedir. Bunun için şimdiden küçük tanımlarda bulunmanın, içeriğimizin sonraki satırları için aydınlatıcı etkisi olacaktır kanaatindeyim;

  • Buckets; objects/nesneler’in yerleştirileceği klasörlerdir.
  • Objects; dosyaları tarif eder. Default olarak nesneler public değildir. Yani dışarıdan erişim gösterilemez. Bunun için Identity And Access Management’ı kullanarak Amazon S3 servisine tam erişim haklarına sahip bir kullanıcı oluşturup dosya erişimlerini bu kullanıcı üzerinden sağlayacağız.
  • Permissions; object’lere erişim için kullanacağımız yetkilerdir.

Bu içeriği takip edebilmeniz için ekstradan AWS hesabına ihtiyacınız olacaktır. Bunun için buraya tıklayarak oldukça basit bir şekilde kaydınızı ücretsiz yapabilir ve test amaçlı S3 servislerini kullanabilmek için 12 ay boyunca 5 GB’a kadar veriyle çalışma şansını elde edebilirsiniz.

Şimdi gelin adım adım kâh AWS ortamını konfigüre ederek, kâh Asp.NET Core uygulamasını geliştirerek ilerlemeye başlayalım.

AWS IAM Aracılığıyla Kullanıcı Oluşturma ve Access Key Generate Etme

Her şeyden önce ilk gereksinim olarak Asp.NET Core uygulaması ile AWS S3’e erişebilmek için gerekli güvenlik işlemlerini gerçekleştirmekte fayda görmekteyim.

IAM(Identity and Access Management), AWS kaynaklarına erişimi güvenli bir şekilde kontrol etmemize yardımcı olan bir servistir. Açılan oturumları, kaynakları kullanmak için yetkilendirilen kullanıcıları vs. denetlememizi sağlamaktadır.

Bu servisi kullanabilmek için AWS Console’da aşağıdaki gibi ‘IAM’ araması yapınız ve ardından gelen IAM servisini açınız.Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeŞimdi gayemiz AWS S3 servisini kullanabilecek tam erişim haklarına sahip yeni bir kullanıcı oluşturmaktır. Bunun için sol menüdeki ‘Users’ sekmesine ve hemen ardından sağdaki mavi ‘Add users’ butonuna tıklayınız.
Bir sonraki açılan formda kullanıcı adınızı belirleyiniz ve aşağıdaki ekran görüntüsünde olduğu gibi ‘Access key – Programmatic access‘ kutucuğunu seçtiğinizden emin olunuz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeBu işlemden sonra sağ alt köşedeki mavi ‘Next: Permissions’ butonuna tıklayınız.
Tabi akabinde bu oluşturulacak kullanıcıya politikalar/izinler atanmalıdır. Bunun için mevcut politikalardan istifade edebiliriz. Bu işlem için aşağıdaki gibi ‘Attach existing policies directly’ sekmesine tıklayınız ve ‘s3’ araması yaparak ‘AmazonS3FullAccess’ politikasını ekleyiniz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirmeİsterseniz bu politikanın dışında daha fazlasını kullanıcıyla ilişkilendirebilirsiniz. Ancak bu içeriğimiz için bu politikanın eklenmesi yeterli olacaktır.

Bir sonraki ekranda ise kullanıcıya etiket ekleme seçeneği sunulmaktadır. Genellikle kullanıcı faturalandırma ve izleme amaçlı bu etiketleri kullanabilirsiniz. Lakin şimdilik bu adımı herhangi bir konfigürasyon yapmaksızın atlayabilirsiniz.Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeTüm bu yapılandırmalardan sonra ‘Create user’ butonuna tıklayınız. İşte bu kadar… Artık Amazon S3 için yeni bir kullanıcı oluşturulmuştur.

Şunu da unutmamak lazım ki, güvenlik için oluşturulan CSV dosyasını aşağıdaki gibi indirdiğinizden emin olun derim. Bu dosyada oluşturduğunuz kullanıcıya dair Access Key Id ve Secret Access Key değerleriniz mevcuttur. Bu ayrıntılara daha sonra kodumuzu AWS S3 Service ile entegrasyon gerçekleştirme sürecinde ihtiyacımız olacaktır.
Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirme

AWS Console Aracılığıyla AWS S3 Bucket Oluşturma

Şimdi oluşturduğumuz kullanıcıyla bir bucket oluşturalım ve böylece bir nebze olsun AWS S3 Console’u keşfetmiş olalım. Bunun için aşağıdaki ekran görüntüsünde olduğu gibi arama çubuğuna ‘S3’ yazıp aratınız ve ilgili servisi açınız. Devamında ise sağ taraftaki turuncu ‘Create bucket’ butonuna tıklayınız.Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirme
Bucket tanımlarken özellikle adının global olarak unique olmasına özen gösterilmelidir. Ayrıca dosyalarınızın aktarım sürecini optimize edebilmek için size en yakın bölgeyi seçmenizde fayda vardır.İlgili sayfada biraz aşağı inerseniz Block Public Access settings for this bucket kısmını görebilirsiniz. Varsayılan olarak AWS, bucket’lara karşı her türlü erişimi engellemektedir. Buradaki erişimle alakalı URL ile ilgili işlemlerin nasıl yapılacağını makalemizin devamında görüyor olacağız. Şimdilik böyle devam edebiliriz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeSayfada biraz daha inince etiketlerle ilgili konfigürasyonları göreceksiniz. İsteğe bağlı olduğu için es geçebilirsiniz.
Netice itibariyle en son turuncu olan ‘Create bucket’ butonuna tıklayarak bucket oluşturabilirsiniz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirme
Aşağıdaki ekran görüntüsünü incelerseniz eğer bucket’ı oluşturduktan sonra test amaçlı bir dosya yükleme işlemi gerçekleştirmekteyiz. Böylece sağlıklı bir şekilde çalışma sergilediğini gözlemlemekteyiz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirme

AWS CLI Yükleme ve Konfigürasyonlarını Gerçekleştirme

Önceki satırlarda AWS’den secret key’leri almıştık. Şimdi ise bu secret key’ler üzerinden işlem yapabilmek için temel konfigürasyonel tanımlamalarda bulunuyor olacağız. .NET uygulamaları için bu tarz değerlerin appsettings.json veya secret.json gibi dosyalarda depolandığını bildiğinizi biliyorum. Lakin bilmenizi istiyorum ki AWS CLI, bu tarz secret key’leri ve kimlik bilgilerini depolayabilmemiz için daha güvenli olan AWS Local Storage‘ı sunmaktadır.

Tabi AWS CLI’ı kullanabilmek için ilk olarak bilgisayarınıza kurmanız gerekmektedir. Bunun için şuradan işletim sisteminize özel indirme işlemini gerçekleştirebilirsiniz.

AWS CLI’ı bilgisayarınıza kurduktan sonra çalışıp çalışmadığını test etmek için cmd üzerinden aws --version talimatını vermeniz yeterlidir.
Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeYukarıdaki ekran görüntüsünde olduğu gibi cevap alıyorsanız eğer başarılısınız…

Şimdi kimlik bilgilerini ve diğer yapılandırma öğelerini barındırmak ve okuyabilmek için yeni bir AWS Local Configuration Profile oluşturalım. Bunun için de cmd üzerinden aşağıdaki talimatın verilmesi yeterlidir.
aws configure --profile "my-profile"
Bu talimatı verdikten sonra AWS CLI bizden Access Key ve Secret Key’leri aşağıdaki gibi istenecektir.
Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeBu değerlerin arasında ‘default region name’e karşılık S3 Bucket’i oluştururken seçtiğimiz bölge adıyla birebir aynı değeri verdiğinizden emin olunuz.

Velhasıl, netice itibariyle AWS CLI üzerinden AWS Local Storage’a konfigürasyonel değerlerimizi bu şekilde yerleştirdikten sonra C:\Users\name\.aws dizininde aşağıdaki gibi dosyaların oluşturulduğunu ve içlerine verilerin depolandırıldığını göreceksiniz.Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeHatta dilerseniz bu dosyaları not defterinde açıp aşağıdaki gibi de inceleyebilirsiniz.
Asp.NET Core - AWS S3 İle Dosya İşlemleri Gerçekleştirme
Ve böylece nihai olarak çalışmamızın AWS S3 ayağını bitirdik diyebiliriz. Şimdi sıra Asp.NET Core tarafında…

Asp.NET Core Web API Uygulamasının Oluşturulması ve Temel Konfigürasyonlarının Yapılması

Uygulamayı örneklendirebilmek için yeni bir Asp.NET Core Web API projesi açınız ve hemen ‘appsettings.json’ dosyasına yukarıdaki satırlarda edindiğimiz profil ve bölge değerlerini konfigürasyonel veriler olarak aşağıdaki gibi ekleyiniz.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AWS": {
    "Profile": "my-profile",
    "Region": "ap-south-1"
  }
}

Bu işlemden sonra AWS S3 servislerinin işlevini daha efektif bir şekilde gerçekleştirebilmek için aşağıdaki SDK kütüphanelerini uygulamaya yükleyiniz.

Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeArdından AWS servisini .NET uygulamasının IoC Container’ına aşağıdaki gibi ekleyiniz.

.
.
.
builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions());
builder.Services.AddAWSService<IAmazonS3>();

var app = builder.Build();
.
.
.

Bu çalışmayla, ‘appsettings.json’ dosyasındaki konfigürasyonel değerleri runtime’da kullanabilmek için cache’e yüklemiş oluyoruz. Burada özellikle 5. satıra dikkat ederseniz eğer S3 servisini IAmazonS3 interface’i ile pipeline’a ekleyerek, Bucket ve Objects için gerekli nesneleri bu arayüz eşliğinde dependency injection ile talep edilebilir bir hale getiriyoruz.

.NET AWS SDK Eşliğinde AWS S3 Bucket İşlemleri

İçeriğimizin önceki satırlarında AWS Console üzerinden bucket oluşturmuştuk. Şimdi ise aynı işlemi API uygulaması aracılığıyla gerçekleştireceğiz. Bunun için ‘BucketsController’ isminde bir controller sınıfı oluşturunuz ve IAmazonS3 arayüzünü aşağıdaki gibi IoC Container’dan inject ediniz.

    [Route("api/[controller]")]
    [ApiController]
    public class BucketsController : ControllerBase
    {
        readonly IAmazonS3 _amazonS3;

        public BucketsController(IAmazonS3 amazonS3)
        {
            _amazonS3 = amazonS3;
        }
    }

Ardından bucket oluşturma sorumluluğuna sahip aşağıdaki action’ı tanımlayınız.

    public class BucketsController : ControllerBase
    {
        .
        .
        .

        [HttpPost]
        public async Task<IActionResult> CreateBucketAsync(string bucketName)
        {
            bool bucketExists = await _amazonS3.DoesS3BucketExistAsync(bucketName);
            if (bucketExists)
                return BadRequest($"Bucket {bucketName} already exist.");
            await _amazonS3.PutBucketAsync(bucketName);
            return Ok($"Bucket {bucketName} created.");
        }
    }

Bu action’a aşağıdaki gibi gönderilen post isteği neticesinde bucket’ın oluşturulduğunu gözlemliyor olacağız.
Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeAsp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeŞimdide mevcut olan tüm bucket’ları listelemesini gerçekleştirelim;

        [HttpGet]
        public async Task<IActionResult> GetAllBucketsAsync()
        {
            ListBucketsResponse bucketDatas = await _amazonS3.ListBucketsAsync();
            return Ok(bucketDatas);
        }

Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeAyriyeten bucket silmek için de aşağıdaki gibi bir action’da oluşturabilirsiniz:

        [HttpDelete("{bucketName}")]
        public async Task<IActionResult> DeleteBucketAsync(string bucketName)
        {
            await _amazonS3.DeleteBucketAsync(bucketName);
            return NoContent();
        }

Asp.NET Core Uygulamasından AWS S3 Servislerinde Dosya İşlemleri

Artık konumuzun ana temasına gelmiş bulunuyoruz. AWS S3 servislerinde kullanıcı oluşturma, access key generate etme, cli yükleme ve bucket oluşturma gibi gerekli olan temel çalışmaları gerçekleştirdikten sonra artık AWS S3 servisleri üzerinde dosya işlemlerini ele almaya başlayabiliriz.

Dosya işlemlerinden kastettiğimizin; yükleme, silme, listeleme ve indirme operasyonları olduğunu bilmenizi isterim. Bunun için, bu sorumlulukları üstlenecek ‘FilesController’ adında bir controller sınıfı oluşturunuz ve içeriğine aşağıdaki işlemleri gerçekleştiriniz.

İlk olarak upload operasyonunu inşa edelim.

    [Route("api/[controller]")]
    [ApiController]
    public class FilesController : ControllerBase
    {
        readonly IAmazonS3 _amazonS3;

        public FilesController(IAmazonS3 amazonS3)
        {
            _amazonS3 = amazonS3;
        }

        [HttpPost]
        public async Task<IActionResult> UploadFileAsync(IFormFile file, string bucketName, string? prefix)
        {
            bool bucketExists = await _amazonS3.DoesS3BucketExistAsync(bucketName);
            if (!bucketExists)
                return NotFound($"Bucket {bucketName} does not exist.");
            PutObjectRequest request = new()
            {
                BucketName = bucketName,
                Key = String.IsNullOrEmpty(prefix) ? file.FileName : $"{prefix?.TrimEnd('/')}/{file.FileName}",
                InputStream = file.OpenReadStream()
            };
            request.Metadata.Add("Content-Type", file.ContentType);
            await _amazonS3.PutObjectAsync(request);
            return Ok($"File {prefix}/{file.FileName} uploaded to S3 successfully!");
        }
    }

Yukarıdaki UploadFileAsync action’ına göz atarsanız eğer dosya bilgileri(IFormFile) eşliğinde, bucket name ve opsiyonel olarak klasör adı(prefix) almaktadır. İşlevsel olarak, AWS S3 hesabında bucket var mı yok mu kontrol edilmekte ve eğer varsa request hazırlanıp dosya transferi gerçekleştirilmektedir. 24. satırda ise bir Metadata örneklendirmesi gerçekleştirilmiştir. Metadata, yüklenecek dosyalara özel farklı özellikleri ifade etmektedir.

Velhasıl… Uygulamayı derleyip, çalıştırdığınızda aşağıdaki gibi test ederek dosya yüklemeyi deneyebilirsiniz.Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeDosya yükleme işleminden sonra AWS S3’de ki bucket’ınıza gidip yüklemenin başarıyla gerçekleşip gerçekleşmediğini de aşağıdaki gibi gözlemleyerek doğrulayabilirsiniz.Asp.NET Core - AWS S3 İle Dosya İşlemleri GerçekleştirmeŞimdi ise bucket’ta bulunan dosyaları listelemeyi ele alalım.

Tabi bunun için öncelikle listelenecek nesnelerin bilgilerini karşılayacak bir DTO oluşturarak başlayalım.

    public class S3ObjectDTO
    {
        public string Name { get; set; }
        public string Url { get; set; }
    }

Yukarıdaki DTO nesnesine bakarsanız eğer dosya adı ve url bilgilerini edinmemiz şimdilik yeterli gözükmektedir. Bu adımdan sonra ‘FileController’ içersinde aşağıdaki action’ı geliştiriniz.

        [HttpGet]
        public async Task<IActionResult> GetAllFilesAsync(string bucketName, string? prefix)
        {
            bool bucketExists = await _amazonS3.DoesS3BucketExistAsync(bucketName);
            if (!bucketExists)
                return NotFound($"Bucket {bucketName} does not exist.");
            ListObjectsV2Request request = new()
            {
                BucketName = bucketName,
                Prefix = prefix
            };
            ListObjectsV2Response response = await _amazonS3.ListObjectsV2Async(request);
            List<S3ObjectDTO> objectDatas = response.S3Objects.Select(@object =>
             {
                 GetPreSignedUrlRequest urlRequest = new()
                 {
                     BucketName = bucketName,
                     Key = @object.Key,
                     Expires = DateTime.UtcNow.AddMinutes(1)
                 };
                 return new S3ObjectDTO
                 {
                     Name = @object.Key,
                     Url = _amazonS3.GetPreSignedURL(urlRequest)
                 };
             }).ToList();
            return Ok(objectDatas);
        }

Bu geliştirmeden sonra uygulamayı derleyip, çalıştırınız ve ilgili endpoint’i test ediniz.Ekran görüntüsü 2022-11-06 132513Burada özellikle dikkat etmenizi istediğim bir husus vardır ki; o da, 15 ile 25. satır aralığında üretilen Pre Signed URL‘lerdir. AWS S3 servisleri, bucket’a yüklenen dosyaların güvenliği konusunda garanti sunduğunu ve erişim konusunda yetkilendirme gerektirdiğini biliyoruz. Lakin, dosyaları müşteriler tarafından önizlenebilmesi için belirli bir süreliğine dışarı açmamızı sağlayan ve süresi dolduğunda erişimi engelleyen Pre Signed URL ismini verdiğimiz adresler geliştirmemize de imkan sağlamaktadır. 19. satırda oluşturulan bu bağlantının yaşam süresini istediğimiz gibi sınırlandırabildiğimize dikkatinizi çekerim.

Erişim süresi dolan dosyaların url’lerine istek gönderdiğinizde sizleri aşağıdaki gibi bir sayfa karşılayacaktır.Ekran görüntüsü 2022-11-06 132513Şimdi dosya silme işlemine odaklanalım.

Bu işlem aşağıdaki gibi oldukça basittir.

        [HttpDelete("{bucketName}/{fileName}")]
        public async Task<IActionResult> DeleteFileAsync(string bucketName, string fileName)
        {
            bool bucketExists = await _amazonS3.DoesS3BucketExistAsync(bucketName);
            if (!bucketExists)
                return NotFound($"Bucket {bucketName} does not exist.");
            await _amazonS3.DeleteObjectAsync(bucketName, fileName);
            return NoContent();
        }

Ve son olarak yüklenmiş dosyaları nasıl indirebileceğimizi(download) inceleyelim.

Bu işlem için de aşağıdaki gibi stream operasyonu yürütebilirsiniz.

        [HttpGet("download/{bucketName}/{fileName}")]
        public async Task<IActionResult> GetFileByNameAsync(string bucketName, string fileName)
        {
            bool bucketExists = await _amazonS3.DoesS3BucketExistAsync(bucketName);
            if (!bucketExists)
                return NotFound($"Bucket {bucketName} does not exist.");
            GetObjectResponse response = await _amazonS3.GetObjectAsync(bucketName, fileName);
            return File(response.ResponseStream, response.Headers.ContentType);
        }

Nihai olarak,
Bu içeriğimizde, Asp.NET Core mimarisinde AWS S3 servisleri eşliğinde dosya işlemleri üzerine bir tecrübe kazanmış bulunuyoruz. Üşenmeden eşlik ettiğiniz için teşekkür ederim.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmayı aşağıdaki github adresinden edinebilirsiniz.
https://github.com/gncyyldz/AWSS3.Example

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. S dedi ki:

    Emeğinize sağlık hocam

  1. 08 Aralık 2022

    […] servisine gidiniz ve bir kullanıcı oluşturunuz. Eğer konuya dair pek bilginiz yoksa önceden AWS S3 konusunda klavyeye almış olduğum makaleden konuyla alakalı bölümü okuyarak detaylı bilgi […]

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir