Asp.NET Core Identity – Identity Altyapısı Kurulumu – II

Merhaba,

Bir önceki Asp.NET Core Identity – Nedir ve Temel Kavramlar? – I başlıklı içeriğimizde Asp.NET Core Identity kütüphanesine dair teorik olarak bir giriş yapmıştık. Bu içeriğimizde ise bir Asp.NET Core uygulamasında Identity alt yapısının nasıl kurulduğunu inceleyeceğiz.

Herşeyden önce Asp.NET Core Identity kütüphanesini bir projeye entegre ederken olayı hem kütüphane hem de veritabanı açısından değerlendirmemiz gerekmektedir. Kütüphane açısından Microsoft.AspNetCore.Identity kütüphanesinin projeye yüklenmiş olması gerektiğini ve Asp.NET Core uygulamalarında ilgili kütüphanenin dahili olarak geldiğini bu yüzden ekstradan işlem yapmamıza gerek kalmadığını yukarıda adresini verdiğimiz önceki makalemizde belirtmiştik.

Veritabanı açısından ise Asp.NET Core Identity kütüphanesi projeye entegre edeceği üyelik sistemiyle alakadar bir veritabanı düzeni getirmektedir. Üye bilgilerini, rolleri, tanımlamaları, token değerlerini, gerekli cross table görevi üstlenen ara tabloları vs. tüm değerleri tutacağı bir yapılanma beklemektedir. Dolayısıyla bu veritabanı karşılığını manuel bir şekilde oluşturmamız mümkün olsa dahi, fıtrat olarak Asp.NET Core Identity yapılanması en güncel ve dinamik veritabanı yaklaşımı olan Code First ile tam bir uyumluluk sergilemekte ve birazdan içeriğimizde ele alacağımız inşa neticesinde yapılan ve modellenen Identity çalışması neticesinde veritabanına uygun tabloları migrate edecek ve bizi manuel yapılanmanın getireceği olası hatalardan net bir şekilde arındırmış olacaktır.

Asp.NET Core Identity, ORM sistemi olan Entity Framework kütüphanesinin Code First yaklaşımıyla %100 uyumlu bir mimaridir.

Proje Alt Yapısı

İlk olarak “Empty” olacak şekilde bir Asp.NET Core uygulaması başlatılarak “Startup.cs” sınıfında aşağıdaki geliştirmeler yapılmalıdır.

    public class Startup
    {
        public IConfiguration Configuration { get; set; }
        public Startup(IConfiguration configuration) => Configuration = configuration;
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();

            app.UseStatusCodePages();
            app.UseStaticFiles();
            app.UseMvc(_ => _.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"));
        }
    }

Şuanda “Startup.cs” sınıfımız olması gereken en sade şekliyle ayarlanmıştır. Birazdan Identity yapılanması inşa edilecek ve gerekli authenticaion yapılanması tekrar bu sınıf üzerinden modifiye edilecektir.

En Temel Identity Sınıfları

Asp.NET Core Identity kütüphanesinde en temel aktörlerimiz “IdentityUser” ve “IdentityRole” sınıflarıdır. En nihayetinde üyelik sistemi olan Identity mimarisi, bir kullanıcıyı genel geçer modelleyen ve o kullanıcıya dair rolleri tanımlayan bu iki sınıf ile bizlere eşlik edecektir.

