Makale Özeti

Bu makalemde sizlerle birlikte uygulamalarımıza aktivasyon mantığını nasıl entegre edebileceğimizi inceleyeceğiz. Kullanacağımız sistem hem web hem windows uygulamalarında kullanılabilir olması bakımından web servis tabanlı bir sistem olacaktır. Uygulama kurulabilecek her bilgisayar için bir guid üretilecek ve bu guid'ler veritabanın da saklanacaktır. Daha sonrasında kullanıcı uygulamayı aktive ettiğinde kullanıcının mac adresini alıp aktivasyon key'i ile eşleştireceğiz. ve başka kullanıcıların kullanmasına izin vermeyeceğiz. Kullanıcı uygulamayı açtığında ise mac adresinden aktive edilmiş bir uygulama kulanıp kullanmadığını test edeceğiz.

Makale

         Merhabalar,

         Bu makalemde sizlerle birlikte uygulamalarımıza aktivasyon mantığını nasıl entegre edebileceğimizi inceleyeceğiz. Kullanacağımız sistem hem web hem windows uygulamalarında kullanılabilir olması bakımından web servis tabanlı bir sistem olacaktır. Uygulama kurulabilecek her bilgisayar için bir guid üretilecek ve bu guid'ler veritabanın da saklanacaktır. Daha sonrasında kullanıcı uygulamayı aktive ettiğinde kullanıcının mac adresini alıp aktivasyon key'i ile eşleştireceğiz. ve başka kullanıcıların kullanmasına izin vermeyeceğiz. Kullanıcı uygulamayı açtığında ise mac adresinden aktive edilmiş bir uygulama kulanıp kullanmadığını test edeceğiz.

         Öncelikle veritabanını tasarlamakla uygulamaya başlayalım

        

         Tasarladığımız veritabanı yapısında alan isimleri bu alanlarda tutulacak verileri çok başarılı bir şekilde ifade etmektedir. Ancak özetleyecek olursak Aktivasyon key ve ActivationId  tabloya ilk başta belirli bir miktarda yazılmaktadır. Bu sayede istersek uygulamayı kurabilecek kişi sayısını da sınırlamış olabiliriz. Bir diğer alternatif is
e örnek uygulamamızda yapacağımız boş kayıt sayısı azaldıkça yeni aktivasyon key'leri eklemek olacaktır. ActivationDate aktivasyonun yapıldığı tarihi, ActivationIp aktivasyonun yapıldığı Ip adresini, ActivationMac ise aktivasyonun yapıldığı mac adresini saklayacak olan alanlardır.

      Aynı zamanda bu veritabanı üzerinde bazı stored procedure'lara ihtiyacımız olacaktır.Bu sp'ler yeni  AktivasyonKey'i eklemeye, Mevcut bir Key'i aktive etmeye, istekte bulunan kullanıcıyı kontrol etmeye yarayacaklardır. Öncelikle bu sp'leri yazalım.

CREATE PROC InsertActivations
AS
INSERT
INTO Activations(ActivationKey) VALUES(NEWID())
 
GO
 
CREATE PROC Activate
@pActivationKey uniqueidentifier,
@pActivationIp nvarchar(15),
@pActivationMac nvarchar(100)
AS
UPDATE
Activations SET ActivationDate=getdate(),ActivationIp=@pActivationIp,ActivationMac=@pActivationMac WHERE ActivationKey=@pActivationKey AND ActivationMac IS NULL
 
GO
 
CREATE PROC CheckActivation
@pActivationKey uniqueidentifier,
@pActivationMac nvarchar(100)
AS
SELECT COUNT(*) FROM Activations WHERE ActivationMac=@pActivationMac AND ActivationKey=@pActivationKey

GO

