Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Web Service Session Bazlı Güvenlik

Varsayalım ki, biz bir alışveriş sitesinin Web Service’ini yazdık.Bu serviste sipariş alan bir metodumuz mevcut ve haliyle Web Service’imizi kullanacak kullanıcı bu metodu istediği kadar kullanabilecek.Kazara dalgacının birine denk gelirsek eğer bize istediği kadar sipariş gönderebilir.Hal böyleyken hem alışveriş firmasını uğraştırır, hemde bizleri.O halde bir güvenlik alınması şart.Web Service uygulamalarında, bu gibi durumlarda iki türlü güvenlik önlemi alabiliriz.Biri Session bazlı güvenlik, diğeri ise SOAP Header ile güvenliktir.Bu yazımızda Session bazlı güvenlikten bahsedeceğiz.Şimdi yukarıdaki senaryoyu açık bir şekilde örneklendirerek, Session bazlı güvenliğin nasıl alındığını görelim.

Web Service’imizi kullanan kullanıcıdan bir kullanıcı adı ve şifre sormamız gerekiyor.Bu bilgileri siz veritabanındaki kayıtlarla eşleştirebilirsiniz.Ancak ben manuel olarak bir kullanıcı adı ve şifre kullanacağım.Veritabanı mevzuyu uzatacağından dolayı sipariş kayıtlarınıda bir not defterine kayıt edeceğim.
Öncelikle Visual Studio’da bir Web uygulaması açıyorum ve projemize bir tane Web Service dosyası ekleyelim.Ben Web Service dosyamızın adını “AlisVeris.asmx” olarak değiştiriyorum.

---AlisVeris.cs---

    [WebMethod]
    public void SiparisVer(int UrunSayisi, string UrunAdi)
    {
        StreamWriter SiparisKayit = new StreamWriter("C:/Dosya/Siparisler.txt",true);
        SiparisKayit.WriteLine("Ürün adı " + UrunAdi + " olan ürünümüzden," + UrunSayisi + " adet sipariş edilmiştir.");
        SiparisKayit.Close();
    }

Evet yukarıda güvenliği olmayan bir Web Service yazmış olduk.
Şimdi bir Windows projesi açalım ve bu Web Service’i referans edelim.
Windows projemizde iki TextBox nesnesi ve bir tanede Button nesnesi koyalım.TextBox’lardan birine kullanıcı adı, diğerine şifre girdirecez birazdan.Şimdiden hazır bulunsunlar 🙂
Ben Web Service’imizin referansının adına “AlisVeris” ismini koyuyorum.

        private void Form1_Load(object sender, EventArgs e)
        {
            AlisVeris.AlisVerisSoapClient Siparis = new AlisVeris.AlisVerisSoapClient();
            Siparis.SiparisVer(3, "Kitap");
        }

Şimdi Formumuzu çalıştırdığımız anda C:/Dosya dizinini kontrol edelim.Siparisler.txt adında bir dosyamız oluşturulmuş ve içine “Ürün adı Kitap olan ürünümüzden,3 adet sipariş edilmiştir.” şeklinde satır eklenmiş.

Varsayalım Ahmet diye bir arkadaşımız Web Service’mizi kullanıyor.Ve aşağıdaki şakayı bize yapıyor.

        private void Form1_Load(object sender, EventArgs e)
        {
            AlisVeris.AlisVerisSoapClient Siparis = new AlisVeris.AlisVerisSoapClient();
            for (int i = 0; i < 50; i++)
            {
                Siparis.SiparisVer(i,"Silgi");
            }
        }