IdentityUser IdentityRole
Sistem üzerinde kullanıcıları temsil eden sınıftır.
Asp.NET Core Identity – Alt Yapı Kurulumu - II
Yukarıdaki ekran alıntısında görüldüğü üzere içerisinde UserName, Email vs. gibi bir kullanıcıya dair genel geçer bilgileri barındırmaktadır.
Peki nasıl kullanılır?
Uygulamamızdaki kullanıcıları temsil edecek ve biryandan da modelleyecek olan “AppUser”(istediğiniz ismi verebilirsiniz) ismini verdiğimiz bir sınıf tasarlayacağız. İşte bu sınıf IdentityUser sınıfından türetilecektir. Yazımızın ileriki satırlarında ele alacağımız bu operasyon neticesinde “AppUser” sınıfı IdentityUser sınıfından gerekli propertyleri kalıtım aracılığıyla miras edinecektir. Neticede aldığı kalıtım ile tasarlanmış olan “AppUser” sınıfını Code First ile migrate ettiğimizde mirastan gelen ilgili propertyler kolon olarak oluşturulacaktır. Bu hazır propertyler dışında ihtiyacımıza dönük tüm custom propertyleri “AppUser” sınıfına oluşturarak migrate neticesindeki veritabanına eklenebilecektir.
Kullanıcının rollerini tanımlayan sınıftır. Bir rolle ilişkili tüm verileri barındırmaktadır.
Peki nasıl kullanılır?
İhtiyaç doğrultusunda “AppUserRole”(istediğiniz ismi verebilirsiniz) isminde bir sınıf oluşturacağız. Bu sınıfın IdentityRole sınıfında türetilmesi yeterlidir. Eğer ki özel kolonlara ihtiyacımız olursa, “AppUserRole” sınıfına eklenen propertyler sayesinde o kolonlar oluşturulmuş olacak ve migrate neticesinde veritabanına yansıtılacaktır.

Temel sınıflarımızıda tanıdıktan sonra şimdi sıra Identity mimarisini uygulamada ayağa kaldırmaya geldi…

Adım 1

Projede “Models” isimli klasör oluşturalım ve içerisine “Authentication” isminde bir klasör daha oluşturalım. Bundan sonraki tüm yapılanmalar en son oluşturulan bu “Authentication” isimli klasör içerisinde gerçekleştirilecektir.

Şimdi ilk olarak kullanıcılarımızı temsil edecek olan sınıfımızı tasarlayalım. Bu sınıfımızın adı istediğiniz herhangi bir değerde olabilir. Ben burada örnek amaçlı “AppUser” ismini veriyorum.

    public class AppUser : IdentityUser
    {
    }

Görüldüğü üzere “AppUser” sınıfı oluşturulmuş ve hemen akabinde “IdentityUser” sınıfında türetilmiştir. Böylece bu sınıf uygulamada tüm kullanıcılarımıza model olabilecektir. Şimdilik bu sınıfa herhangi bir custom property girmiyorum. İlerleyen makalelerde custom property girildiği taktirde nasıl bir fark yarattığına dair mukayesede bulunacağız…

Adım 2

Bu içeriğimizdeki esas gayemiz basit bir Identity mekanizmasını ayağa kaldırabilmektir. Bundan dolayı kullanıcıları temsil eden bir sınıfın olması bizim için yeterlidir lakin yukarıda bahsedilen IdentityRole sınıfından türeyen ve sistemdeki rolleri tanımlayan bir sınıf inşa etmemize şimdilik gerek yoktur. Merak etmeyin, ilerleyen makalelerde a’dan z’ye herşeyi, en doğru şekilde incelemiş olacaksınız 🙂

Artık bu noktaya kadar elimizde kullanıcıları modelleyen bir “AppUser” sınıfı mevcuttur. Dolayısıyla şimdi yapmamız gereken Code First yaklaşımıyla üretilecek/migrate edilecek olan veritabanımızın bir karşılığı olan DbContext sınıfını üretmektir. Bunun için “Models” klasörü altında “Context” isimli bir klasör oluşturalım ve içerisinde “AppDbContext” isminde bir sınıf üretelim.

    public class AppDbContext : IdentityDbContext<AppUser>
    {
        public AppDbContext(DbContextOptions<AppDbContext> dbContext) : base(dbContext) { }
    }

Yukarıdaki kod bloğunu incelerseniz eğer oluşturulan context sınıfı normalde “DbContext” sınıfından türetilmesi gerekiyordu. Lakin biz sistemimizde Identity kullandığımızdan dolayı bu identity yapısının karşılığını veritabanında oluşturtmamız gerekmektedir ve bunu “IdentityDbContext” sınıfı ile gerçekleştirebilmekteyiz. Dolayısıyla context sınıfının hangi identity ile birlikte çalışacağını belirtebilmek için “IdentityDbContext” sınıfından türetilmektedir. Ve dikkat edilirse generic olarak bu identity yapılanmasının tarafımızca oluşturulan “AppUser” isimli sınıf ile gerçekleştirildiğini belirtmiş oluyoruz.

Context sınıfını inşa ettikten sonra migrate işlemi neticesinde hedef sunucu providerını “appsettings.json” dosyasında aşağıdaki şekilde belirleyelim;

{
  "ConnectionStrings": {
    "SqlServerConnectionString": "Server=.;Database=IdentityExampleDb;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Adım 3

Artık uygulamada inşa edilen bu identity yapılanması “Startup.cs” sınıfı üzerinden uygulamaya dahil edilmelidir. Bunun için aşağıdaki çalışma yeterlidir…

    public class Startup
    {
        public IConfiguration Configuration { get; set; }
        public Startup(IConfiguration configuration) => Configuration = configuration;
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<AppDbContext>(_ => _.UseSqlServer(Configuration["ConnectionStrings:SqlServerConnectionString"]));
            services.AddIdentity<AppUser, IdentityRole>().AddEntityFrameworkStores<AppDbContext>();
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();

            app.UseStatusCodePages();
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseMvc(_ => _.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"));
        }
    }

7. satır‘da görüldüğü üzere uygulamaya geliştirdiğimiz context nesnesi DbContext olarak tanıtılmaktadır.

8. satır‘da görüldüğü üzere ise uygulamaya identity yapılanmasına dair gerekli entegrasyonu “AddIdentity” metodu ile gerçekleştirmekteyiz. Dikkat ederseniz generic olarak birinci parametreye bu identity yapılanmasının kullanacağı IdentityUser yapılanmasını istemektedir. Bunun için tarafımızdan “AppUser” sınıfı verilmiştir. Lakin ikinci parametreye ise tarafımızca herhangi bir IdentityRole sınıfından türeyen sınıf inşa edilmediğinden dolayı direkt olarak “IdentityRole” sınıfı verilmiştir. Yani anlayacağınız temelde biz sadece IdentityUser sınıfından türeyen “AppUser” sınıfını inşa ederek en temel üyelik yönetimi yapılanmasını gerçekleştirmiş bulunmaktayız. Buradaki işlem neticesinde “AddEntityFrameworkStores” generic metodu sayesinde “AppDbContext” isminde oluşturduğumuz contexte özel depolama gerçekleştirmiş bulunmaktayız.

Ayrıca 19. satır‘da “UseAuthentication” metodu sayesinde uygulamanın identity ile kimlik doğrulaması gerçekleştireceğini belirtmiş bulunmaktayız.

Evet…

Bu işlemler neticesinde artık uygulamamızda bir Identity altyapısı mevcut hale getirilmiştir. Şimdi Code First yaklaşımı ile migrationları oluşturup veritabanımızı sunucuya migrate edelim. Asp.NET Core uygulamalarında migration işlemlerini tam teferruatlı inceleyebilmek için Asp.NET Core 2 MVC’de Migrations İle Veritabanı İşlemleri başlıklı makaleye göz atabilirsiniz.

dotnet ef migrations add mig_1
dotnet ef database update

Asp.NET Core Identity – Alt Yapı Kurulumu - II
Bu işlem neticesinde migrate edilen veritabanı ve oluşturulan tabloları aşağıdaki görselde olduğu gibidir;
Asp.NET Core Identity – Alt Yapı Kurulumu - II

Netice olarak; bu içeriğimizde sadece üyeleri temsil edecek olan sınıfı inşa ederek IdentityDbContext nesnesi oluşturmayı, Startup sınıfına Identity mimarisini entegre ederek projeye tüm bu yapılanmayla ayağa kaldırmayı incelemiş olduk. Yani uzun lafın kısası bir projede en sade haliyle Identity mimarisinin nasıl kurulduğunu görmüş olduk.

Sonraki makalemizde ise neticede oluşturulan veritabanında Identity mimarisine özel tabloları inceleyeceğiz. O halde şimdilik görüşmek üzere…

İlgilenenlerin faydalanması dileğiyle…
İyi çalışmalar…

Not : Örnek projeyi indirmek için buraya tıklayınız.

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. 10 Ağustos 2019

    […] Asp.NET Core Identity – Identity Alt Yapısı Kurulumu – II […]

  2. 11 Ağustos 2019

    […] önceki Asp.NET Core Identity – Identity Altyapısı Kurulumu – II başlıklı makalede Asp.NET Core uygulamalarında Identity altyapısının nasıl kurulduğunu […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir