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

Asp.NET Core Identity – Cookie Bazlı Kimlik Doğrulama – IX

Merhaba,

Bu içeriğimizde; artık Asp.NET Core Identity yazı dizimizde sıra Cookie bazlı kimlik doğrulama mekanizmasını inşa etmeye geldiğinden dolayı web uygulamamızda kullanıcı doğrulama kontrolünün Cookie mekanizmasıyla nasıl yapılandırıldığını inceleyecek ve uygulamalı olarak örneklendireceğiz.

Yine uygulamayı yazı dizimizde şu ana kadar bizlere eşlik eden malum projemiz üzerinden pratiğe dökeceğiz. Evet, hadi başlayalım…

Uygulamada Temel Cookie Konfigürasyonunun Yapılandırılması

Uygulamada Cookie bazlı kimlik doğrulaması yapabilmek için herşeyden önce Cookie konfigürasyonunun gerçekleştirilmesi gerekmekte ve bunun için her zaman olduğu gibi “Startup.cs” dosyasında çalışılması 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.

                _.User.RequireUniqueEmail = true; //Email adreslerini tekilleştiriyoruz.
                _.User.AllowedUserNameCharacters = "abcçdefghiıjklmnoöpqrsştuüvwxyzABCÇDEFGHIİJKLMNOÖPQRSŞTUÜVWXYZ0123456789-._@+"; //Kullanıcı adında geçerli olan karakterleri belirtiyoruz.
            }).AddPasswordValidator<CustomPasswordValidation>()
              .AddUserValidator<CustomUserValidation>()
              .AddErrorDescriber<CustomIdentityErrorDescriber>().AddEntityFrameworkStores<AppDbContext>();

            services.ConfigureApplicationCookie(_ =>
            {
                _.LoginPath = new PathString("/User/Login");
                _.Cookie = new CookieBuilder
                {
                    Name = "AspNetCoreIdentityExampleCookie", //Oluşturulacak Cookie'yi isimlendiriyoruz.
                    HttpOnly = false, //Kötü niyetli insanların client-side tarafından Cookie'ye erişmesini engelliyoruz.
                    Expiration = TimeSpan.FromMinutes(2), //Oluşturulacak Cookie'nin vadesini belirliyoruz.
                    SameSite = SameSiteMode.Lax, //Top level navigasyonlara sebep olmayan requestlere Cookie'nin gönderilmemesini belirtiyoruz.
                    SecurePolicy = CookieSecurePolicy.Always //HTTPS üzerinden erişilebilir yapıyoruz.
                };
                _.SlidingExpiration = true; //Expiration süresinin yarısı kadar süre zarfında istekte bulunulursa eğer geri kalan yarısını tekrar sıfırlayarak ilk ayarlanan süreyi tazeleyecektir.
                _.ExpireTimeSpan = TimeSpan.FromMinutes(2); //CookieBuilder nesnesinde tanımlanan Expiration değerinin varsayılan değerlerle ezilme ihtimaline karşın tekrardan Cookie vadesi burada da belirtiliyor.
            });

            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?}"));
        }
    }

Yukarıdaki “Startup.cs” dosyasının kodlarını incelerseniz eğer “ConfigureServices” metodu içerisinde uygulamaya 22 ile 35. satırları arasında eklenen “ConfigureApplicationCookie” servisine göz atarsanız eğer parametre olarak belirtilen lambda ifadesiyle belli başlı tanımlamalar yapılmıştır. Bu tanımlamaların ne olduğuna dair açıklamalar kod kısmında yorum satırı olarak yanlarına yazılmıştır.

İşte bu şekilde uygulamada kullanılacak olan Cookie yapılanmasının temel konfigürasyonunu sağlamış bulunmaktayız. Burada devam etmeksizin “CookieBuilder” nesnesinin “SameSite” ve “SecurePolicy” olmak üzere iki propertysi üzerinde durmak ve detaylandırmak istiyorum.

SameSite SecurePolicy
SameSite, uygulamamıza ait Cookie bilgilerinin 3. taraflardan kaynaklanan isteklere gönderilip gönderilmemesi ayarını yaptığımız bir özelliktir. “None”, “Strict” ve “Lax” olmak üzere üç farklı değer alır.

  • None
    Uygulamaya ait Cookie bilgilerini 3. taraf isteğe ekler ve gönderir.
  • Strict
    Uygulamaya iat Cookie bilgilerini 3. taraf hiçbir isteğe göndermez.
  • Lax
    Uygulamaya ait Cookie bilgilerini üst düzey(top level) navigasyonlara sebep olmayan yani bir başka deyişle adres çubuğundaki değişikliklere neden olmayan isteklere göndermeyecektir.
SecurePolicy, uygulamamıza ait Cookie bilgilerinin güvenilir(HTTPS) ya da güvensiz(HTTP) üzerinden erişilebilir olup olmamasını ayarladığımız özelliktir. “Always”, “SameAsRequest” ve “None” olmak üzere üç farklı değer alır.

  • Always
    Cookie’leri HTTPS üzerinden erişilebilir yapar.
  • SameAsRequest
    Cookie’leri hem HTTP hemde HTTPS protokolü üzerinden erişilebilir yapar.
  • None
    Cookie’leri HTTP üzerinden erişilebilir yapar.

Login Viewmodel Tasarımı

Şimdi geliştirmeye devam edersek eğer sırada doğrulama yapılacak kullanıcı bilgilerini tarafımıza ulaştıracak viewmodel nesnemizi tasarlayalım. Bunun için “Models” -> “ViewModels” klasörüne “LoginViewModel” adında bir sınıf oluşturalım ve aşağıdaki gibi tasarlayalım.

    public class LoginViewModel
    {
        [Required(ErrorMessage = "Lütfen e-posta adresini boş geçmeyiniz.")]
        [DataType(DataType.EmailAddress, ErrorMessage = "Lütfen uygun formatta e-posta adresi giriniz.")]
        [Display(Name = "E-Posta ")]
        public string Email { get; set; }
        [Required(ErrorMessage = "Lütfen şifreyi boş geçmeyiniz.")]
        [DataType(DataType.Password, ErrorMessage = "Lütfen uygun formatta şifre giriniz.")]
        [Display(Name = "Şifre")]
        public string Password { get; set; }
        /// <summary>
        /// Beni hatırla...
        /// </summary>
        [Display(Name = "Beni Hatırla")]
        public bool Persistent { get; set; }
        public bool Lock { get; set; }
    }

Bu viewmodele göz atarsanız eğer giriş yapacak kullanıcının e-posta adresini ve şifresini barındırmakla birlikte “Persistent” ve “Lock” isminde iki adet bool tipinde propertyde barındırmaktadır. Bu dikkat çekici model elemanlarının sırasıyla ne olduklarına değinirsek eğer; “Persistent”, cookie konfigürasyonlarında Expiration değeri olarak verilen vade süresinin oluşturulacak cookie için geçerli/aktif olup olmamasını tutmakta, “Lock” özelliği ise kullanıcının belirli sayıda yapmış olduğu oturum girişi hatalarında ilgili user profilinin kilitlenip kilitlenmeyeceğini tutmaktadır.

Evet… Artık uygulamamızda Cookie bazlı kimlik doğrulamayı kullanabiliriz.

Login Action Metodunun Tasarlanması ve SignInManager Sınıfının Tanımlanması

Uygulamada giriş sorumluluğunu üstlenecek olan bir “Login” action metodu tasarlamamız gerekmektedir. Bunun için yukarıdaki “Startup.cs” dosyasının 24. satırında belirtildiği gibi önceden(önceki içeriklerde) oluşturduğumuz “User(Controller).cs” controller sınıfını kullanacağız. Tabi siz isterseniz kendinize özel farklı bir controllerda çalışmalarınızı gerçekleştirebilirsiniz.

    public class UserController : Controller
    {
        readonly UserManager<AppUser> _userManager;
        readonly SignInManager<AppUser> _signInManager;
        public UserController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
        }
        public IActionResult Login(string ReturnUrl)
        {
            TempData["returnUrl"] = ReturnUrl;
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                AppUser user = await _userManager.FindByEmailAsync(model.Email);
                if (user != null)
                {
                    //İlgili kullanıcıya dair önceden oluşturulmuş bir Cookie varsa siliyoruz.
                    await _signInManager.SignOutAsync();
                    Microsoft.AspNetCore.Identity.SignInResult result = await _signInManager.PasswordSignInAsync(user, model.Password, model.Persistent, model.Lock);

                    if (result.Succeeded)
                        return Redirect(TempData["returnUrl"].ToString());
                }
                else
                {
                    ModelState.AddModelError("NotUser", "Böyle bir kullanıcı bulunmamaktadır.");
                    ModelState.AddModelError("NotUser2", "E-posta veya şifre yanlış.");
                }
            }
            return View(model);
        }

        .
        .
        diğer actionlar
        .
        .
    }

Yukarıdaki kod bloğunu incelerseniz eğer “Login” actionının GET metodunda “ReturnUrl” parametresi alınmış ve TempData kontrolüne atanmıştır. Bunun nedeni, Identity mekanizması herhangi bir kullanıcının yetkisinin olmadığı sayfalara erişmeye yahut yetkisi dışında bir iş yapmaya çalıştığında otomatik bir şekilde direkt olarak “Login” actionına yönlendirecektir. İşte bu actionda veritabanıyla tutarlı veriler eşliğinde bir doğrulama gerçekleştirilirse eğer kullanıcıyı ilk gitmek istediği adrese yönlendirmekteyiz.

“Login” actionının POST metoduna göz atarsak eğer 21. satırda kullanıcıdan gelen email adresine uygun olan bir user varsa çekilmekte ve 25. satırda ilgili kullanıcıya ait önceden oluşturulmuş olan cookieler varsa da temizlenmektedir. 26. satırda ise kullanıcıya SignInManager sınıfının PasswordSignInAsync metoduyla oturum açmasına izin vermekteyiz.

Peki nedir bu SignInManager sınıfı?
Kullanıcının giriş ve çıkışlarını kontrol eden bir sınıftır.

Devamında ise kullanıcı tarafından girilen email adresinin yanlış olma durumunda 33 ve 34. satırlarda ModelState’e error olarak ilgili hata mesajları eklenmekte ve böylece kullanıcıya bilgi verilmektedir.

Ayriyetten; 26. satıra tekrardan göz atarsanız eğer SignInManager sınıfının PasswordSignInAsync metodunun 3. parametresine true verildiği taktirde oluşturulacak cookie değerinin Expiration olarak belirtilen vade kadar tutulacağını ifade etmekte aksi taktirde session açık kaldığı sürece coockie değerlerinin kullanılabileceğini lakin browser kapatıldığı vakit cookielerin temizleneceğini ifade etmektedir.. 4. parametrede ise başarısız neticelenen n adet giriş denemelerinde ilgili kullanıcının hesabının kilitlenip kilitlenmeme durumunu kontrol etmiş oluyoruz. Bu konuyu makalemizin ileriki satırlarında ayrıca ele alacak ve detaylandıracağız.

Velhasıl oluşturduğumuz “Login” actionının view görüntüsünü aşağıdaki gibi tasarlayalım.

@model AspNetCoreIdentityExample.Models.ViewModels.LoginViewModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<h4>Giriş Yap</h4>
<hr />
<form asp-action="Login">
    <table>
        <tr>
            <td colspan="3"><div asp-validation-summary="All"></div></td>
        </tr>
        <tr>
            <td><label asp-for="Email"></label></td>
            <td><input asp-for="Email" /></td>
            <td><span asp-validation-for="Email"></span></td>
        </tr>
        <tr>
            <td><label asp-for="Password"></label></td>
            <td><input asp-for="Password" /></td>
            <td><span asp-validation-for="Password"></span></td>
        </tr>
        <tr>
            <td><label asp-for="Persistent"></label></td>
            <td><input asp-for="Persistent" /></td>
            <td><span asp-validation-for="Persistent"></span></td>
        </tr>
        <tr>
            <td colspan="3"><input type="submit" value="Giriş Yap" /></td>
        </tr>
    </table>
</form>

Authorize Attribute’u İle Yetki Kontrolü

Artık uygulamamızda cookie bazlı kimlik doğrulaması tam olarak inşa edilmiş bulunmaktadır. Dolayısıyla bu safhadan itibaren sayfa bazlı yetki kontrolü gerçekleştirmemiz yeterli ve yerinde olacaktır. Bunun için Authorize attributeunun kullanılması yeterlidir. Burada örneklendirme için “User(Controller).cs” controllerı altında “Index” actionını seçiyorum ve aşağıda olduğu gibi Authorize attributeu ile işaretliyorum.

    public class UserController : Controller
    {
        readonly UserManager<AppUser> _userManager;
        readonly SignInManager<AppUser> _signInManager;
        public UserController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
        }

        [Authorize]
        public IActionResult Index()
        {
            return View(_userManager.Users);
        }
        .
        .
        .
        diğer actionlar
        .
        .
        .
    }

Bu işlemden sonra ilgili sayfaya giriş yapmaksızın girmeye çalıştığımızda aşağıdaki ekran görüntüsünde görüldüğü üzere “user/login” dizinine yönlendirme yapacaktır.
Asp.NET Core Identity - Cookie Bazlı Kimlik Doğrulama - IX

Peki giriş(login) yaptığımızda ne oluyor? diye sorarsanız eğer onunda cevabını aşağıdaki ekran görüntüsü vermektedir.
Asp.NET Core Identity - Cookie Bazlı Kimlik Doğrulama - IX

Yukarıdaki ekran görüntüsünü incelerseniz eğer tarayıcıya sağ tıklayarak “İncele” dedikten sonra “Application” sekmesini açtığınızda sol tarafta çıkan menü üzerinden “Cookies” sekmesinde uygulamamıza ait cookieleri görebilmekteyiz. Dikkat ederseniz uygulama login yaptığı taktirde Startup.cs dosyasında modifiye ettiğimiz CookieBuilder nesnesindeki “AspNetCoreIdentityExampleCookie” name değerini verdiğimiz bir cookie oluşturulmuştur. Bunun dışında login işleminden önce Identity Asp.NET Core uygulaması tarafından eklenen varsayılan cookieler mevcuttur. Bunlar Asp.NET MVC’de CSRF/XSRF(Cross-Site Request Forgery) Saldırı Güvenliği ile alakalı önlemler üzerine yapılmış mimarisel çalışmalardır.

Eğer ki “Application” penceresindeki bu cookieleri manuel silersek uygulama logout yapmış olacaktır. Bunun için ise “User(Controller).cs” controllerında ayriyetten bir “Logout” isminde action metot tasarlayarak bu işlemi daha da programatize edebiliriz.

    public class UserController : Controller
    {
        readonly UserManager<AppUser> _userManager;
        readonly SignInManager<AppUser> _signInManager;
        public UserController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
        }

        public async Task<IActionResult> Logout()
        {
            await _signInManager.SignOutAsync();
            return RedirectToAction("Index");
        }
        .
        .
        .
        diğer actionlar
        .
        .
        .
    }

Asp.NET Core Identity - Cookie Bazlı Kimlik Doğrulama - IX

Sonuç olarak Asp.NET Core Identity mekanizmasında Cookie bazlı kimlik doğrulamasını tüm detaylarıyla gerçekleştirmiş olduk. Bir sonraki içeriğimizde belli bir sayıda başarısız oturum açma durumlarında hesabına girmeye çalışan ilgili kullanıcının hesabının sonraki girişleri doğru bilgilerle dahi olsa nasıl kilitleneceğini ele alacağız.

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...