Şimdi bu Ahmet’in yaptığı işmi!Bakın Siparisler.txt dosyasına.Elli tane kayıt mevcut.Eee güvenlik şart, güvenliksiz yola çıkılırsa illa bir Ahmet’e denk gelinir.Bu Web Service’i alışveriş firmasının kullanıcı adı ve şifre verdiği üyeler kullanabilsin.
Şimdi en başta “AlisVeris.cs” dosyasına dönelim ve Session tabanlı güvenlik işlemlerini yapmaya başlayalım.

    [WebMethod]
    public string UyeLogin(string KullaniciAdi, string Sifre)
    {
        if (KullaniciAdi == "Gencay" && Sifre == "123")
        {
            if (Session["UyeSifre"] != null)
            {
                string Deger = new Guid().ToString();
                Session["UyeSifre"] = Deger;
                return Deger;
            }
            else
            {
                string Deger = new Guid().ToString();
                Session.Add("UyeSifre", Deger);
                return Deger;
            }
        }
        return null;
    }

    [WebMethod]
    public bool SiparisVer(int UrunSayisi, string UrunAdi, string UyeSifre)
    {
        if (Session["UyeSifre"] != null)
        {
            if (Session["UyeSifre"].ToString() == UyeSifre)
            {
                StreamWriter SiparisKayit = new StreamWriter("C:/Dosya/Siparisler.txt", true);
                SiparisKayit.WriteLine("Ürün adı " + UrunAdi + " olan ürünümüzden," + UrunSayisi + " adet sipariş edilmiştir.");
                SiparisKayit.Close();
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }

Yukarıdaki kodları incelerseniz eğer, UyeLogin adında bir metod ekleniyor ve bu metodun parametrelerine girilen değerlerin, şartlardaki değerler ile uyup uymadığı kontrol ediliyor.(Şartlardaki değerleri ben manuel olarak yazdım.Siz veritabanındaki verilerle karşılaştırabilirsiniz.)
Eğer uyuyorsa Guid tipinde bir değer oluşturuyor.Ve bu oluşturulan veriyi Session’a ekliyor.Aynı zamanda bu değeri geri string olarak döndürüyor.
SiparisVer metodunda ise, UyeSifre parametresi ile, Session’daki Guid tipi değerin saklandığı alan karşılaştırılıyor.Eğer eşitlik sağlanırsa sipariş işlemi tamamlanıyor.Sağlanmaz ise, demek ki bu Web Service’i kullanan kullanıcı,UyeLogin metodunu kullanarak şifre oluşturmamış.(Metodun her kullanışında farklı değer oluşturulur.)
Şimdi Windows projemize geri dönüp Web Service’imizi güncelleyelim.Güncelleme işleminden sonra aşağıdaki kodları incelleyiniz.

        private void button1_Click(object sender, EventArgs e)
        {
            AlisVeris.AlisVerisSoapClient Siparis = new AlisVeris.AlisVerisSoapClient();
            string UyeSifre = Siparis.UyeLogin(textBox1.Text, textBox2.Text);
            if (UyeSifre != null)
            {
                Siparis.SiparisVer(5, "Klavye", UyeSifre);
                MessageBox.Show("Sipariş Verildi.");
            }
            else
            {
                MessageBox.Show("Hata");
            }
        }

Artık kullanıcı adı ve şifre girildiği için TextBox ve Button nesnelerini kullanıyoruz.Button nesnesinin Click eventına yazdığımız bu kod kullanıcı adı ve şifre doğruda girilse, yanlışta girilse hata mesajını verecektir.Bu hata mesajının sebebi ise, Web Service’ler de Session işlemleri yapıyorsak eğer, WebMethod attributeunda bunu belirtmemiz gerekmektedir.(Bütün Session işlemi yapılan metodlarda uygulanmalıdır.)
Evet “AlisVeris.cs” adındaki Web Service’imizin son hali aşağıdaki gibi olması gerekiyor.

    [WebMethod(true)]
    public string UyeLogin(string KullaniciAdi, string Sifre)
    {
        if (KullaniciAdi == "Gencay" && Sifre == "123")
        {
            if (Session["UyeSifre"] != null)
            {
                string Deger = new Guid().ToString();
                Session["UyeSifre"] = Deger;
                return Deger;
            }
            else
            {
                string Deger = new Guid().ToString();
                Session.Add("UyeSifre", Deger);
                return Deger;
            }
        }
        return null;
    }

    [WebMethod(true)]
    public bool SiparisVer(int UrunSayisi, string UrunAdi, string UyeSifre)
    {
        if (Session["UyeSifre"] != null)
        {
            if (Session["UyeSifre"].ToString() == UyeSifre)
            {
                StreamWriter SiparisKayit = new StreamWriter("C:/Dosya/Siparisler.txt", true);
                SiparisKayit.WriteLine("Ürün adı " + UrunAdi + " olan ürünümüzden," + UrunSayisi + " adet sipariş edilmiştir.");
                SiparisKayit.Close();
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }

Bu işlemide yaptıktan sonra programı derleyip, Windows projesinde Web Service’i Update edelim.
Evet projemizi bir daha çalıştırıp kullanıcı adı ve şifremizi girdikten sonra tekrar hatayla karşılaşacaz.

---Hata Mesajı---
/*There was no endpoint listening at http://localhost:16382/WebSite24/AlisVeris.asmx
that could accept the message. This is often caused by an incorrect address or SOAP
action. See InnerException, if present, for more details.*/

Bu hatadan kurtulmanın yolu, Windows projemizdeki App.config dosyasındaki ufak bir ayardan geçmektedir.

---App.config---
<!--?xml version="1.0" encoding="utf-8" ?-->
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding allowCookies="true" name="AlisVerisSoap" />
                // Buradaki allowCookies özelliği False gelmektedir.Bunu True yaparsak bu hatadan kurtuluruz.
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:16382/WebSite24/AlisVeris.asmx"
                binding="basicHttpBinding" bindingConfiguration="AlisVerisSoap"
                contract="AlisVeris.AlisVerisSoap" name="AlisVerisSoap" />
        </client>
    </system.serviceModel>
</configuration>

Yukarıdaki kod bloğunda açıklama satırı yapılan alanda bulunan allowCookies özelliğini true yaparsak bu hatayıda aşmış oluruz.
Son olarak projeyi çalıştırıp denediğimizde ise, yanlış kullanıcı adı ve şifre girersek mesaj kutusunda hata verecektir.Doğru girersek mauel olarak yazdığımız 5 adet klavyeyi not defterine ekleyecektir.

Artık Web Service’lerde güvenliğin ne kadar önemli olduğunun farkına vardık.Session bazlı güvenliği kullanmanız gereken yapıları iyi sezmeniz lazım.Sadece matematik işlem yapıp geriye sonuç döndüren bir Web Service yazıyorsanız güvenliğe ihtiyacınız yok.Amma ve Lakin bu yazıdaki gibi bir işlevi,eylemi kurgulayan sistemlerde şifreleme çok önemlidir.
Bir sonraki yazımda görüşmek üzere..
İyi Çalışmalar..

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. harun dedi ki:

    peki hocam. web servise aynı anda iki kişi girdiğinde ikisinede farklı UyeSifre degeri dönecek SiparisVer metodunu çağırdıklarında sadece son giren üye if in içine düşmezmi?sonuçta son giren web servisteki UyeLogin kısmından Session.Add(“UyeSifre”,Deger); ile UyeSifre degeri değişecek e o zaman ilk giren üye SiparisVer metodunda if (Session[“UyeSifre”].ToString() == UyeSifre) ‘in içine düşmez ki benmi yanlış yorumluyorum:S

  2. harun dedi ki:

    birde hocam client tarafında login olduktan sonraki yapılacak her işlemde yeni cookie mi üretmem gerek

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir