|
Web.config ile Rol Tabanlı Güvenlik |
|
Gönderiliyor lütfen bekleyin... |
|
|
Web
uygualamaları doğası gereği internet üzerinde çalıştığı için tüm internet kullanıcılarına
açıktır. Fakat bu açıklık bir sitenin tüm bölümlerine girmenizi sağlama. Yetki
durumunuza göre sitedeki içeriği görebilir ve yine site üzerinde bazı haklara
sahip olabilirsiniz. Gerçek hayatta da buna benzer yetkilere sahibizdir. Örneğin;
tatilinizi geçirmek için bir tatil köyüne gittiğinizi düşünün. Yaptığınız rezervasyona
ve istediğiniz hizmete göre bileğinize renkli künyeler takılır. Bu künyelerin
renklerine göre, fitness, yemek hizmeti, içecek hakkınız gibi bir takım haklara
sahip olursunuz. Eğer hakkınız yoksa fitness salonuna gidip spor yapamazsınız.
Web uygulamalarında da login sayfasından siteye giriş yaptığınızda, size daha
önce tanınmış haklara göre site içeriğini görüp, değiştirebilirsiniz.
Bu tip yetkilendirme ve kimlik denetimi işlemlerini ASP.NETden önce de yapabiliyorduk
.Bunlar karmaşık kimlik denetimi (Authentication) ve yetkilendirme (Authorization)
işlemleri gerektiriyordu. Çok daha fazla kod yazımı ve zaman kaybına yol açıyordu.
ASP.NET ile gelen Forms Authentication çok güçlü özellikleri , daha az kod ve
çaba ile ihtiyacınız olan karmaşık kimlik denetimi sağlıyor. aspnedir?.comda
yer alan birkaç makalede kimlik denetiminin nasıl gerçekleştiğini görebilirsiniz.
Ben bu makalede sizlere System.Web.Security ve System.Security.Principal
namespacelerinde yeralan bazı sınıfların rol tabanlı kimlik yönetiminde nasıl
kullanıldığını göstereceğim.
Öncelikle konuyu daha iyi anlayabilmeniz için uygulamamızın yapısısını görelim.
Yukarıdaki
şemamızda görüldüğü gibi ziyaretçi bölümü herkese açıktır.Buraya siteye login
olmadan (kimlik denetimi yapmadan ) herkes göreblir. Admin bölümü, Manager bölümü
ve User bölümüne login.aspx sayfamızdan giriş yaptıktan sonra veritabanında
yeralan user tablosundaki roles verisine göre yetkilendirme
yapılıp (Tatil köyü örneğindeki gibi kullanıcılara bir künye takılıyor gibi
düşünebilirsiniz) girilebiliyor.
Uygulamamızı
daha iyi anlayabilmeniz için aşağıda uygulamamızın dizin şemasını görebilirsiniz.
Root dizininde login.aspx, default.aspx, web.config, ve global.asax dosyalarımız
olacak. Admin, Manager ve User alt dizinlerimiz içinde birer tane default.aspx
ve web.config dosyalarımız yer alacak.
Uygulamamızın Veritabanı
Web uygulamamız için kimlik denetimi ve yetkilendirme işlemlerini yapabilmesi
için olmazsa olmazlardan bir tanesi olan veritabanı ve tablomuzu yaratalım.
Veritabanımızın adı aspnedir,
tablomuzun adı users. Tablomuzun
yapısı ise 3 bölüme ayrılmıştır; username, password
ve roles.
Bu üç sütun değerinin veri tipini nvarchar
olarak ayarlayın. Deneme amaçlı olarak tablomuzun verilerini şu şekilde doldurun:
login.aspx
Sayfamız
login.aspx
sayfamızın görüntüsü şu şekildedir.
LOGIN butonuna basıldığında çalışacak kod ise şudur. login.aspx.cs
dosyasına System.Data.SqlClient ve System.Web.Security
namespaceini yazmayı unutmayın.
private
void
Button1_Click(object sender, System.EventArgs
e)
{
// Connection nesnesi oluşturulup veitabanına bağlantı
gerçekleştiriliyor.
string connStr = "Initial Catalog=aspnedir;
Data Source=sekanet; User id=serkan; password=deneme;";
SqlConnection conn = new SqlConnection(connStr);
conn.Open(); //
Gerekli sorgu işlemleri yapılıyor.
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "Select roles From users Where username = @txtusername
AND password = @txtpassword";
cmd.Parameters.Add("@txtusername",SqlDbType.NVarChar,50).Value
= txtusername.Text;
cmd.Parameters.Add("@txtpassword",SqlDbType.NVarChar,50).Value
= txtpassword.Text;
SqlDataReader
dr;
dr = cmd.ExecuteReader();
if(dr.Read())
//Eğer Kullanıcı adı ve şifresi veritabanında kayıtlı
ise aşağıdaki işlermleri gerçekleştirir.
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
1, //Ticket versiyonu (şu andadaki güncel versiyon
1dir)
txtusername.Text, //ticket ile ilgili olan txtusername
DateTime.Now, //şu anki zamanı alıyor.
DateTime.Now.AddMinutes(30), //yaratılan cookienin
zamanını 30 dakika olarak ayarlıyor.
false, //yaratılan
cookienin IsPErsistent özelliğini false yapıyor.
dr.GetString(0),// kullanıcının rollerle ilgili
bilgisini alıyor.
FormsAuthentication.FormsCookiePath); // yaratılan
cookienin yolunu belirtiyor.
//
FormsAuthenticationTicket ile yaratılan cookieyi şifreliyoruz.
string encTicket = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,encTicket);
//
Eğer FormsAuthenticationTicket ile yaratılan cookienin expiration süresi
//sınırsız ise, bu cookieye ticket nesnesinin Expiration
süresi atanıyor.
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
Response.Cookies.Add(cookie);
//Eğer direkt olarak Browserınıza Admin/default.aspx
gibi bir sayfayı çağıracak olursanız,
//adres çubuğunda otomatik olarak yaratılan ReturnUrl ifadesini görürsünüz
//bu ifade login.aspx sayfasında login olduktan sonra çağırdığınız bir
önceki
//sayfaya otomatik olarak geri dönmenizi sağlar.
string returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "/RoleBasedFormsAuthentication/default.aspx";
Response.Redirect(returnUrl);
}
else
// Eğer kullanıcı adı ve şifresi veritabanındakilerle uyuşmuyorsa aşağıdaki
uyarı hatasını verir.
ErrorLabel.Text = "Yanlış Kullanıcı Adı veya Parola";
conn.Close();
}
|
Yukarıdaki
sayfamızda yer alan kod satırlarının arasına gerekli açıklamaları yaptığım için
ayrıca burada açıklama yapmayacağım. Yalnız burada benim yazdığım ConnectionString
(connStr) kendi veritabanımın özelliklerini yansıtıyor. Bu kodun aynısını kullanarak
kendi yarattığınız veritabanına bağlanmaya kalkışırsanız hata verecektir. Daha
önce SQL veritabanınıza nasıl bağlanıyorsanız ona göre bir ConnectionString
ifadesi yazın.
Global.asax
Dosyamız
Global.asax.cs dosyamızın başına System.Web.Security
ve System.Security.Principal namespacelerini ekliyoruz.
Global.asax.cs sayfamızın Application_AuthenticateRequest
metoduna aşağıdaki kod satırlarını yazalım.
protected
void Application_AuthenticateRequest(Object
sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is
FormsIdentity)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(,);
HttpContext.Current.User = new GenericPrincipal(id,
roles);
}
}
}
}
|
login.aspx sayfamızda yer alan kodlar çalıştırılıp kullanıcı Authenticate edildiği
zaman Global.asax sayfamızdaki Application_AuthenticateRequest metodu çağırılıyor.
Burada if döngüleriyle kullanıcı ile ilgili bilgiler alınıp, GenericPrincipal
metodu ile id ve veritabanından alınan roller atanıyor. Böylece dizinlere ayırdığımız
sayfalara girebilme hakkı elde ediliyor.
Şimdi sıra geldi kullanıcının login sayfasından geçtikten sonra hangi sayfaları
görebilme hakkına sahip olduğunu belirlemek için web.config sayfalarımızı inşa
edelim.
web.config
Uygulamamızın root klasörünün içinde yer alan web.config dosyamızı aşağıdaki
şekilde yapalım.
<?xml
version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation defaultLanguage="c#" debug="true"/>
<authentication mode="Forms">
<forms name=".ASPXROLEBASED"
loginUrl="login.aspx"
protection="All"
path="/"/>
</authentication>
<authorization>
<!-- Root dizininde yer alan tüm sayfaları public
yapıp her kullanıcıya erişim hakkı veriliyor.-->
<allow users="*"/>
</authorization>
</system.web>
<!-- Admin dizini için gerekli güvenlik ayarları
yapılıyor -->
<location path="Admin">
<system.web>
<authorization>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<!-- Manager dizini için gerekli güvenlik ayarları
yapılıyor -->
<location path="Manager">
<system.web>
<authorization>
<allow roles="Manager"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<!-- User dizini için gerekli güvenlik ayarları
yapılıyor -->
<location path="User">
<system.web>
<authorization>
<allow roles="User"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
</configuration> |
Sadece root klasöründe yer alan web.config sayfamızı bu şekilde inşa ederek
alt klasörlerde yer alan Admin, Manager ve User klasörümüzdeki sayfalara erişme
hakkını sadece tek bir web.config dosyasıyla halledebiliriz.
Yukarıda yer alan kodların içinden bir örnek alıp inceleyelim.
<location
path="Manager">
<system.web>
<authorization>
<allow roles="Manager"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
<location path="Manager" /> tagı arasında Manager
dizini içinde yer alan sayfalara erişim izinlerini ayarlarız.Aslında bu location
ifadesi ile dizin ayarlarını tek bir web.config dosyasında düzenleyebiliriz.
<allow roles="Manager" /> ifadesi bize yetki
düzeyi Manager olan kullanıcılar için giriş izni vermektedir.
<deny users="*" /> ifadesi ile de tüm kullanıcıları
baştan reddediyor.( * yerine ? kullanımı ise anonymous girişlerini reddediyor.)
Yine aynı şekilde diğer kod satırıda bu şekilde açıklanabilir. Eğer bu açıklamayı
anladıysanız Web.config dosyamızdaki buna benzer kod satırlarını da anlamanız
çok kolay olacaktır.
Admin/Web.config Dosyamız
Yukarıdaki şekilde web.config dosyamızı düzenlersek tek bir web.config ile tüm
dizinleri yönetebiliriz. Fakat ben bunun yerine her dizinde ayrı ayrı web.config
dosyaları oluşturarak dizinleri özelleştiriyorum. Bu şekilde yaparak uzun kod
satırları arasında dolaşarak kafa karışıklığınıda önlemiş oluyorum. Hemde uygulamamın
okunabilirliği daha da artıyor. Böylece her iki yöntemi de görüp istediğinii
uygulayabilirsiniz.
Admin içindeki web.config dosyamızı şu şekilde de hazırlayabiliriz.
<?xml
version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<allow roles="Admin"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration> |
Root dizinimizdeki web.config sayfamızdan bir farkı yok değil mi? Aynı şekilde
diğer alt dizinlerimizdeki web.config dosyalarımızı da yazalım.
Manager/Web.config
<?xml
version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<allow roles="Manager"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration> |
User/Web.config
<?xml
version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<allow roles="User"/>
<deny users="*"/>
</authorization>
</system.web>
</configuration> |
Yine sırasıya Admin , Manager ve User dizinimizde yeralan default.aspx sayfalarımızın
içine sırasıyla birer tane Label web kontrolü koyup
Text özelliğine yine sırasıyla, Admin Sayfası, Manager
Sayfası ve User Sayfası yazalım.
Daha sonra login sayfasına girdikten sonra kontrol amaçlı dizinlere giriş iznimizin
olup olmadığını anlamak için root klasörümüzün içinde default.aspx
sayfası hazırlayalım. Bu sayfaya 3 tane HyperLink
web kontrolü ekleyelim. Her HyperLink kontrolünün NavigateUrl
özelliğine sırasıyla Admin/default.aspx,
Manager/default.aspx ve User/default.aspx
linklerini verelim. Yine bu sayfanın içine güvenli çıkışı sağlamak için bir
tane Button yerleştirelim ve Buttonun Click
özelliğine şu kodu yazalım.
private
void
Button1_Click(object sender, System.EventArgs
e)
{
FormsAuthentication.SignOut(); //Yetkilendirme işlemini
sonlandırıyoruz.
Response.Redirect("default.aspx");
} |
Bu kod ile daha önce FormsAuthenticationTicket ile yaratılan cookie değerleri
yok oluyor. Böylece bir daha login olmadığınız sürece izniniz olmayan sayfaları
göremiyorsunuz.
Root dizindeki default.aspx sayfamızın
görüntüsü şu şekilde olmalıdır.
Şimdi sıra geldi uygulamamızı çalıştırmaya. Uygulamanızın root dizininde yer
alan default.aspx sayfasını browserınızdan çağırın . Daha sonra bu sayfada
yer alan herhangi bir linke tıklayın. login.aspx sayfasına yönlendirildiniz
değil mi? Çünkü Authenticate işlemini gerçekleştirmediğiniz için giriş izni
vermediğimiz dizinlerdeki sayfaları kesinlikle göremezsiniz.Bu yönlendirme işlemini
root dizinimizde yer alan web.config dosyamızın içinde belirtiyoruz. Şimdi login.aspx
sayfasından veritabanınızdaki tabloda bulunan kullanıcıların herhangi birisiyle
giriş yapın ve linklere tıklayın. Eğer izniniz yoksa bazı dizinlere giremediğinizi
ve otomatik olarak login.aspx sayfasına yönlendirildiğinizi görürsünüz. Eğer
giriş yaptıktan sonra default.aspx sayfasındaki LOGOUT
butonuna tıklarsanız. Tüm yetkilendirme ve kimlik denetimi işlemleriniz iptal
edilir ve bir daha login oluncaya kadar kimlik denetimi gerektiren dizinlerdeki
sayfaları göremezsiniz.
Örneğin login.aspx sayfasından veritabanımızdaki users tablosunda yer alan herhangi
bir kullanıcı adı ile girip, default.aspx sayfasında bulunan linklere tıkladığınızda
eğer izniniz varsa sayfa görüntüsü şu şekilde olur.
Bu makalemizin anlatımı uzun gibi gözükse de uygulaması oldukça basittir.. Eğer
kodları denerseniz aslında işlemlerin ne kadar kolay olduğunu anlarsınız.
Örnek Uygulama : Role-Based
Security
Makale:
Web.config ile Rol Tabanlı Güvenlik ASP.NET Serkan Karaarslan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|