28 Cevaplar

  1. ishak dedi ki:

    Hocam merhaba;

     [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task SignIn(string Email_Login, string Password, bool Persistent, bool Lock)
            {
    
    
    
                if (ModelState.IsValid)
                {
                    CustomIdentityUser user = await _userManager.FindByEmailAsync(Email_Login);
                    if (user != null)
                    {
                        //İlgili kullanıcıya dair önceden oluşturulmuş bir Cookie varsa siliyoruz.
                        await _signInManager.SignOutAsync();
    

    await _signInManager.SignOutAsync(); Hata veriyor.

    Hata mesajı : NullReferenceException: Object reference not set to an instance of an object.s

  2. Hasan dedi ki:

    Giriş yapılıyor ve Cookie geliyor ama [Authorize] Olan yerlere yine girmiyor.

    • Gençay dedi ki:

      Eğer ki Asp.NET Core 3.0+ sürümlerinde çalışıyorsanız “Startup.cs” dosyasındaki “Configure” metodu içerisinde “UseAuthentication” middlewareinin yanında “UseAuthorization” olduğuna dikkat ediniz.

      
              public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
              {
                  .
                  .
                  .
                  app.UseAuthentication();
                  app.UseAuthorization();
                  .
                  .
                  .
              }
      
  3. Umut dedi ki:

    Merhabalar,

    Login postumda var result = await _signInManager.PasswordSignInAsync(user, model.Password, model.Persistent, model.Lock);

    kısmı derlenirken
    Cannot create a DbSet for ‘IdentityRole’ because this type is not included in the model for the context. diye hata alıyorum

  4. tugay dedi ki:

    merhaba,startup içerisinde UseAuthorization komutunu yazdıgımda altını çiziyor.
    bu konuda ne yapabilirim.

  5. yasin dedi ki:
    public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews();
                services.AddRazorPages();
                services.AddDbContext(options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("Default"));
                });
                services.AddIdentity(_ =>
                {
                    _.Password.RequiredLength = 4; //En az kaç karakterli olması gerektiğini belirtiyoruz.
                    _.Password.RequireNonAlphanumeric = true; //Alfanumerik zorunluluğunu kaldırıyoruz.
                    _.Password.RequireLowercase = true; //Küçük harf zorunluluğunu kaldırıyoruz.
                    _.Password.RequireUppercase = true; //Büyük harf zorunluluğunu kaldırıyoruz.
                    _.Password.RequireDigit = true; //0-9 arası sayısal karakter zorunluluğunu kaldırıyoruz.
    
                    _.User.RequireUniqueEmail = true; //Email adreslerini tekilleştiriyoruz.
                    _.User.AllowedUserNameCharacters = "abcçdefghiıjklmnoöpqrsştuüvwxyzABCÇDEFGHIİJKLMNOÖPQRSŞTUÜVWXYZ0123456789-._@+"; //Kullanıcı adında geçerli olan karakterleri belirtiyoruz.
                }).AddPasswordValidator()
                  .AddUserValidator()
                  .AddErrorDescriber().AddEntityFrameworkStores()
                  .AddDefaultTokenProviders();
    
                //services.ConfigureApplicationCookie(_ =>
                //{
                //    _.LoginPath = new PathString("/User/Login");
                //    _.LogoutPath = new PathString("/User/Logout");
                //    _.Cookie = new CookieBuilder
                //    {
                //        Name = "yasinCookie", //Oluşturulacak Cookie'yi isimlendiriyoruz.
                //        HttpOnly = false, //Kötü niyetli insanların client-side tarafından Cookie'ye erişmesini engelliyoruz.
                //        Expiration = TimeSpan.FromMinutes(2), //Oluşturulacak Cookie'nin vadesini belirliyoruz.
                //        SameSite = SameSiteMode.Lax, //Top level navigasyonlara sebep olmayan requestlere Cookie'nin gönderilmemesini belirtiyoruz.
                //        SecurePolicy = CookieSecurePolicy.Always //HTTPS üzerinden erişilebilir yapıyoruz.
                //    };
                //    _.SlidingExpiration = true; //Expiration süresinin yarısı kadar süre zarfında istekte bulunulursa eğer geri kalan yarısını tekrar sıfırlayarak ilk ayarlanan süreyi tazeleyecektir.
                //    _.ExpireTimeSpan = TimeSpan.FromMinutes(2); //CookieBuilder nesnesinde tanımlanan Expiration değerinin varsayılan değerlerle ezilme ihtimaline karşın tekrardan Cookie vadesi burada da belirtiliyor.
                //});
                services.ConfigureApplicationCookie(options =>
                     {
                         // Cookie settings
                         options.Cookie.HttpOnly = true;
                           options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
    
                         options.LoginPath = "/User/Login";
                         options.AccessDeniedPath = "/Identity/Account/AccessDenied";
                         options.SlidingExpiration = true;
                       });
                services.AddMvc();
    
                services.Configure(options =>
                {
                    // Password settings.
                    options.Password.RequireDigit = true;
                    options.Password.RequireLowercase = true;
                    options.Password.RequireNonAlphanumeric = true;
                    options.Password.RequireUppercase = true;
                    options.Password.RequiredLength = 6;
                    options.Password.RequiredUniqueChars = 1;
    
                    // Lockout settings.
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                    options.Lockout.MaxFailedAccessAttempts = 8;
                    options.Lockout.AllowedForNewUsers = true;
    
                    // User settings.
                    options.User.AllowedUserNameCharacters =
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                    options.User.RequireUniqueEmail = false;
                });
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseStatusCodePages();
                app.UseRouting();
    
                app.UseAuthorization();
                app.UseAuthentication();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
                
            }
        }
    }
    

    Hata burada sanırım bu startup cs doğru mu acaba

  6. Mustafa dedi ki:

    app.UseAuthentication();
    app.UseAuthorization();
    olması daha doğru olmaz mı ? 103 ve 102. satırlar

  7. Abdullatif dedi ki:

    Hocam ben kedi sitemde bu yaptıklrınızı yaptım. Localde çalışıyor ama gereçek ortamda cookie nin daha çok süresi varken 10 ya da 15 dk sonra falan cookie siliniyor bu duruma ne sebep olmuş olabilir? Benim için çok önemli lütfen yardımcı olabilir misiniz?

    • Gençay dedi ki:

      Sunucuya danışmanı tavsiye ederim.

      • Abdullatif dedi ki:

        Natro ile yayınladım sitemi session süreleri maximum 30 dk imiş bununla alakalı olabilir mi?
        Bir de new CookieBilder içindeki Expiration u vermeye çalıştığımda hata veriyor bundan dolayı olabilir mi?

        Bir de sitenizi ve içeriklerinizi beğeniyorum ama yapılan yorumlara cevap geldiğinde mail ile bilgilendirme olursa daha güzel olur 🙂 sitenizi geliştirebilmeniz için bir tavsiye.

        Cevabınızı bekliyorum
        Teşekkür ederim:)

        • Gençay dedi ki:

          Evet olabilir.
          CookieBuilder’de ki Expiration’a değer atamamanızı öneririm.

          Evet, bu öneri üzerine ilk fırsatta yorumlar notification işlemi için bir eklenti vs. araştırmaya başlayacağım…
          Sevgiler…

  8. Cihan KARAKAŞ dedi ki:

    Hocam, benim admin, bayi, üye rolünde 3 farklı kullanıcım var. Login işlemini _usermanager.signin() methoduyla yapıyorum. Bu kullanıcılar aynı tarayıca oturum açamıyorum. Farklı kullanıcı giriş yaptğında diğer oturum kapanıyor. Bunu önlemenin bir yolu var mı ? Yani aynı tarayıca 2 farklı kullanıcıda oturum açmam mümkün mü cevaplandırırsanız sevinirim kolay gelsin

    • Gençay dedi ki:

      ‘Authentication Schema’ları incelemeniz tavsiye ederim. Yapı yine aynı. Sadece farklı şemalarda farklı türlere göre authentication konfigürasyonlarını sağlaman gerekmektedir.

  9. Turab dedi ki:

    Merabalar Hocam.Projeyi calıştırdığımda :
    -OptionsValidationException: Cookie.Expiration is ignored, use ExpireTimeSpan instead
    hatayı alıyorum.Sorunu çözmemde yardımcı olur musunuz ?

    • minetpcuglu dedi ki:

      Çözebildinizmi ?

      • batuhansarikaya dedi ki:

        bu hatayı çözebildiniz mi

        • Taha dedi ki:
          Expiration = TimeSpan.FromMinutes(120) //Oluşturulacak Cookie'nin vadesini belirliyoruz.
          

          Bu ifade yerine

          MaxAge = TimeSpan.FromMinutes(120)
          

          bunu deneyin

          • Taha dedi ki:

            Bu arada MaxAge = TimeSpan.FromMinutes(120) 120 ifadesi dakika cinsindendir bunu kendinize göre ayarlayabilirsiniz.

          • Adil dedi ki:

            Autentifikasyon icin Cookie konfiqurasyonu zamani:

            services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath = new PathString("/User/Login");
                options.Cookie = new CookieBuilder
                {
                    Name = "AspNetCoreIdentityExampleCookie",
                    HttpOnly = false,
            		SameSite = SameSiteMode.Lax,
                    SecurePolicy = CookieSecurePolicy.Always,
            		
                    
                    // Expiration = TimeSpan.FromMinutes(2), >- gosteremeyiz bunun yerine
                };
            	
                options.ExpireTimeSpan = TimeSpan.FromMinutes(2); // su sekilde gostermeliyiz Expire tarihini
                options.SlidingExpiration = true;
            });
            
  10. Oğuzhan dedi ki:

    Hocam merhabalar.

        public IActionResult Login(string ReturnUrl)
        {
            TempData["returnUrl"] = ReturnUrl;
            return View();
        }
    

    Bu Action metoduına ReturnUrl bilgisinin gelme ayarını nerde yaptınız acaba makaleyi ikinci okuyuşum hala anlayamadım. Startup.cs içerisinde veya başka bir yerde böyle bir ayara denk gelmedim acaba gözden mi kaçırıyorum, yoksa bilmediğim birşey mi var.

    • Gençay dedi ki:

      Merhaba,

      Login’e yönlendirildiğin taktirde hangi sayfaya girmek istediyseniz o otomatik olarak ReturnUrl parametresiyle gelecektir.
      İyi çalışmalar.

  11. Imran Ekberli dedi ki:

    Merhaba Hocam client-server projem var, serverde jwt token kullaniyorum,client tarafda elde etdiyim access,refresh tokenleri ise cookiede tutmak isdiyorum , bunu nasil yapmaliyim.biraz zorunluk cekiyorum.tesekkurler.

  12. Ahmet dedi ki:

    Merhaba,

    Login ekranında her zaman değil ancak bazen formu post ettiğimde http 400 bad request hatası alıyorum. Her zaman olmaması hatayı bulamamama sebep oluyor. Sebebi ne olabilir yardımcı olabilir misiniz hocam hayırlı günler.

  13. Furkan dedi ki:

    İyi çalışmalar hocam. Benim cookie zamanla büyüyor ve chunk’lar şeklinde tutulmaya çalışılıyor ve 431 hatası alıyorum. Ama cookie’de role ve claim yok.

  14. serdar dedi ki:

    merhaba bir türlü anlayamadığım bir şey var cevaplarsanız çok sevinirim.Oturum kimlik doğrulama kullanıyorsam sunucu ile client arasında bir token anahtarını şifreleyerek cookie içine yazıp kullanıcı tekrar siteye girdiğinde cookie deki token anahtarını alıp sql ile karşılaştırmam gerektiği bir çok makalede okudum.Ancak ben kötü niyetli biriyim ve aynı şirkette arkadaşımın bilgisayarından girdiği örneğin facebook sitesine ait cookie manuel çaldım sonra bunu kendi bilgisayarımda aynı browser kullanarak cookilerin olduğu yere kopyaladım

    bu durumda facebook ben kendi bilgisayarımdan girdiğimde facebook cookie me bakarak beni arkadaşım sanarak oturum izni verecektir.
    eğer bu senaryo doğruysa

    cookie içine sessionID token olarak şifreleyerek koymanın anlamı ne ? zaten şifrelenmişde olsa sunucu bu şifreli bir şekilde veya descrypt ederek sql ile karşılaştırıp izin veriyor

    bana göre bir istemci siteye girdiğinde istemciye ait bir harddisk numarası veya anakart numarası alınarak bu sql de saklanmalı tekrar istek yaptığında bu kontrol edilmeli.Ancak browserlar buna izin vermiyor ki.. zaten yasal değil kullanıcının ip adresini saklasam o zaman public olan ip adresi elimde olacak oda bir şirket olduğundan aynı ip adresi çıkacak buda çözüm değil o zaman benim yanlış düşündüğüm şey nedir ? neden herkes token harika ulu diye bahsediyor cookie içine yazılan bir token sonuç olarak cookie çalındığında bir anlamı kalmıyor
    bir yerde token anahtarının x dakika içinde güncellemesi gerekir denmiş ama örneği 15 dk içinde güncelleme yapıyor olsa bile bu süre içinde bende onu çalarsam yine oturum açabilirim
    örneğin bankaya giriş yaptığımda 2 li doğrulama gerekiyor anlık bir sms atıyor ve girmemi istiyor işte bu evet mantıklı yada kullanıcının sadece bilebileceği bir token şifresi

    yukarıda yazdıklarım yanlışsa lütfen düzeltin doğruysa o zaman token kullanmanın manasını anlamadım teşekkürler

  1. 20 Ağustos 2019

    […] Asp.NET Core Identity – Cookie Bazlı Kimlik Doğrulama – IX […]

minetpcuglu için bir yanıt yazın Yanıtı iptal et

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