Sayfalar

8 Ağustos 2013 Perşembe

ASP.NET MVC DERSLERİ ( 7.2 ) AUTHORIZE ATTRIBUTE VE ROL YETKİLENDİRME

Internet Application şablonunda yeni bir proje oluşturduğumuzda, SimpleMembershipProvider varsayılan olarak gelmektedir. Hiçbir değişiklik yapmadan direk olarak bu üyelik sistemini kullanabilirsiniz. Ama MVC ye yeni başlayanlar bu konuda çok fazla mesai harcıyorlar. SimpleMembershipProvider, code first olarak geliştirilmiştir. Genişletilebilir bir yapısı vardır. Bu derste kendi üyelik sistemimizi nasıl yapabiliriz bu konuya değineceğim.

Öncelikle, AuthorizeAttribute nesnesi role ve kullanıcıya göre nasıl yetkilendirilir bunu görelim. Örneğin;
[Authorize(Roles="Administrator")]
public class AdminController : Controller

şeklinde bir kullanımda, AdminController sınıfına sadece belirlenen rollerdeki kullanıcılar girebilir. Ayrıca kullanıcıya özel yetkilendirme de yapılabilir. Örneğin;
[Authorize(Users="ali,veli,ahmet,mehmet")]
public class KullaniciOzelController:Controller

şeklinde bir kullanımda, sadece belirlenen kullanıcılara özel bir yetkilendirme yapılır.

Bu tanımlamalar, hazır olan membershipProviderlar ile çalışacaktır. Ama bizim kendi kullanıcı ve rol tablolarımızı, bu nitelik ile nasıl kullanacağız.  Yani Authorize niteliği için Roles ve Users parametrelerini nasıl kullanacağız.

Bunun için override etmemiz gereken metodlar olacaktır. Örneğin haber istesi projesinde Kullanıcı ve Rol tablolarımız var. Bunları üyelik sisteminde nasıl kullanacağız.

  1. Kendi üyelik sağlayıcı sınıfımızı yazacağız.
  2. Kendi rol sağlayıcı sınıfımızı yazacağız.
  3. Bu sağlayıcıları, web.config dosyamızda tanımlayacağız.
Authorize, nitaliğinin Roles ve Users parametrelerini kullanmak için aşağıdaki metodları override etmemiz gerekiyor.

public class UyelikSaglayici : MembershipProvider
{    
   public override bool ValidateUser(string kullaniciAdi, string sifre)
   {            
   }
}
 
public class RolSaglayici : RoleProvider
{
   public override bool IsUserInRole(string kullaniciAdi, string rolAdi)
   {
   }
 
   public override string[] GetRolesForUser(string kullaniciAdi)
   {
   } 
}


Proje içerisinde ~/Uygulama/Uyelik klasörü içerisinde bu sınıflarımız mevcut. Bu sınıfları yazdıktan sonra, web.config içerisinde bu sağlayıcıları kullanacağımızı belirtmemiz gerekir. Bu arada, diğer metodları da isterseniz override edebilirsiniz. AuthorizeAttribute için yukarıdakiler yeterli olacaktır. 

web.config içerisindeki ayarlar:

<membership defaultProvider="UyelikSaglayici">
    <providers>
        <!--<add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />-->
        <add name="UyelikSaglayici" type="HaberSitesi.Web.Uygulama.Uyelik.UyelikSaglayici" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
    </providers>
</membership>
<roleManager defaultProvider="RolSaglayici" enabled="true">
    <providers>
        <add name="RolSaglayici" type="HaberSitesi.Web.Uygulama.Uyelik.RolSaglayici" connectionStringName="DefaultConnection" applicationName="/" />
    </providers>
</roleManager>


Böylece kendi üyelik sistemimizle bu nitelikleri tam manasıyla kullanabiliriz. Biraz karışık bir anlatım olmuş olabilir. Ama projeyi açık inceleme şansınız olursa sanırım daha iyi anlaşılacaktır. Anlaşılmayan kısımlar hakkında geri dönüş yapılırsa, elimden geldiği kadar anlatmaya çalışırım.



