﻿
{"id":11861,"date":"2019-08-20T22:36:01","date_gmt":"2019-08-20T22:36:01","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=11861"},"modified":"2019-08-21T08:29:00","modified_gmt":"2019-08-21T08:29:00","slug":"asp-net-core-identity-cookie-bazli-kimlik-dogrulama-ix","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-cookie-bazli-kimlik-dogrulama-ix\/","title":{"rendered":"Asp.NET Core Identity &#8211; Cookie Bazl\u0131 Kimlik Do\u011frulama &#8211; IX"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde; art\u0131k <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-identity-yazi-dizisi\/\" target=\"_blank\" rel=\"noopener noreferrer\">Asp.NET Core Identity yaz\u0131 dizimizde<\/a> s\u0131ra Cookie bazl\u0131 kimlik do\u011frulama mekanizmas\u0131n\u0131 in\u015fa etmeye geldi\u011finden dolay\u0131 web uygulamam\u0131zda kullan\u0131c\u0131 do\u011frulama kontrol\u00fcn\u00fcn Cookie mekanizmas\u0131yla nas\u0131l yap\u0131land\u0131r\u0131ld\u0131\u011f\u0131n\u0131 inceleyecek ve uygulamal\u0131 olarak \u00f6rneklendirece\u011fiz.<\/p>\n<p>Yine uygulamay\u0131 yaz\u0131 dizimizde \u015fu ana kadar bizlere e\u015flik eden malum projemiz \u00fczerinden prati\u011fe d\u00f6kece\u011fiz. Evet, hadi ba\u015flayal\u0131m&#8230;<\/p>\n<h3>Uygulamada Temel Cookie Konfig\u00fcrasyonunun Yap\u0131land\u0131r\u0131lmas\u0131<\/h3>\n<p>Uygulamada Cookie bazl\u0131 kimlik do\u011frulamas\u0131 yapabilmek i\u00e7in her\u015feyden \u00f6nce Cookie konfig\u00fcrasyonunun ger\u00e7ekle\u015ftirilmesi gerekmekte ve bunun i\u00e7in her zaman oldu\u011fu gibi &#8220;Startup.cs&#8221; dosyas\u0131nda \u00e7al\u0131\u015f\u0131lmas\u0131 gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Startup\r\n    {\r\n        public IConfiguration Configuration { get; set; }\r\n        public Startup(IConfiguration configuration) =&gt; Configuration = configuration;\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            services.AddDbContext&lt;AppDbContext&gt;(_ =&gt; _.UseSqlServer(Configuration&#x5B;&quot;ConnectionStrings:SqlServerConnectionString&quot;]));\r\n            services.AddIdentity&lt;AppUser, AppRole&gt;(_ =&gt;\r\n            {\r\n                _.Password.RequiredLength = 5; \/\/En az ka\u00e7 karakterli olmas\u0131 gerekti\u011fini belirtiyoruz.\r\n                _.Password.RequireNonAlphanumeric = false; \/\/Alfanumerik zorunlulu\u011funu kald\u0131r\u0131yoruz.\r\n                _.Password.RequireLowercase = false; \/\/K\u00fc\u00e7\u00fck harf zorunlulu\u011funu kald\u0131r\u0131yoruz.\r\n                _.Password.RequireUppercase = false; \/\/B\u00fcy\u00fck harf zorunlulu\u011funu kald\u0131r\u0131yoruz.\r\n                _.Password.RequireDigit = false; \/\/0-9 aras\u0131 say\u0131sal karakter zorunlulu\u011funu kald\u0131r\u0131yoruz.\r\n\r\n                _.User.RequireUniqueEmail = true; \/\/Email adreslerini tekille\u015ftiriyoruz.\r\n                _.User.AllowedUserNameCharacters = &quot;abc\u00e7defghi\u0131jklmno\u00f6pqrs\u015ftu\u00fcvwxyzABC\u00c7DEFGHI\u0130JKLMNO\u00d6PQRS\u015eTU\u00dcVWXYZ0123456789-._@+&quot;; \/\/Kullan\u0131c\u0131 ad\u0131nda ge\u00e7erli olan karakterleri belirtiyoruz.\r\n            }).AddPasswordValidator&lt;CustomPasswordValidation&gt;()\r\n              .AddUserValidator&lt;CustomUserValidation&gt;()\r\n              .AddErrorDescriber&lt;CustomIdentityErrorDescriber&gt;().AddEntityFrameworkStores&lt;AppDbContext&gt;();\r\n\r\n            services.ConfigureApplicationCookie(_ =&gt;\r\n            {\r\n                _.LoginPath = new PathString(&quot;\/User\/Login&quot;);\r\n                _.Cookie = new CookieBuilder\r\n                {\r\n                    Name = &quot;AspNetCoreIdentityExampleCookie&quot;, \/\/Olu\u015fturulacak Cookie'yi isimlendiriyoruz.\r\n                    HttpOnly = false, \/\/K\u00f6t\u00fc niyetli insanlar\u0131n client-side taraf\u0131ndan Cookie'ye eri\u015fmesini engelliyoruz.\r\n                    Expiration = TimeSpan.FromMinutes(2), \/\/Olu\u015fturulacak Cookie'nin vadesini belirliyoruz.\r\n                    SameSite = SameSiteMode.Lax, \/\/Top level navigasyonlara sebep olmayan requestlere Cookie'nin g\u00f6nderilmemesini belirtiyoruz.\r\n                    SecurePolicy = CookieSecurePolicy.Always \/\/HTTPS \u00fczerinden eri\u015filebilir yap\u0131yoruz.\r\n                };\r\n                _.SlidingExpiration = true; \/\/Expiration s\u00fcresinin yar\u0131s\u0131 kadar s\u00fcre zarf\u0131nda istekte bulunulursa e\u011fer geri kalan yar\u0131s\u0131n\u0131 tekrar s\u0131f\u0131rlayarak ilk ayarlanan s\u00fcreyi tazeleyecektir.\r\n                _.ExpireTimeSpan = TimeSpan.FromMinutes(2); \/\/CookieBuilder nesnesinde tan\u0131mlanan Expiration de\u011ferinin varsay\u0131lan de\u011ferlerle ezilme ihtimaline kar\u015f\u0131n tekrardan Cookie vadesi burada da belirtiliyor.\r\n            });\r\n\r\n            services.AddMvc();\r\n        }\r\n\r\n        public void Configure(IApplicationBuilder app, IHostingEnvironment env)\r\n        {\r\n            if (env.IsDevelopment())\r\n                app.UseDeveloperExceptionPage();\r\n\r\n            app.UseStatusCodePages();\r\n            app.UseStaticFiles();\r\n            app.UseAuthentication();\r\n            app.UseMvc(_ =&gt; _.MapRoute(&quot;Default&quot;, &quot;{controller=Home}\/{action=Index}\/{id?}&quot;));\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki &#8220;Startup.cs&#8221; dosyas\u0131n\u0131n kodlar\u0131n\u0131 incelerseniz e\u011fer &#8220;ConfigureServices&#8221; metodu i\u00e7erisinde uygulamaya 22 ile 35. sat\u0131rlar\u0131 aras\u0131nda eklenen &#8220;ConfigureApplicationCookie&#8221; servisine g\u00f6z atarsan\u0131z e\u011fer parametre olarak belirtilen lambda ifadesiyle belli ba\u015fl\u0131 tan\u0131mlamalar yap\u0131lm\u0131\u015ft\u0131r. Bu tan\u0131mlamalar\u0131n ne oldu\u011funa dair a\u00e7\u0131klamalar kod k\u0131sm\u0131nda yorum sat\u0131r\u0131 olarak yanlar\u0131na yaz\u0131lm\u0131\u015ft\u0131r.<\/p>\n<p>\u0130\u015fte bu \u015fekilde uygulamada kullan\u0131lacak olan Cookie yap\u0131lanmas\u0131n\u0131n temel konfig\u00fcrasyonunu sa\u011flam\u0131\u015f bulunmaktay\u0131z. Burada devam etmeksizin &#8220;CookieBuilder&#8221; nesnesinin &#8220;SameSite&#8221; ve &#8220;SecurePolicy&#8221; olmak \u00fczere iki propertysi \u00fczerinde durmak ve detayland\u0131rmak istiyorum.<\/p>\n<table>\n<thead>\n<tr>\n<td>SameSite<\/td>\n<td>SecurePolicy<\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>SameSite, uygulamam\u0131za ait Cookie bilgilerinin 3. taraflardan kaynaklanan isteklere g\u00f6nderilip g\u00f6nderilmemesi ayar\u0131n\u0131 yapt\u0131\u011f\u0131m\u0131z bir \u00f6zelliktir. &#8220;None&#8221;, &#8220;Strict&#8221; ve &#8220;Lax&#8221; olmak \u00fczere \u00fc\u00e7 farkl\u0131 de\u011fer al\u0131r.<\/p>\n<ul style=\"text-align: left;\">\n<li><strong>None<\/strong><br \/>\nUygulamaya ait Cookie bilgilerini 3. taraf iste\u011fe ekler ve g\u00f6nderir.<\/li>\n<li><strong>Strict<\/strong><br \/>\nUygulamaya iat Cookie bilgilerini 3. taraf hi\u00e7bir iste\u011fe g\u00f6ndermez.<\/li>\n<li><strong>Lax<\/strong><br \/>\nUygulamaya ait Cookie bilgilerini \u00fcst d\u00fczey(top level) navigasyonlara sebep olmayan yani bir ba\u015fka deyi\u015fle adres \u00e7ubu\u011fundaki de\u011fi\u015fikliklere neden olmayan isteklere g\u00f6ndermeyecektir.<\/li>\n<\/ul>\n<\/td>\n<td style=\"vertical-align: top;\">SecurePolicy, uygulamam\u0131za ait Cookie bilgilerinin g\u00fcvenilir(HTTPS) ya da g\u00fcvensiz(HTTP) \u00fczerinden eri\u015filebilir olup olmamas\u0131n\u0131 ayarlad\u0131\u011f\u0131m\u0131z \u00f6zelliktir. &#8220;Always&#8221;, &#8220;SameAsRequest&#8221; ve &#8220;None&#8221; olmak \u00fczere \u00fc\u00e7 farkl\u0131 de\u011fer al\u0131r.<\/p>\n<ul style=\"text-align: left;\">\n<li><strong>Always<\/strong><br \/>\nCookie&#8217;leri HTTPS \u00fczerinden eri\u015filebilir yapar.<\/li>\n<li><strong>SameAsRequest<\/strong><br \/>\nCookie&#8217;leri hem HTTP hemde HTTPS protokol\u00fc \u00fczerinden eri\u015filebilir yapar.<\/li>\n<li><strong>None<\/strong><br \/>\nCookie&#8217;leri HTTP \u00fczerinden eri\u015filebilir yapar.<\/li>\n<\/ul>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Login Viewmodel Tasar\u0131m\u0131<\/h3>\n<p>\u015eimdi geli\u015ftirmeye devam edersek e\u011fer s\u0131rada do\u011frulama yap\u0131lacak kullan\u0131c\u0131 bilgilerini taraf\u0131m\u0131za ula\u015ft\u0131racak viewmodel nesnemizi tasarlayal\u0131m. Bunun i\u00e7in &#8220;Models&#8221; -&gt; &#8220;ViewModels&#8221; klas\u00f6r\u00fcne &#8220;LoginViewModel&#8221; ad\u0131nda bir s\u0131n\u0131f olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki gibi tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class LoginViewModel\r\n    {\r\n        &#x5B;Required(ErrorMessage = &quot;L\u00fctfen e-posta adresini bo\u015f ge\u00e7meyiniz.&quot;)]\r\n        &#x5B;DataType(DataType.EmailAddress, ErrorMessage = &quot;L\u00fctfen uygun formatta e-posta adresi giriniz.&quot;)]\r\n        &#x5B;Display(Name = &quot;E-Posta &quot;)]\r\n        public string Email { get; set; }\r\n        &#x5B;Required(ErrorMessage = &quot;L\u00fctfen \u015fifreyi bo\u015f ge\u00e7meyiniz.&quot;)]\r\n        &#x5B;DataType(DataType.Password, ErrorMessage = &quot;L\u00fctfen uygun formatta \u015fifre giriniz.&quot;)]\r\n        &#x5B;Display(Name = &quot;\u015eifre&quot;)]\r\n        public string Password { get; set; }\r\n        \/\/\/ &lt;summary&gt;\r\n        \/\/\/ Beni hat\u0131rla...\r\n        \/\/\/ &lt;\/summary&gt;\r\n        &#x5B;Display(Name = &quot;Beni Hat\u0131rla&quot;)]\r\n        public bool Persistent { get; set; }\r\n        public bool Lock { get; set; }\r\n    }\r\n<\/pre>\n<p>Bu viewmodele g\u00f6z atarsan\u0131z e\u011fer giri\u015f yapacak kullan\u0131c\u0131n\u0131n e-posta adresini ve \u015fifresini bar\u0131nd\u0131rmakla birlikte &#8220;Persistent&#8221; ve &#8220;Lock&#8221; isminde iki adet bool tipinde propertyde bar\u0131nd\u0131rmaktad\u0131r. Bu dikkat \u00e7ekici model elemanlar\u0131n\u0131n s\u0131ras\u0131yla ne olduklar\u0131na de\u011finirsek e\u011fer; &#8220;Persistent&#8221;, cookie konfig\u00fcrasyonlar\u0131nda Expiration de\u011feri olarak verilen vade s\u00fcresinin olu\u015fturulacak cookie i\u00e7in ge\u00e7erli\/aktif olup olmamas\u0131n\u0131 tutmakta, &#8220;Lock&#8221; \u00f6zelli\u011fi ise kullan\u0131c\u0131n\u0131n belirli say\u0131da yapm\u0131\u015f oldu\u011fu oturum giri\u015fi hatalar\u0131nda ilgili user profilinin kilitlenip kilitlenmeyece\u011fini tutmaktad\u0131r.<\/p>\n<p>Evet&#8230; Art\u0131k uygulamam\u0131zda Cookie bazl\u0131 kimlik do\u011frulamay\u0131 kullanabiliriz.<\/p>\n<h3>Login Action Metodunun Tasarlanmas\u0131 ve SignInManager S\u0131n\u0131f\u0131n\u0131n Tan\u0131mlanmas\u0131<\/h3>\n<p>Uygulamada giri\u015f sorumlulu\u011funu \u00fcstlenecek olan bir &#8220;Login&#8221; action metodu tasarlamam\u0131z gerekmektedir. Bunun i\u00e7in yukar\u0131daki &#8220;Startup.cs&#8221; dosyas\u0131n\u0131n 24. sat\u0131r\u0131nda belirtildi\u011fi gibi \u00f6nceden(\u00f6nceki i\u00e7eriklerde) olu\u015fturdu\u011fumuz &#8220;User(Controller).cs&#8221; controller s\u0131n\u0131f\u0131n\u0131 kullanaca\u011f\u0131z. Tabi siz isterseniz kendinize \u00f6zel farkl\u0131 bir controllerda \u00e7al\u0131\u015fmalar\u0131n\u0131z\u0131 ger\u00e7ekle\u015ftirebilirsiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UserController : Controller\r\n    {\r\n        readonly UserManager&lt;AppUser&gt; _userManager;\r\n        readonly SignInManager&lt;AppUser&gt; _signInManager;\r\n        public UserController(UserManager&lt;AppUser&gt; userManager, SignInManager&lt;AppUser&gt; signInManager)\r\n        {\r\n            _userManager = userManager;\r\n            _signInManager = signInManager;\r\n        }\r\n        public IActionResult Login(string ReturnUrl)\r\n        {\r\n            TempData&#x5B;&quot;returnUrl&quot;] = ReturnUrl;\r\n            return View();\r\n        }\r\n\r\n        &#x5B;HttpPost]\r\n        public async Task&lt;IActionResult&gt; Login(LoginViewModel model)\r\n        {\r\n            if (ModelState.IsValid)\r\n            {\r\n                AppUser user = await _userManager.FindByEmailAsync(model.Email);\r\n                if (user != null)\r\n                {\r\n                    \/\/\u0130lgili kullan\u0131c\u0131ya dair \u00f6nceden olu\u015fturulmu\u015f bir Cookie varsa siliyoruz.\r\n                    await _signInManager.SignOutAsync();\r\n                    Microsoft.AspNetCore.Identity.SignInResult result = await _signInManager.PasswordSignInAsync(user, model.Password, model.Persistent, model.Lock);\r\n\r\n                    if (result.Succeeded)\r\n                        return Redirect(TempData&#x5B;&quot;returnUrl&quot;].ToString());\r\n                }\r\n                else\r\n                {\r\n                    ModelState.AddModelError(&quot;NotUser&quot;, &quot;B\u00f6yle bir kullan\u0131c\u0131 bulunmamaktad\u0131r.&quot;);\r\n                    ModelState.AddModelError(&quot;NotUser2&quot;, &quot;E-posta veya \u015fifre yanl\u0131\u015f.&quot;);\r\n                }\r\n            }\r\n            return View(model);\r\n        }\r\n\r\n        .\r\n        .\r\n        di\u011fer actionlar\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer &#8220;Login&#8221; action\u0131n\u0131n GET metodunda &#8220;ReturnUrl&#8221; parametresi al\u0131nm\u0131\u015f ve TempData kontrol\u00fcne atanm\u0131\u015ft\u0131r. Bunun nedeni, Identity mekanizmas\u0131 herhangi bir kullan\u0131c\u0131n\u0131n yetkisinin olmad\u0131\u011f\u0131 sayfalara eri\u015fmeye yahut yetkisi d\u0131\u015f\u0131nda bir i\u015f yapmaya \u00e7al\u0131\u015ft\u0131\u011f\u0131nda otomatik bir \u015fekilde direkt olarak &#8220;Login&#8221; action\u0131na y\u00f6nlendirecektir. \u0130\u015fte bu actionda veritaban\u0131yla tutarl\u0131 veriler e\u015fli\u011finde bir do\u011frulama ger\u00e7ekle\u015ftirilirse e\u011fer kullan\u0131c\u0131y\u0131 ilk gitmek istedi\u011fi adrese y\u00f6nlendirmekteyiz.<\/p>\n<p>&#8220;Login&#8221; action\u0131n\u0131n POST metoduna g\u00f6z atarsak e\u011fer 21. sat\u0131rda kullan\u0131c\u0131dan gelen email adresine uygun olan bir user varsa \u00e7ekilmekte ve 25. sat\u0131rda ilgili kullan\u0131c\u0131ya ait \u00f6nceden olu\u015fturulmu\u015f olan cookieler varsa da temizlenmektedir. 26. sat\u0131rda ise kullan\u0131c\u0131ya SignInManager s\u0131n\u0131f\u0131n\u0131n PasswordSignInAsync metoduyla oturum a\u00e7mas\u0131na izin vermekteyiz.<\/p>\n<p><strong>Peki nedir bu SignInManager s\u0131n\u0131f\u0131?<\/strong><br \/>\nKullan\u0131c\u0131n\u0131n giri\u015f ve \u00e7\u0131k\u0131\u015flar\u0131n\u0131 kontrol eden bir s\u0131n\u0131ft\u0131r.<\/p>\n<p>Devam\u0131nda ise kullan\u0131c\u0131 taraf\u0131ndan girilen email adresinin yanl\u0131\u015f olma durumunda 33 ve 34. sat\u0131rlarda ModelState&#8217;e error olarak ilgili hata mesajlar\u0131 eklenmekte ve b\u00f6ylece kullan\u0131c\u0131ya bilgi verilmektedir.<\/p>\n<p>Ayriyetten; 26. sat\u0131ra tekrardan g\u00f6z atarsan\u0131z e\u011fer SignInManager s\u0131n\u0131f\u0131n\u0131n PasswordSignInAsync metodunun 3. parametresine true verildi\u011fi taktirde olu\u015fturulacak cookie de\u011ferinin Expiration olarak belirtilen vade kadar tutulaca\u011f\u0131n\u0131 ifade etmekte aksi taktirde session a\u00e7\u0131k kald\u0131\u011f\u0131 s\u00fcrece coockie de\u011ferlerinin kullan\u0131labilece\u011fini lakin browser kapat\u0131ld\u0131\u011f\u0131 vakit cookielerin temizlenece\u011fini ifade etmektedir.. 4. parametrede ise ba\u015far\u0131s\u0131z neticelenen n adet giri\u015f denemelerinde ilgili kullan\u0131c\u0131n\u0131n hesab\u0131n\u0131n kilitlenip kilitlenmeme durumunu kontrol etmi\u015f oluyoruz. Bu konuyu makalemizin ileriki sat\u0131rlar\u0131nda ayr\u0131ca ele alacak ve detayland\u0131raca\u011f\u0131z.<\/p>\n<p>Velhas\u0131l olu\u015fturdu\u011fumuz &#8220;Login&#8221; action\u0131n\u0131n view g\u00f6r\u00fcnt\u00fcs\u00fcn\u00fc a\u015fa\u011f\u0131daki gibi tasarlayal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n@model AspNetCoreIdentityExample.Models.ViewModels.LoginViewModel\r\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\r\n&lt;h4&gt;Giri\u015f Yap&lt;\/h4&gt;\r\n&lt;hr \/&gt;\r\n&lt;form asp-action=&quot;Login&quot;&gt;\r\n    &lt;table&gt;\r\n        &lt;tr&gt;\r\n            &lt;td colspan=&quot;3&quot;&gt;&lt;div asp-validation-summary=&quot;All&quot;&gt;&lt;\/div&gt;&lt;\/td&gt;\r\n        &lt;\/tr&gt;\r\n        &lt;tr&gt;\r\n            &lt;td&gt;&lt;label asp-for=&quot;Email&quot;&gt;&lt;\/label&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;input asp-for=&quot;Email&quot; \/&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;span asp-validation-for=&quot;Email&quot;&gt;&lt;\/span&gt;&lt;\/td&gt;\r\n        &lt;\/tr&gt;\r\n        &lt;tr&gt;\r\n            &lt;td&gt;&lt;label asp-for=&quot;Password&quot;&gt;&lt;\/label&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;input asp-for=&quot;Password&quot; \/&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;span asp-validation-for=&quot;Password&quot;&gt;&lt;\/span&gt;&lt;\/td&gt;\r\n        &lt;\/tr&gt;\r\n        &lt;tr&gt;\r\n            &lt;td&gt;&lt;label asp-for=&quot;Persistent&quot;&gt;&lt;\/label&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;input asp-for=&quot;Persistent&quot; \/&gt;&lt;\/td&gt;\r\n            &lt;td&gt;&lt;span asp-validation-for=&quot;Persistent&quot;&gt;&lt;\/span&gt;&lt;\/td&gt;\r\n        &lt;\/tr&gt;\r\n        &lt;tr&gt;\r\n            &lt;td colspan=&quot;3&quot;&gt;&lt;input type=&quot;submit&quot; value=&quot;Giri\u015f Yap&quot; \/&gt;&lt;\/td&gt;\r\n        &lt;\/tr&gt;\r\n    &lt;\/table&gt;\r\n&lt;\/form&gt;\r\n<\/pre>\n<h3>Authorize Attribute&#8217;u \u0130le Yetki Kontrol\u00fc<\/h3>\n<p>Art\u0131k uygulamam\u0131zda cookie bazl\u0131 kimlik do\u011frulamas\u0131 tam olarak in\u015fa edilmi\u015f bulunmaktad\u0131r. Dolay\u0131s\u0131yla bu safhadan itibaren sayfa bazl\u0131 yetki kontrol\u00fc ger\u00e7ekle\u015ftirmemiz yeterli ve yerinde olacakt\u0131r. Bunun i\u00e7in Authorize attributeunun kullan\u0131lmas\u0131 yeterlidir. Burada \u00f6rneklendirme i\u00e7in &#8220;User(Controller).cs&#8221; controller\u0131 alt\u0131nda &#8220;Index&#8221; action\u0131n\u0131 se\u00e7iyorum ve a\u015fa\u011f\u0131da oldu\u011fu gibi Authorize attributeu ile i\u015faretliyorum.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UserController : Controller\r\n    {\r\n        readonly UserManager&lt;AppUser&gt; _userManager;\r\n        readonly SignInManager&lt;AppUser&gt; _signInManager;\r\n        public UserController(UserManager&lt;AppUser&gt; userManager, SignInManager&lt;AppUser&gt; signInManager)\r\n        {\r\n            _userManager = userManager;\r\n            _signInManager = signInManager;\r\n        }\r\n\r\n        &#x5B;Authorize]\r\n        public IActionResult Index()\r\n        {\r\n            return View(_userManager.Users);\r\n        }\r\n        .\r\n        .\r\n        .\r\n        di\u011fer actionlar\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p>Bu i\u015flemden sonra ilgili sayfaya giri\u015f yapmaks\u0131z\u0131n girmeye \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131zda a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere &#8220;user\/login&#8221; dizinine y\u00f6nlendirme yapacakt\u0131r.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11909\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX.gif\" alt=\"Asp.NET Core Identity - Cookie Bazl\u0131 Kimlik Do\u011frulama - IX\" width=\"600\" height=\"503\" \/><\/a><\/p>\n<p><em>Peki giri\u015f(login) yapt\u0131\u011f\u0131m\u0131zda ne oluyor?<\/em> diye sorarsan\u0131z e\u011fer onunda cevab\u0131n\u0131 a\u015fa\u011f\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fc vermektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX-1.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11914\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX-1.gif\" alt=\"Asp.NET Core Identity - Cookie Bazl\u0131 Kimlik Do\u011frulama - IX\" width=\"600\" height=\"470\" \/><\/a><\/p>\n<p>Yukar\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcn\u00fc incelerseniz e\u011fer taray\u0131c\u0131ya sa\u011f t\u0131klayarak &#8220;\u0130ncele&#8221; dedikten sonra &#8220;Application&#8221; sekmesini a\u00e7t\u0131\u011f\u0131n\u0131zda sol tarafta \u00e7\u0131kan men\u00fc \u00fczerinden &#8220;Cookies&#8221; sekmesinde uygulamam\u0131za ait cookieleri g\u00f6rebilmekteyiz. Dikkat ederseniz uygulama login yapt\u0131\u011f\u0131 taktirde Startup.cs dosyas\u0131nda modifiye etti\u011fimiz CookieBuilder nesnesindeki &#8220;AspNetCoreIdentityExampleCookie&#8221; name de\u011ferini verdi\u011fimiz bir cookie olu\u015fturulmu\u015ftur. Bunun d\u0131\u015f\u0131nda login i\u015fleminden \u00f6nce Identity Asp.NET Core uygulamas\u0131 taraf\u0131ndan eklenen varsay\u0131lan cookieler mevcuttur. Bunlar <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-mvcde-csrfxsrfcross-site-request-forgery-saldiri-guvenligi\/\" target=\"_blank\" rel=\"noopener noreferrer\">Asp.NET MVC\u2019de CSRF\/XSRF(Cross-Site Request Forgery) Sald\u0131r\u0131 G\u00fcvenli\u011fi<\/a> ile alakal\u0131 \u00f6nlemler \u00fczerine yap\u0131lm\u0131\u015f mimarisel \u00e7al\u0131\u015fmalard\u0131r.<\/p>\n<p>E\u011fer ki &#8220;Application&#8221; penceresindeki bu cookieleri manuel silersek uygulama logout yapm\u0131\u015f olacakt\u0131r. Bunun i\u00e7in ise &#8220;User(Controller).cs&#8221; controller\u0131nda ayriyetten bir &#8220;Logout&#8221; isminde action metot tasarlayarak bu i\u015flemi daha da programatize edebiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class UserController : Controller\r\n    {\r\n        readonly UserManager&lt;AppUser&gt; _userManager;\r\n        readonly SignInManager&lt;AppUser&gt; _signInManager;\r\n        public UserController(UserManager&lt;AppUser&gt; userManager, SignInManager&lt;AppUser&gt; signInManager)\r\n        {\r\n            _userManager = userManager;\r\n            _signInManager = signInManager;\r\n        }\r\n\r\n        public async Task&lt;IActionResult&gt; Logout()\r\n        {\r\n            await _signInManager.SignOutAsync();\r\n            return RedirectToAction(&quot;Index&quot;);\r\n        }\r\n        .\r\n        .\r\n        .\r\n        di\u011fer actionlar\r\n        .\r\n        .\r\n        .\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX-2.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11921\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Asp.NET-Core-Identity-Cookie-Bazl\u0131-Kimlik-Do\u011frulama-IX-2.gif\" alt=\"Asp.NET Core Identity - Cookie Bazl\u0131 Kimlik Do\u011frulama - IX\" width=\"600\" height=\"429\" \/><\/a><\/p>\n<p>Sonu\u00e7 olarak Asp.NET Core Identity mekanizmas\u0131nda Cookie bazl\u0131 kimlik do\u011frulamas\u0131n\u0131 t\u00fcm detaylar\u0131yla ger\u00e7ekle\u015ftirmi\u015f olduk. Bir sonraki i\u00e7eri\u011fimizde belli bir say\u0131da ba\u015far\u0131s\u0131z oturum a\u00e7ma durumlar\u0131nda hesab\u0131na girmeye \u00e7al\u0131\u015fan ilgili kullan\u0131c\u0131n\u0131n hesab\u0131n\u0131n sonraki giri\u015fleri do\u011fru bilgilerle dahi olsa nas\u0131l kilitlenece\u011fini ele alaca\u011f\u0131z.<\/p>\n<p>O halde \u015fimdilik g\u00f6r\u00fc\u015fmek \u00fczere \ud83d\ude42<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<br \/>\nNot : \u00d6rnek projeyi indirmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/AspNetCoreIdentityExample-6.zip\">buraya t\u0131klay\u0131n\u0131z.<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde; art\u0131k Asp.NET Core Identity yaz\u0131 dizimizde s\u0131ra Cookie bazl\u0131 kimlik do\u011frulama mekanizmas\u0131n\u0131 in\u015fa etmeye geldi\u011finden dolay\u0131 web uygulamam\u0131zda kullan\u0131c\u0131 do\u011frulama kontrol\u00fcn\u00fcn Cookie mekanizmas\u0131yla nas\u0131l yap\u0131land\u0131r\u0131ld\u0131\u011f\u0131n\u0131 inceleyecek ve uygulamal\u0131 olarak \u00f6rneklendirece\u011fiz. Yine&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":11583,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2668,2656,2811,2832,2898],"tags":[2952,3000,2997,2998,2999],"class_list":["post-11861","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asp-net-core-2","category-asp-net-core-2-mvc","category-asp-net-core-2-1","category-asp-net-core-2-2","category-asp-net-core-3-0","tag-asp-net-core-identity","tag-authorize","tag-cookie-bazli-kimlik-dogrulama","tag-identity-cookie-bazli-kimlik-dogrulama","tag-signinmanager"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11861","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=11861"}],"version-history":[{"count":62,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11861\/revisions"}],"predecessor-version":[{"id":11933,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11861\/revisions\/11933"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/11583"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=11861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=11861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=11861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}