Merhabalar,
Başlığı biraz açıklamak gerekirse, controller’lara erişebilme yetkisini rol bazlı olarak verdiğimizde sadece o role sahip kişiler ilgili controller’ların fonksiyonlarından faydalanır fakat yetkili olmadığı bir controller a istekte bulunduğunda veya olmayan bir action a veya controller a istek gönderdiğindeki durumları inceliyor olacağız.
Mesela,Admin controller’ına “2000” rolündeki kişi, User controller’ına da “3000” rolündeki kişi erişebiliyor olsun. Örnek olarak controller’lar öznitelikleri ile birlikte aşağıdaki gibi görünür bu durumda;
[Authorize(Role= “3000”)]
public class UserController : Controller
[Authorize(Role= “2000”)]
public class AdminController : Controller
Bu rol bazlı yetkilendirme de eğer yetkisiz biri istekte bulunursa ona yetkisi olmadığına dair bir hata sayfasını cevap olarak döndüreceğiz. Dolayısıyla Authorize attribute’ü miras alarak senaryomuza uygun bir şeyler karalayalım.
public class CustomAuthorize : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (this.AuthorizeCore(filterContext.HttpContext)) { // yetkili olduğu sayfada ise herhangi bir değişiklik yapmıyoruz. // yetkili olduğu sayfaya direkt girebilir sonuçta,başka bir sayfaya yönlendirmeyeceğiz. base.OnAuthorization(filterContext); } else { // orada yetkili değilse ya yetkili olduğu sayfaya geri gönderiyoruz // yada yetkisiz olduğuna dair error page i istemciye gönderiyoruz. var _urlReferrer = filterContext.HttpContext.Request.UrlReferrer; if (_urlReferrer != null) { string _redirectUrl = "~" + _urlReferrer.LocalPath; filterContext.Result = new RedirectResult(_redirectUrl); } else { // direkt url den talebi göndermiş demektir. filterContext.Result = new RedirectResult("~/WorkFlow/Processor/UnAuthorized"); } } } }
Authorize niteliğini kendimize göre uyarladığımıza göre controller’larda aşağıdaki değişikliği yapabiliriz.
[CustomAuthorize(Role= “3000”)]
public class UserController : Controller
[CustomAuthorize(Role= “2000”)]
public class AdminController : Controller
Öncelikle uygulama ayağa kalkarken neler oluyor ona bir bakalım.
1.Uygulamanmzı çalıştırdığınızda ilk olarak HttpApplication sınıfından türetilmiş global.asax dosyamız içerisindeki event’lardan Application_Start() çalışır.
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); }
Burada ilk olarak web dosyamız içerisinde oluşturduğumuz area ile ilgili route yönlendirmelerini area adını vs alır. İkinci olarakta RouteConfig sınıfımız içerisinde uygulama ayağa kalkarken default olarak verdiğimiz route ayarlarını alır.
2. Yukarıdaki yapılandırmaları aldıktan sonra ikinci olarak startup.cs dosyanıza gider. Burada kimlik doğrulama tipini ve local url gibi ayarları alır.
3. Üçüncü olarak Application_BeginRequest() event ı çalışır. Bu aşamada login sayfası için yada normal sayfa yüklemesi için ilk sayfanın çağrılmış demek olduğunu anlıyoruz.
4. Bu aşamada controller’a yönelir, eğer controller’ın çağrıldığı sırada herhangi bir eylem yürütmek istemediyseniz,yani Authorization, ActionAttribute vs gibi öznitelikler kullanmadıysanız,yapıcı (constructor) metot çalışır.
5. Bu aşamada da Application_EndRequest() event ı çalışır. Bu aşamaya geldiğinde action’ın yönlendirdiği sayfa çoktan taranmış olur ve sayfa kullanıcıya gösterilmeden önceki son ayarları burada yapabilirsiniz. Bu aşamadan sonra sayfa kullanıcıya gösterilmiş olur.
Şimdi gelelim kullanıcılar login olduktan sonraki işlemlerinde yaşanabilecek sorunlara. User kullanıcısı yukarıdaki senaryoya göre Admin controller’ına önce url’den sonra da bir butonun altına koyduğumuz link yardımıyla talep gönderdiğinde,bu yönlendirmeleri nasıl yapacağına göz atalım.
1-) URL’den yetkili olmadığı controller a girilmek istendiğinde;
İlk olarak istek Application_BeginRequest() event ına gelir,çünkü sayfa istekleri ilk olarak global.asax ta beginrequest event ında karşılanır. Buradaki işlemini gerçekleştirdikten sonra istek yaptığı controller’ın varsa constructor metotuna gider. Sonraki aşamada ise kişiselleştirdiğimiz öznitelik olan CustomAuthorize sınıfına geçer.
Bu sınıfta OnAuthorization metotunu override etmiştik. Bu metot AuthorizationContext sınıfından bir örnek alır. Bu örnek controller, HTTP context, request context, action result ve route data ile ilgili bilgileri içerisinde ihtiva eder. AuthorizeAttribute sınıfı içerisindeki AuthorizeCore methodu ile kullanıcının otorize olup olmadığını kontrol ediyoruz. Bu method HttpContextBase tipinde veri alır, bu context server, session, request, user ve application ile ilgili verileri parametrelerinde tutar. Eğer request i gönderen kullanıcının rolü controller daki rol ile uyuşuyorsa true değeri döner ve istekte bulunduğu sayfanın görüntülenmesine izin verir.
Yetkili olunmadığı controller a bu istek yapıldığından false değeri döner ve else kısmından devam ediyoruz açıklamaya.
var _urlReferrer = filterContext.HttpContext.Request.UrlReferrer; // satırı ile isteğin url den mi yoksa bir event sonrası mı geldiğini anlayabiliriz. Parametremiz null değer alıyorsa istek url den gelmiş demektir, url den gelen istekleri kendi hazırladığımız sayfaya yönlendiriyoruz.

