Asp.Net Core Login - Cookie Olaylarinda Yardim
-
unbalanced bunu yazdı
@DrKill hocam istersen baglanip bakabilirsin yani hatayi bulabilirim diyorsan makine seni bekliyor :)
@ontedi en basit haliyle cözmek istiyorum aslinda hocam. Daha önce actionfilter kullanmadim ama sanirim middleware gibi calisiyor. Aslinda cookie vs ile isim yok ama bu login bilgisi cookie'de tutuluyor.
Benim anlamadigim notka su, neden bu kadar karisik. Yani authentication yaptiktan sonra login menü item'ini gizlemem lazim ama girdigim sayfaya göre (action), context'de user identity var veya yok.. Yani ben mi yanlis yapiyorum acaba yoksa bu böyle mi calisiyor. Cookie olusuyorsa zaten bunu neden her yerde kullanamiyorum onu anlamis degilim.
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.User = result.Principal;su kod isimi görüyor ama her metoda bunu yazmak istemiyorum. ActionFitler de sart degilse onu da yapmak istemiyorum ben direk HttpContext.User.Identity üzerinden ulasmak istiyorum (yukaridaki kodu yazmadan).
şu tarz bir auth koyduğunu düşünüyorum. Startup ı bir incele:
http://www.voidgeeks.com/tutorial/How-to-Add-Google-Authentication-in-ASPNET-Core-Application/17
Bir cevap buldum istersen bir dene:What fixed the false response for me was changing from;
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
to
var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);Eğer çokta olmazsa ya bir acrtionfilter üzerinden götür yetkilendirmeyi, ya da bir middleware yaz bu iş için.
DrKill tarafından 07/Şub/22 09:03 tarihinde düzenlenmiştir -
DrKill bunu yazdı
şu tarz bir auth koyduğunu düşünüyorum. Startup ı bir incele:
http://www.voidgeeks.com/tutorial/How-to-Add-Google-Authentication-in-ASPNET-Core-Application/17
Bir cevap buldum istersen bir dene:What fixed the false response for me was changing from;
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
to
var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);Eğer çokta olmazsa ya bir acrtionfilter üzerinden götür yetkilendirmeyi, ya da bir middleware yaz bu iş için.
linkteki startup'u kontrol ettim, bir kac eksik sey vardi onlari ekledim ama sonuc ayni hocam.
Paylastigin kodu zaten ben ilk mesajimda yazdim, o sekilde yapinca alabiliyorum ama ben onu direk her context'te görmek istiyorum problem o ve hala gelmiyor. Görünüse göre zaten actionfilter falan kullanmak gerek. Bir yerde bir hata var ama cözemedim
-
Hannibal_King bunu yazdı
Web uygulaması geliştirmemizi sağlayan bir frameworkten beklediğimiz en önemli şey; HTTP isteklerini nesneler ile temsil etmesidir. Ve biz bu nesnelere uygulama kodlarımız aracılığı ile erişebilmeliyiz. Bir HTTP isteği düz bir metin olabilir veya binary formda da olabilir. HTTP 1.1, 2.0 farketmez. Framework bu isteği alır parçalar ve C# tarafında belirli nesnelere yerleştirir. Ve hatta client a dönülecek olan HTTP isteğini de kolayca manipüle edebilelim diye onun içinde ayrı bir nesne oluşturur. Ve bizde yazılımcı olarak bu nesneler ile muhatap oluruz. Bütün bu işleme HTTP isteğini handle etmek(ele almak) diyebiliriz. Yani framework un ele alması.
İşte ASP.NET Core da bu işi HttpContext nesneleri ile çok güzel bir şekilde yapıyor. Biz HttpContext nesneleri sayesinde querystringlere, cookielere, ip adresine, routing bilgilerine kısaca HTTP mesajında ne varsa ona erişebiliyoruz. HttpContext nesnesinin request e özgü olduğunu unutmayalım. Her gelen istek için ayrı bir nesne gibi düşünebiliriz.
Uygulamanın farklı yerlerinden HttpContext nesnesine erişebilmek mümkün. Bazen bir viewdan, bazen controller içinden, bazen filters içinden, bazen bir middleware içinden HttpContext e erişmek isteyebiliriz. HttpContext nesnesine erişmemizi sağlayacak olan propertylerin veya değişkenlerin isimleri farklı olabilir. Örneğin View üzerinde HttpContext e erişmek istersek @ViewContext.HttpContext yazmamız gerekebilir. (property isimleri ASP.NET ve ASP.NET Core da değişkenlik gösterebiliyor.) Ancak yazılımcının temel amacı hep aynı: HttpContext e eriş ve gerekliyse manipüle et veya bir değeri oku.
Senin örneğe gelecek olursak;
*) Önce doğrudan problemi çözelim.
Herkesin erişebildiği bir action methodun ve bu action methodun çalışması sonucunda ortaya çıkan bir View var. Sen bu view üzerindeki bir alanı yani HTML kodunu duruma göre gizlemek veya göstermek istiyorsun.
1-) Projende Util isminde bir klasör aç. İçine MyBasePage isimli bir sınıf ekle. Bu sınıfı RazorPage sınıfından türet. (GÖRSEL 1) Bu sınıflar generic olacak.
https://bulutdoktor.notion.site/tbt-photo-9f98e1a436a64e51a509556ee4d78e7e tüm görsellere bu link üzerinden erişebilirsin.
2-) Bu sınıfın içine bir metot yaz ismine IsAuthenticated() diyebilirsin. GÖRSEL 2 de olduğu gibi içini kendince yaz. Sen burada auth-cookie olup olmadığına bakacaksın. Artık cookienin adı ne ise cookie varsa metodun true yoksa false dönecek.
Dikkat edersen RazorPage isimli sınıftan dahi HttpContext nesnesine erişebiliyoruz.
3-) GÖRSEL 3 te koyduğum gibi Views klasörünün altına doğrudan _ViewImports.cshtml isimli dosyayı oluştur.
4-) GÖRSEL 4 te olduğu gibi _ViewImports.cshtml içinde senin viewlarının 1.adımda oluşturduğun MyBasePage sınıfını dikkate alacaklarını söyle. Böylece MyBasePage sınıfındaki metotları tüm viewlarından kullanabileceksin.
5-) İstediğin view a git @if (IsAuthenticated()){ // HTML KODLARIN } yaz.
ideal çözüm bu.
*) Controller içinden o anki Request in sahibi olan User ın bilgilerine erişmek istersek ne yapacağız?
@MaviGozluDevün dediği gibi yapacağız. MyBaseController isimli bir controller oluşturup diğer tüm Controllerları MyBaseController dan türeteceğiz. MyBaseController içinde CurrentUser isimli bir property olabilir.
GÖRSEL 5 te kendi örneğimi attım. Burada rahat bir şekilde CurrentUser = context.HttpContext.Items["CurrentUser"] as OnlineUserData; yazmışım ben. Çünkü HttpContext.Items ın içine daha önceden Anahtarı "CurrentUser" olan ve değeride OnlineUserData türünden bir nesne olan itemi koymuşum. HttpContext.Items son derece önemlidir. Tüm pipeline boyunca veri taşımamızı sağlar.
Ben Controller'ın OnActionExecuting metodundan daha önce hazırladığım bu item'e erişiyorsam bunu nerede SET etmiş olabilirim. Mantıken Controller çalışmadan önce set etmem lazım. Evet öylede yaptım.
Kendim bir filtre yazdım. GÖRSEL 6 ya bakabilirsin.
*) Peki filtreler her zaman Controllerdan önce mi çalışır?
HAYIR. Hangi filtre olduğuna bağlı. Ben kendi örneğimde IAuthorizationFilter kullanmışım. Çünkü biliyorum ki bu filtre Controller dan önce çalışacak.
*) Filtre ne demek?
ASP.NET Core ve ASP.NET te bulunan özelleştirilmiş Attributelardır. Bizim gelen requeste belirli noktalarda müdahale etmemizi sağlar.
*) Filtre kavramı middleware kavramı gibi mi?
Hayır. Detaya girmiyim uzun sürer.
Authorize attribute kullanmayınca HttpContext.User boş geliyorsa demekki ilgili attribute o property yi dolduruyor. Normal bir durum. Pipeline, Filters vb. konular üzerine uzun uzun yazardım ama konu uzamasın çok. Umarım faydalı olur.
hocam cok cok tesekkür ederim aciklayici cevap icin. Bir cok sorumun cevabini buldum burda yani daha iyi anladim mantigini. Bu context'i ben bir kereye mahsus olarak düsündüm ama her request'te degismesi ilginc geldi ama icersinde request bilgilerini barindiriyorsa o zaman normaldir böyle olmasi.
Ben projede bir hata yapiyorum o yüzden olmadigini düsünüyorum. Yani sanki bir metod var ve ben o metodu cagirinca context user'in identity'si dolacakmis gibi ama öyle bir metod görmedim.
Görünen o ki senin söyledigin gibi base view ve base controller olusturup yapacagim. Biraz daha ugrasayim bugün, olmazsa yapacak bir sey yok. Vaktin olursa startup.cs'ye bakabilirsen sevinirim. hatta özelden yollayayim. Bir eksiklik mi var bilemedim
-
sorunu buldum sanirim. benim claims'leri ekledigim context, oauth'dan gelen context o da haliyle authorization ile iliskili.
Simdi startup'da anonymous'un httpcontext'ine nasil erisebilirim ki
oauth context'ine yazdigim context.RunClaimActions(user);
aynisini anonymous'a da yazayim. Böylece sorun cözülmüs olur.
IHttpContextAccessor'u singleton olarak ekledim ama Configure metodunda HttpContext null geliyor
public void ConfigureService(IServiceCollection services) { services.AddHttpContextAccessor(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IHttpContextAccessor accessor) { var aaa = accessor.HttpContext; // => null }bu context'e nasil ulabilirim startup.cs den? Bunu yapabilirsem sorun cözülmüs olacak gibi duruyor
@Hannibal_King 'in cevabina göre bu context request ile olusuyor ama en azindan bu context icin nasil cookie ekleyebilirim yani belki startup.cs den erisemem ama otomatik olarak bu (anonymous) contextlere'e nasil cookie olusturabilirim?
unbalanced tarafından 07/Şub/22 13:35 tarihinde düzenlenmiştir -
sonunda olayi cözdüm :)) kac saat harcadim kücücük bir sey icin, bir sürü sey ekle cikar falan filan.. deneme yoluyla buldum problemi.
Simdi benim anladigim kadariyla context'de identity'nin görünmesi icin SignIn yapilmasi gerekiyormus.
O yüzden 3.parti yazilimindan cevap geldiginde oradaki contextten identity aliyorum ve httpcontext üzerinden sign-in yapiyorum
var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, result.Principal);
Ancak buradaki SignIn bir türlü calismadi yani HttpContext.User'a baktigimda hep bostu anlamsiz yere. Onu cözmeyle ugrastim ve sorunu buldum
asagida AddAuthentication metodu var buradaki kismi youtube videosuna bakarak yapmistim.
services.AddAuthentication(options => { options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; })DefaultAuthenticateScheme a JwtBearerDefaults.AuthenticationScheme atamis ve sorun da burdan kaynaklaniyormus.
O kismi söyle degistirince
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
Basarili sekilde login olabildim ve HttpContext.User artik her metod da dolu geliyor :) Yani anonymous context'e sonunda yazdirdim istedigimi
Cevap veren, ilgilenen tüm arkadaslara cok tesekkür ederim. Ekstra filter, base class vs yazmama gerek kalmadi sükür gerci onlari da yapmistim ama bu sekil istedigim gibi oldu :)) Artik rahatca uyurum
unbalanced tarafından 08/Şub/22 04:35 tarihinde düzenlenmiştir -
Pipeline hakkında detaylıca yazacaktım hocam. Çok yoğundum yazamadım kusura bakma. Yarın müsait olursam 3-5 bir şey yazayım. Çözmene sevindim. Yarın detaylı bakarım yaptığın çözüme.
-
Hannibal_King bunu yazdı
Pipeline hakkında detaylıca yazacaktım hocam. Çok yoğundum yazamadım kusura bakma. Yarın müsait olursam 3-5 bir şey yazayım. Çözmene sevindim. Yarın detaylı bakarım yaptığın çözüme.
Çok sağol hocam. Yazdığın şeyler çok faydalı oldu öğrenmekten için. Bir çok insana eminim katkı sağlıyor