CREATE PROC SelectActivationByActivationMac
@pActivationMac nvarchar(100)
AS
SELECT COUNT(*) FROM Activations WHERE ActivationMac=@pActivationMac


         Şimdi bu authentication işlemlerinin yapılacağı web servisimizi yazmaya başlayabiliriz.
 

    [WebMethod]
    public bool Activate(string macAddress, string activationKey)
    {
        SqlConnection conn = new SqlConnection("data source=.;initial Catalog=ActivationMakale;integrated Security=SSPI");
 
        SqlCommand cmd2 = new SqlCommand("SelectActivationByActivationMac", conn);
        cmd2.Parameters.AddWithValue("@pActivationMac", macAddress);
        cmd2.CommandType = System.Data.CommandType.StoredProcedure;
        conn.Open();
        object o = null;
        o = cmd2.ExecuteScalar();
 
        if (o == null || o == DBNull.Value)
        {
            conn.Close();
            throw new Exception("Zaten Aktivasyon yapmışsınız.");
        }
        if (Convert.ToInt32(0) > 0)
        {
            conn.Close();
            throw new Exception("Zaten Aktivasyon yapmışsınız.");
        }
 
        SqlCommand cmd1 = new SqlCommand("Activate", conn);
        cmd1.CommandType = System.Data.CommandType.StoredProcedure;
        cmd1.Parameters.AddWithValue("@pActivationIp", System.Web.HttpContext.Current.Request.UserHostAddress);
        cmd1.Parameters.AddWithValue("@pActivationMac", macAddress);
        cmd1.Parameters.AddWithValue("@pActivationKey", activationKey);
        int rows = cmd1.ExecuteNonQuery();
        if (rows == 0)
        {
            conn.Close();
            throw new Exception("Aktivasyon kodunuz yanlış.");
        }
 
        SqlCommand cmd3 = new SqlCommand("InsertActivations", conn);
        cmd3.CommandType = System.Data.CommandType.StoredProcedure;
        cmd3.ExecuteNonQuery();
 
        conn.Close();
        return true;
    }


         Activate metodumuzda öncelikle bu mac adresi ile bir aktivasyon yapılıp yapılmadığını kontrol ediyoruz. Eğer bu mac adresinden bir aktivasyon yapılmış ise Exception fırlatıyoruz. Daha sonrasında ise Bir key için değerleri update ediyoruz. Eğer key yanlış ise kayıttan etkilenen satır sayısı 0 olacarak döneceğinden kullanıcıya hata verebiliriz. Son olarak ise bu aktivasyon key'i kullanılırsa yerine yeni bir key oluşturulması gerekliliğidir. Bundan dolayı InsertActivation çalıştırılarak işlemimizi sonlandırıyoruz.
 

    [WebMethod]
    public bool CheckActivation(string activationKey, string macAddress)
    {
        SqlConnection conn = new SqlConnection("data source=.;initial Catalog=ActivationMakale;integrated Security=SSPI");
 
        SqlCommand cmd1 = new SqlCommand("CheckActivation", conn);
        cmd1.Parameters.AddWithValue("@pActivationKey", activationKey);
        cmd1.Parameters.AddWithValue("@pActivationMac", macAddress);
        cmd1.CommandType = System.Data.CommandType.StoredProcedure;
        conn.Open();
        object o = cmd1.ExecuteScalar();
        if (o == null || o == DBNull.Value)
        {
            conn.Close();
            return false;
        }
        else if (Convert.ToInt32(o) == 0)
        {
            conn.Close();
            return false;
        }
        conn.Close();
        return true;
    }


         CheckActıvation Metodunda ise aktivasyon kodu mac adresini sunucuya göndererek giren kişinin yetkisinin olup olmadığına bakıyoruz. Bu kısımda sp'den dönen değer 0'dan büyük ise gönderilen değerler doğru değil ise yanlış demektir.

         Şimdi bu kodu uygulamamızda kullanalım. Öncelikle web servisi uygulamamıza web referans olarak ekliyoruz. Ve Uygulamamızda iki adet form oluşturuyoruz bu formlardan bir tanesi Main Formumuz diğeri ise aktivasyonun yapılacağı form. şimdi Ana Formumuza kodu yazalım.
 

        public frmMain()
        {
            if (Settings.Default.Key == "")
            {
                frmActivate insFrmActivate = new frmActivate();
                insFrmActivate.ShowDialog();
            }
            else
            {
                ActivationService.Activation act = new SampleApplication.ActivationService.Activation();
                bool res = false;
                try
                {
                    res = act.CheckActivation(Settings.Default.Key, GetMacAddress(Environment.MachineName));
                }
                catch (Exception)
                {
                    MessageBox.Show("Aktivasyon Kontrolü Sırasında Hata");
                    Environment.Exit(0);                   
                }
 
                if (res)
                {
                    //uygulama açılabilir.
                }
                else
                {
                    MessageBox.Show("Aktivasyon Hatalı");
                    Environment.Exit(0);
                }
            }
            InitializeComponent();
        }


         Öncelikle uygulamamız açılırken Settings'de bulunan Key property'si boşsa aktivasyon yapılmamış demektir.Bunun için aktivasyon formunu açıyoruz. Eğer daha önceden aktivasyon yapılmış ise uygulamanın Aktivasyon durumu kontrol ediliyor ve geçersiz olduğu durumda uygulamanın açılmasına izin verilmiyor.
 

        [DllImport("iphlpapi.dll", ExactSpelling = true)]
        public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen);
        public string GetMacAddress(string hostName)
        {
            System.Net.IPAddress[] adrr = Dns.GetHostEntry(hostName).AddressList;
            byte[] by = new byte[6];
            int len = by.Length; 
            int r = SendARP((int)adrr[0].Address, 0, by, ref len);
            return BitConverter.ToString(by, 0, 6);
 
        }

    
         Bu kod bloğunda ise client'ın aktif network bağlantısının mac adresini alıyoruz.

         Şimdi ise aktivasyon formumuzu inceleyelim.
 

        private void btnActivate_Click(object sender, EventArgs e)
        {
            ActivationService.Activation act = new SampleApplication.ActivationService.Activation();
            bool res = false;
            try
            {
                res = act.Activate(GetMacAddress(Environment.MachineName), txtActivationKey.Text);
            }
            catch (Exception)
            {
                MessageBox.Show("Aktivasyon Sırasında Hata");
                Application.Exit();
            }
 
            if (res)
            {
                Settings.Default.Key = txtActivationKey.Text;
                Settings.Default.Save();
                this.Close();
            }
            else
            {
                MessageBox.Show("Aktivasyon Hatalı");
                Application.Exit();
            }
        }


         Gördüğünüz gibi bu formda web servisini kullanarak uygulamanın aktivasyonunu gerçekleştiriyoruz. Bu sayede uygulamalarımızın aktivasyon edilmeden kullanılmasının önüne geçebiliyoruz. Bu yöntemin kullanıldığı örnek uygulamayı download'lar kısmında bulabilirsiniz. Umarım faydalı ve uygulamalarınızda kullanabileceğiniz bir makale olmuştur.
 
         oztamer@hotmail.com
         tamer.oz@yazgelistir.com
         oztamer@hotmail.com
Ornek Kodlar