new RedirectResult(“~/WorkFlow/Processor/UnAuthorized”) ile gelen isteği başka bir url e yönlendiriyoruz ve yukarıdaki gibi bir çıktı alıyoruz.
2-) Sayfa üzerindeki elementler ile etkileşimde yetkili olmadığı controller a girilmek istendiğinde;
İkinci olarak bu sefer bir anchor elementinin href inde bu url i tanımlayarak verelim.

Normalde kimse yetkilendirme sürecini buradan kontrol etmez, benim rolüm ne ise view’de de ona göre web sayfası bana gösterilir. Yani ben admin isem kullanıcı sayfasındaki verileri manipüle etme yetkim yok ise oraya erişim butonunu kimse koymaz nasıl olsa rolü uygun değilse geri gönderirim diye. Şöyle bir şey olabilir,html e sağ tıklayıp url değiştirilip admin tarafına isteği oradan başlatmak isteyebilirler. Karşı taraf sadece url den gelen istekleri kontrol etmiş olabilir nasıl olsa herkes html den link değiştirmeyi bilmiyor diye. Gibi bir sürü senaryo olabilir,biz bizim senaryomuz gereği Admin kullanıcının görebileceği bir sayfa olan izleme sayfasına erişim linkini user rolündeki kullanıcıya da verdik. Kullanıcı da buna tıkladı ;
İstek yine ilk olarak Application_BeginRequest() event ına gider sonrasında ise istekte bulunduğu controller ın varsa yapıcı metotuna gider. İçerisindeki kodları debug ettikten sonra kişiselleştirdiğimiz authorize attribute üne yönelir. Yine AuthorizeCore metotumuz içerisinde gönderdiğimiz context ile kullanıcının otorize olup olmadığını kontrol eder değilse false döndürerek işleme else den sonra devam ettemizi sağlar.
var _urlReferrer = filterContext.HttpContext.Request.UrlReferrer; // satırı ile bu sefer isteği yapan taraftaki orjinal url path ini alırız. Yani Admin tarafına bu istek yapılmadan önce isteğin kullanıcı hangi otorize olduğu sayfada geziyordu ise bu url i alıyoruz.
string _redirectUrl = “~” + _urlReferrer.LocalPath;
filterContext.Result = new RedirectResult(_redirectUrl); // satırları ile de geldiği sayfaya geri gönderiyoruz.
3-) Url üzerinden, olmayan controller veya olmayan action a (metota) istekte bulunma
Normalde kullanıcı login olduğunda http://localhost:10801/WorkFlow/User sayfasına yönleniyordu,biz /Trace yazarak isteği takip edeceğiz ve kendi özelleştirdiğimiz hata sayfasına yönlendirme yapacağız. İstek ilk olarak Application_BeginRequest() e gelir,controller ın yapıcı metotunu çalıştırır,sonrada istekte bulunduğu action bulamadığı için isteği bitirmek üzere Application_EndRequest() event ını çalıştırır. Biz bu event’ta şu kodlar ile kontrol ediyorduk gelen istekleri ;
protected void Application_EndRequest(object sender, EventArgs e) { HttpApplication application = (HttpApplication)sender; var customErrors = (CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors"); var accessDeniedPath = ""; if (application.Response.StatusCode == 404) { accessDeniedPath = customErrors.Errors["404"] != null ? customErrors.Errors["404"].Redirect : customErrors.DefaultRedirect; } if (string.IsNullOrEmpty(accessDeniedPath)) { return; } application.Response.ClearContent(); application.Server.MapPath(accessDeniedPath); application.Response.Redirect(accessDeniedPath); }
Metota gelen sender parametresini HttpApplication sınıfından alınan örneğe cast ederek alıyoruz. Böylece application parametremizde cevap olarak dönen http code u görebiliriz.
var customErrors = (CustomErrorsSection)ConfigurationManager.GetSection
(“system.web/customErrors”); // satırı ile web.config dosyamız içerisinde system.web tag inin altındaki customErrors tag ine ulaşabiliyoruz.
Peki bizim web.config dosyamızda o tag de neler var;
< customErrors mode="RemoteOnly" > < error statusCode="404" redirect="~/WorkFlow/Processor/Error404" /> </ customErrors>
redirect attribute’ünde statusCode 404 olduğundaki yönlendirileceği sayfanın linki var.
accessDeniedPath = customErrors.Errors[“404”] != null ? customErrors.Errors[“404”].Redirect : customErrors.DefaultRedirect; // bu satırda error element tag inin redirect attribute ünde tanımlı olan linki alıyoruz.
application.Response.ClearContent();
application.Server.MapPath(accessDeniedPath); application.Response.Redirect(accessDeniedPath); // bu satırlarda da önce response içindeki içeriği boşaltıyoruz,sonra browser da yazan url’i verdiğimiz linkteki gibi görünmesini istediğimiz için MapPath içerisine error linkimizi gönderiyoruz,son olarakta sayfayı redirect’ten aldığımız localpath e yönlendiriyoruz.

Öyle işte,biraz konu konuyu açtı gibi oldu ama derdimi anlattım sanırım 🙂
İyi çalışmalar.
Merhaba, emeğiniz için teşekkürler.Kodların bulunduğu alan arka planı ve yazı rengi beyaz olduğundan metni seçmeden kodlar görünmüyor. Bu konuyla ilgili geri bildirim yapmak istedim. İyi çalışmalar dilerim.
BeğenBeğen