13 yorum:

  1. Merhaba,
    Haber Portalınıo yazarken, hangi mimariyi ve tasarım desenlerini kullandınız?

    YanıtlaSil
    Yanıtlar
    1. Tasarım deseni yok. Servis ve Data katmanları var. Data katmanında Repository yok. Eğitim amaçlı olduğundan ORM yi repository gibi kullandım. Şu an bir makale yazıyorum. Dependency Injection, IoC, Repository, Unit of Work desenlerinin kullanıldığı ve yine, servis ve veri katmanının oldugu bir yazı olacak. Tek makalede, full bir proje nasıl oluşturulur bundan bahsetmeye calısacagım. ama merak ettiğiniz bişey varsa sorabilirsiniz

      Sil
  2. Birde vs 2010 da çalışması için nasıl bir yol izlemeliyiz?

    YanıtlaSil
    Yanıtlar
    1. Onu tam olarak bilmiyorum hic araştırmadım. Müsait oldugumda bir araştırayım. Sizde bir yol bulursanız paylasırsınız.

      Sil
  3. Merhaba,
    Benim sorum biraz daha genel olucak; Sizin yaptığınız gibi kendim Role UserRoles tablolarını oluşturdum ve roleprovider olarak default role provider kullanmak istesem nasıl bi yol izlemeyelim ? Yani kendim yazmak istemiyorum sağlayıcıyı ama bu sefer User.IsInRole değeri yetkili olmasına rağmen false döndürüyor..

    YanıtlaSil
  4. Yazılarınız ve verdiğiniz emek için çok teşekkür ederim. Dependency Injection, IoC, Repository, Unit of Work desenleri, servis yönelimli mimari ve çok katmanlı mimariyi temel mantığından, neden ihtiyaç duyulduğuna, inebildiğiniz kadar derinliğine bir makale dizisi yazarsanız çok faydalı olacağına inanıyorum. Umarım yazacak zamanı bulabilirsiniz. Tekrar emeğinize sağlık, kolay gelsin...

    YanıtlaSil
  5. Merhaba,
    /Admin/Etiket/Etiketler şeklinde bir istek oluşturduğumda giriş yapmayan kullanıcılar için proje Uyelik Controller a yonlendirme yapıyor bunu nasıl sağladığınız?

    YanıtlaSil
    Yanıtlar
    1. Bu yorum yazar tarafından silindi.

      Sil
    2. https://github.com/alirizaadiyahsi/HaberSitesiV2/blob/master/HaberSitesi.Web/Web.config

      burada system.web altında, authentication diye bir ayar var. Buraya yönlenmesini istediginiz adresi yazıyorsunuz.

      Sil
    3. Ali bey bir sorum daha var. AnaController içersindeki OnActionExecuting metodu hep sürekli çalışıyor bir istekte. Mesela örneğin /Admin/Etiket/Etiketler istediğinde olduğu gibi. Ve bu çalışan metod içersnde ise sürekli servis e git gel yapılıyor. Bu metodu sadece 1 kez çalıştırma gibi bir arayış içersine girdiğiniz mi sorunu algılayıp. Eğer çözüm üretebildiyseniz paylaşabilirmisiniz?

      Sil
    4. O metod her zaman çalışır. ActionMetod zaten her istekte çalışmalı, amacı bu. Ama servise gitmesi mantıklı değil. Bunun için kullanıcının diğer verilerinide tutacak şekilde bir IPrincible yazmak gerekiyor. Yani bunu genişletmek gerekiyor. Additional User Data şeklinde aratırsanız, bu sorunu çözersiniz.

      Sil
    5. Evet bende zaten servise gitmesi konusunda demiştim. Tşkler bilgiler için.

      Sil