Asp.NET Core Identity – Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü – VI

Merhaba,

Asp.NET Core Identity yazı dizimizin 6. makalesinde, kullanıcı üye olurken varsayılan şifre validasyon ayarlarının değiştirilmesini ve bunun yanında IPasswordValidator arayüzü ile kendimize özel validasyon yapılanmasını oluşturmayı inceleyeceğiz.

Herşeyden önce bir önceki UserManager Sınıfı İle Kullanıcı Yönetimi başlıklı makalemizde kullanıcının UserManager sınıfını kullanarak nasıl üye olduğunu incelemiştik. İlgili makaleye göz atarsanız eğer üyelik işlemlerini “User(Controller).cs” controller sınıfındaki “SignIn” action metodunda gerçekleştirdik. İlgili metodun son halini aşağıya alıp incelersek eğer;

        [HttpPost]
        public async Task<IActionResult> SignIn(AppUserViewModel appUserViewModel)
        {
            if (ModelState.IsValid)
            {
                AppUser appUser = new AppUser
                {
                    UserName = appUserViewModel.UserName,
                    Email = appUserViewModel.Email
                };
                IdentityResult result = await _userManager.CreateAsync(appUser, appUserViewModel.Sifre);
                if (result.Succeeded)
                    return RedirectToAction("Index");
            }
            return View();
        }

Post edilen “AppUserViewModel” tipindeki viewmodel nesnemizin tüm validasyonları geçerliyse eğer 11. satırda kayıt işlemini gerçekleştiriyoruz. 12. satırda yapılan kontrol neticesinde, eğer kayıt başarılıysa kullanıcıyı “Index” actionına yönlendiriyoruz. Yok eğer kayıt geçerli değilse demek ki validasyon dışında süreçte bir hata var demektir. İşte bu hatalar kullanıcıdan gelen şifreyle alakalıdır. 11. satırda “CreateAsync” metoduna ikinci parametre olarak verilen şifre Identity mekanizmasının varsayılan validasyonlarına takılmış demektir.

Dolayısıyla varsayılan password validasyonlarına uygun olmayan şifreler girildiği taktirde “IdentityResult” bizlere hangi validasyonlar olduğuna dair “Errors” propertysi ile bilgi verecektir. Bunuda aşağıdaki gibi “ModelState” nesnesine yükleyerek son kullanıcıya hata mesajı olarak iletebiliriz.

        [HttpPost]
        public async Task<IActionResult> SignIn(AppUserViewModel appUserViewModel)
        {
            if (ModelState.IsValid)
            {
                AppUser appUser = new AppUser
                {
                    UserName = appUserViewModel.UserName,
                    Email = appUserViewModel.Email
                };
                IdentityResult result = await _userManager.CreateAsync(appUser, appUserViewModel.Sifre);
                if (result.Succeeded)
                    return RedirectToAction("Index");
                else
                    result.Errors.ToList().ForEach(e => ModelState.AddModelError(e.Code, e.Description));
            }
            return View();
        }

15. satıra göz atarsanız eğer “IdentityResult” nesnesinde gelen “Errors” propertysindeki tüm hatalar “ModelState” nesnesine “AddModelError” metoduyla eklenmiştir. Bu işlem neticesinde kullanıcı girmiş olduğu tüm hatalı şifreler yüzünden aşağıdaki gibi bilgilendirilecektir.
Asp.NET Core Identity - Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü - VI
Görüldüğü üzere Identity mekanizması tarafından varsayılan olarak gelen validasyonlara takıldığımız vakit bu hata mesajlarıyla karşılaşılmaktadır.

“Peki hoca, bu hata mesajlarını nasıl değiştirebiliyoruz?”, “şifrede istemediğim validasyonları nasıl kaldırabilirim?” vs. gibi sorularınızı duyar gibiyim… Tamam sakin olun. Bu makalede zaten bu ve buna benzer tüm soruların cevaplarını vermeye çalışacağız.

Şimdi ilk olarak varsayılan validasyon ayarlarıyla oynamayı inceleyelim.

Varsayılan Password Validasyon Ayarlarını Değiştirme

Bunun için “Startup.cs” dosyasına gitmemiz gerekmektedir. “ConfigureServices” içerisinde “AddIdentity” metodu ile uygulamaya dahil edilen Identity mekanizmasına 8. satırda olduğu gibi belirli işlemler yapılmaktadır.

    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, AppRole>(_ =>
            {
                _.Password.RequiredLength = 5; //En az kaç karakterli olması gerektiğini belirtiyoruz.
                _.Password.RequireNonAlphanumeric = false; //Alfanumerik zorunluluğunu kaldırıyoruz.
                _.Password.RequireLowercase = false; //Küçük harf zorunluluğunu kaldırıyoruz.
                _.Password.RequireUppercase = false; //Büyük harf zorunluluğunu kaldırıyoruz.
                _.Password.RequireDigit = false; //0-9 arası sayısal karakter zorunluluğunu kaldırıyoruz.
            }).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?}"));
        }
    }

Bu işlemler, ilgili kod satırlarında açıklamalarıyla belirtildiği gibi varsayılan olarak gelen validasyon ayarları üzerine gerçekleştirilmektedirler.

Evet… Varsayılan validasyon ayarlarını istediğimiz gibi şekillendirmeyi gördük. Peki özel validasyonları nasıl oluşturacağız? sorusunu sorarsak eğer bunun içinde IPasswordValidator arayüzünü kullanmamız gerekecektir.

IPasswordValidator Arayüzü İle Özel Validasyon Geliştirme

IPasswordValidator arayüzü, özelleştirilmiş validasyonlarımızı geliştirebilmek için tasarlanmış bir arayüzdür. İlgili arayüzün içeriğini şöyle bir incelersek eğer;
Asp.NET Core Identity - Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü - VI
görüldüğü üzere uygulamada kullanıcı yönetimini sağlayan UserManager nesnesi, üyelik bilgileri doldurulan kullanıcı nesnesi ve ilgili kullanıcıya atanmaya çalışılan password bilgileri “ValidateAsync” metoduna parametre olarak gelmektedir ve böylece özelleştirilmiş validasyonlarımızı tasarlarken elimizin altında tüm nesnelerimiz mevcut olmuş olacaktır.

Özelleştirilmiş validasyonlarımızı tasarlayabilmek için IPasswordValidator arayüzünden miras alan bir sınıf oluşturmamız gerekmektedir. Bunun için projenizin istediğiniz herhangi bir noktasında gerekli çalışmayı gerçekleştirebilirsiniz. Ben makale dizimizde kullandığım örnek projenin ana dizininde “CustomValidations” isminde bir klasör oluşturuyorum ve içerisine “CustomPasswordValidation” isminde bir sınıf ekliyorum. Bu sınıf içeriğini aşağıdaki gibi geliştirebilirsiniz;

    public class CustomPasswordValidation : IPasswordValidator<AppUser>
    {
        public Task<IdentityResult> ValidateAsync(UserManager<AppUser> manager, AppUser user, string password)
        {
            List<IdentityError> errors = new List<IdentityError>();
            if (password.Length < 5) //Password karakter sayısı
                errors.Add(new IdentityError { Code = "PasswordLength", Description = "Lütfen şifreyi en az 5 karakter giriniz." });
            if (password.ToLower().Contains(user.UserName.ToLower())) //Password içerisinde username kontrolü
                errors.Add(new IdentityError { Code = "PasswordContainsUserName", Description = "Lütfen şifre içerisinde kullanıcı adını yazmayınız." });

            if (!errors.Any())
                return Task.FromResult(IdentityResult.Success);
            else
                return Task.FromResult(IdentityResult.Failed(errors.ToArray()));
        }
    }

Görüldüğü üzere örneklendirme için belli başlı özel validasyon yapılanması inşa etmiş bulunmaktayım. 5. satırda oluşturulan “IdentityError” koleksiyonuna doğrulanmayan şifrenin ilgili hata mesajları eklenecek ve bu koleksiyonun dolu olma durumunda geriye Task.FromResult ile ilgili hatalar döndürülecektir.

Artık oluşturulan bu özelleştirilmiş validasyonu kullanması için Identity mekanizmasına bildirmemiz gerekmektedir. Bunun için yine “Startup.cs” dosyasına gitmemiz gerekmektedir.

    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, AppRole>(_ =>
            {
                _.Password.RequiredLength = 5; //En az kaç karakterli olması gerektiğini belirtiyoruz.
                _.Password.RequireNonAlphanumeric = false;//Alfanumerik zorunluluğunu kaldırıyoruz.
                _.Password.RequireLowercase = false;//Küçük harf zorunluluğunu kaldırıyoruz.
                _.Password.RequireUppercase = false;//Büyük harf zorunluluğunu kaldırıyoruz.
                _.Password.RequireDigit = false;//0-9 arası sayısal karakter zorunluluğunu kaldırıyoruz.
            }).AddPasswordValidator<CustomPasswordValidation>().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?}"));
        }
    }

“ConfigureServices” metodu içerisindeki 15. satıra göz atarsanız eğer “AddPasswordValidator” generic metodu ile uygulamanın hangi validasyon ayarlarını benimseyeceğini belirtmiş oluyoruz. Bu şekilde uygulamayı derleyip çalıştırdığımızda, içerisinde kullanıcı adının geçtiği bir şifre yazdığımız vakit aşağıdaki ekran görüntüsünde olduğu gibi özelleştirilmiş validasyon hatasını almaktayız.
Asp.NET Core Identity - Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü - VI

Bu noktadan itibaren bir üyelik işleminde kullanıcı şifresi üzerinde validasyon ayarlarının nasıl yapıldığını ve ihtiyacımıza dönük özelleştirilmiş validasyon yapılanmasının nasıl oluşturulduğunu incelemiş olduk… Dizimizin bir sonraki içeriğinde kullanıcı doğrulama ayarları üzerine konuşuyor olacağız. O halde şimdilik hoşçakalın.

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

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

Bunlar da hoşunuza gidebilir...

6 Cevaplar

  1. Senol dedi ki:

    Merhaba. Öncelikle makale için elinize sağlık. Çok detaylı ve açıklayıcı hazırlamışsınız. Kullanıcıdan şifre için büyük ve küçük harf, rakam veya alfanumerik karakater zorunluluğu talep ettiğimizde ilgili hata mesajını nasıl Türkçe yazdırabiliriz. CustomPasswordValidation sınıfında kullandığımız “password” objesinde bununla ilgili metodları bulamadım. Şifre için default validasyonları kullandığınızda ‘DataAnnotations’ ile require ve length özellikleri için özel mesaj yazdırılabiliyor ancak yukarıdaki dört özellik ile ilgili nasıl Türkçe hata mesajı yazdırılacağını bulamadım. Yardımcı olursanız sevinirim. İyi günler…

  2. Senol dedi ki:

    Merhaba. Biraz sabırsız davrandım herhalde. Şifre validasyonlarında Türkçe hata mesajları ile ilgili sorumun cevabını 8. makalenizde buldum. Teşekkürler..

  1. 14 Ağustos 2019

    […] Asp.NET Core Identity – Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü – VI […]

  2. 16 Ağustos 2019

    […] önceki Şifre Validasyon Ayarları ve IPasswordValidator Arayüzü başlıklı makalemizde Identity mimarisinde varsayılan ayarları bulunan kullanıcı şifresi […]

Bir cevap yazın

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