Çarşamba, Eylül 29, 2010

ASP.NET ve SharePoint'teki Güvenlik Açığı İçin Yama Yayınlandı (Microsoft Security Advisory (2416728))

Daha önceki postlarımızda ASP.NET tarafında doğal olarak SharePoint'i de etkileyen 2416728 kodlu güvenlik açığından bahsedip geçici bir çözüm önerisinde bulunmuştuk. Microsoft bu açığı kapatmak için .NET Framewotk tarafında bir yama yayınladı güvenlik bültenini okumak ve yamayı indirmek için http://www.microsoft.com/technet/security/bulletin/ms10-070.mspx adresini ziyaret edebilirsiniz. 

Salı, Eylül 21, 2010

ASP.NET ve SharePoint'te Güvenlik Açığı (Microsoft Security Advisory (2416728))

ASP.NET'te SharePoint'i de etkileyen bir güvenlik açığı duyuruldu. Bu güvenlik açığı ile ViewState verisi elde edilebiliyor ya da sitede bulunan web.config gibi dosyaların içeriği görüntülenebiliyor. Güvenlik açığının detay bilgilerine buraya tıklayarak erişebilirsiniz.


Güvenlik açığından kurtulmak için; sitenin Custom Errors modunu "On" olarak ayarlayıp site içerisinde hata oluşması durumunda kullanıcıyı kendi tasarladığınız custom bir hata sayfasına yönlendirmeniz yeterli oluyor. SharePoint için yapılması gereken işlemleri maddeler halinde SharePoint'in resmi bloğunda olduğu şekilde açıklıyorum;


1. SharePoint'i yüklemiş olduğunuz dizinde %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\14\template\layouts klasörüne geçin.

2. Klasörde error2.aspx adında bir dosya oluşturup içeriğini aşağıdaki hale getirin:


3. %SystemDrive%\inetpub\wwwroot\wss\virtualdirectories dizinine geçin.


4. Her alt klasör için aşağıdaki işlemleri tekrarlayın:


     1. web.config'i açın. 
     2. custom Errors düğümünü bulup aşağıdaki gibi düzenleyin;
          default Redirect="/_layouts/error2.aspx" />
     3. Değişiklikleri Kaydedin. 
     4. Run iisreset /noforce

Daha fazla bilgi için:

Microsoft Security Advisory (2416728) - Vulnerability in ASP.NET Could Allow Information Disclosure


Security Advisory 2416728 Released – Microsoft Security Response Center Blog


Understanding the ASP.NET Vulnerability – Microsoft Security Research & Defense Blog


Important: ASP.NET Security Vulnerability – Scott Guthrie’s Blog


Frequently Asked Questions about the ASP.NET Security Vulnerability – Scott Guthrie’s Blog

Çarşamba, Eylül 15, 2010

SharePoint 2010 Nasıl Yapılır? - External List'lere CRUD yeteneği kazandırmak!

Daha önceki yazılarımızda SharePoint 2010 ile birlikte hayatımıza giren External List'in ne olduğu ve nasıl oluşturulabildiğini ele almıştık daha önceki posta erişmek için buraya tıklayabilirsiniz; Bu postta da External List'e yeni öğe eklemeyi ve var olanları düzenlemeyi ele alıyoruz.  External List'te CRUD yeteneği kazandırma konusunda Internet'te yapmış olduğum araştırmalarda konu ele alınırken veri ekleme, silme ve güncelleme işlemlerinin Linq to SQL Classes aracılığı ile gerçekleştirildiğini gördüm sizler de bu metodu tercih ederseniz SharePoint'in resmi bloğunu ziyaret edebilirsiniz. Biz burada biraz daha farklı bir yöntemle ilerliyor olacağız, veri tabanına erişmek için kullanacağımız kodları tamamen kendimiz geliştireceğiz.

Yeni bir Business Data Connectivity Model oluşturarak işleme başlayalım. Yeni bir BDC Model oluşturmak için Visual Studio 2010'da New/project ekranından SharePoint bölümü aracılığı ile BDC Model projesini seçelim.

Proje şablonunu seçip OK butonuna basıldıktan sonra geliştirmenin hangi site üzerinde gerçekleştirileceği Visual Studio'ya belirtilmelidir. Buraya oluşturulacak olan modelin deploy edilecek olduğu siteyi yazıp Finish butonu ile proje oluşturulur.


Oluşturulan projeye BDC Model'de kullanılmak üzere bir tane class ekleyeceğiz. Ekleyecek olduğumuz Class hem tip olarak kullanılacak hem de CRUD olarak kısaltabileceğimiz Create, Retrieve, Update ve Delete metodlarını içerecek. Visual Studio'da Projeye sağ tuş ile tıklayıp New Item menüsünden Kisi adında bir tane Class ekleyelim. Oluşturulan Class aşağıdaki resimde yer alan Rehber isimli tabloya veri ekleyip silecektir. Resimden de anlaşılacağı üzere tablonun beş tane sütunu var bu sütunlardan KisiID olanı primary key ve aynı zamanda da identity özellikli Create ve Update işlemlerinde bu sütuna dikkat etmek gerekiyor.

Oluşturulan Class'ın içeriğini gerekli işlemlerin yapılabilmesi adına aşağıdaki şekilde dolduruyoruz.

Kisi.cs
using System;
using System.Collections.Generic;

using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;


namespace BdcRehberMakale
{
     public class Kisi
     {
          public int KisiID { get; set; }
          public string Ad { get; set; }
          public string Soyad { get; set; }
          public string Email { get; set; }
          public string Telefon { get; set; }
          public string ConnectionString
          {
               get
              {
                    return "Data Source=.; Initial Catalog=TCMLABTEST; Integrated Security=True";
               }
          }


          public Kisi()
          {


          }


          public Kisi(int kisiID,string ad,string soyad, string email, string telefon)
          {
                    this.KisiID = kisiID;
                    this.Ad = ad;
                    this.Soyad = soyad;
                    this.Email = email;
                    this.Telefon = telefon;
          }


          public void Create()
          {
               SqlConnection baglanti = new SqlConnection();
               baglanti.ConnectionString = this.ConnectionString;


               SqlCommand komut = new SqlCommand();
               komut.Connection = baglanti;
               komut.CommandText = "INSERT INTO Rehber (Ad,Soyad,Email,Telefon) VALUES (@Ad,@Soyad,@Email,@Telefon)";


               komut.Parameters.AddWithValue("@Ad", this.Ad);
               komut.Parameters.AddWithValue("@Soyad", this.Soyad);
               komut.Parameters.AddWithValue("@Email", this.Email);
               komut.Parameters.AddWithValue("@Telefon", this.Telefon);


               baglanti.Open();
               komut.ExecuteNonQuery();
               baglanti.Close();
          }


          public List RetrieveAll()
          {
               SqlConnection baglanti = new SqlConnection();
               baglanti.ConnectionString = this.ConnectionString;


               SqlCommand komut = new SqlCommand();
               komut.Connection = baglanti;
               komut.CommandText = "Select * FROM Rehber ORDER BY KisiID";


               DataTable dt = new DataTable();
               SqlDataAdapter adapter = new SqlDataAdapter(komut);
               adapter.Fill(dt);


               List kisiler = new List();
               foreach (DataRow row in dt.Rows)
               {
               kisiler.Add(new Kisi(Convert.ToInt32(row["KisiID"]),"" + row["Ad"], "" + row["Soyad"], "" + row["Email"], "" + row["Telefon"]));
               }


               return kisiler;
          }


          public Kisi RetrieveByID(int kisiID)
          {
               SqlConnection baglanti = new SqlConnection();
               baglanti.ConnectionString = this.ConnectionString;

               SqlCommand komut = new SqlCommand();
               komut.Connection = baglanti;
               komut.CommandText = "Select * FROM Rehber WHERE KisiID=@KisiID";
               komut.Parameters.AddWithValue("@KisiID", kisiID);


               DataTable dt = new DataTable();
               SqlDataAdapter adapter = new SqlDataAdapter(komut);
               adapter.Fill(dt);


               Kisi k = new Kisi();
               if (dt.Rows.Count == 1)
               {
                    k.KisiID = kisiID;
                    k.Ad=""+dt.Rows[0]["Ad"];
                    k.Soyad = "" + dt.Rows[0]["Soyad"];
                    k.Email = "" + dt.Rows[0]["Email"];
                    k.Telefon = "" + dt.Rows[0]["Telefon"];
               }
               return k;
          }


          public void Update()
          {
               SqlConnection baglanti = new SqlConnection();
               baglanti.ConnectionString = this.ConnectionString;


               SqlCommand komut = new SqlCommand();
               komut.Connection = baglanti;
               komut.CommandText = @"UPDATE Rehber SET
                                                            Ad=@Ad,
                                                            Soyad=@Soyad,
                                                            Email=@Email,
                                                            Telefon=@Telefon
                                                            WHERE   KisiID=@KisiID";
               komut.Parameters.AddWithValue("@Ad", this.Ad);
               komut.Parameters.AddWithValue("@Soyad", this.Soyad);
               komut.Parameters.AddWithValue("@Email", this.Email);
               komut.Parameters.AddWithValue("@Telefon", this.Telefon);
               komut.Parameters.AddWithValue("@KisiID", this.KisiID);


               baglanti.Open();
               komut.ExecuteNonQuery();
               baglanti.Close();
          }


          public void Delete()
         {
               SqlConnection baglanti = new SqlConnection();
               baglanti.ConnectionString = this.ConnectionString;


               SqlCommand komut = new SqlCommand();
               komut.Connection = baglanti;
               komut.CommandText = @"DELETE FROM Rehber
                                                            WHERE KisiID=@KisiID";
               komut.Parameters.AddWithValue("@KisiID", this.KisiID);


               baglanti.Open();
               komut.ExecuteNonQuery();
               baglanti.Close();
          }
     }
}

Kisi class'ını dikkatle incelediğimizde yapılandırıcı metod dışında toplam beş tane metod olduğu gözlerden kaçmayacaktır. Bu metodlardan iki tanesi veri getirmek diğer üçü de veri yazmak için olan işlemlerdir. Veri getirmek için kullanılan metodların dönüş değerinin Kisi sınıfı ve Kisi koleksiyonu olduğuna dikkat ediniz. Veri sınıfımız başka bir deyişle Data Access Layer hazırlandı şimdi sıra geldi BDC Modeli'ni hazırlamaya. Visual Studio'da Solution Explorer'a göz atacak olursak orada BDCModel1 adında bir modelin yer aldığını görüyor olacağız. Her şeyi sıfırdan yapmak adına BDCModel1 isimli modeli projemizden silelim. Yeni bir model eklemek için projeye sağ tıklayalım ve New Item menüsünden SharePoint/2010 bölümünde yer alan Business Data Connectivity Model tipini seçelim. Model adı olarak BdcModelRehber belirleyelim. BDCModelRehber'e tıklayarak model'in içeriğine göz atabiliriz. Oluşturulan modelde Entity1 isimli bir entity hazır halde karşımıza gelecektir, bunu da silip yenisini ekleyeceğiz. Entity1'e tıkladıktan sonra delete tuşu ile gerekli aksiyonu alabiliriz. Yeni bir Entity eklemek için sol tarafta yer alan ToolBox'ı kullanabiliriz. ToolBox'tan bir tane Entity'i sürükleyip modelimizin üzerine bırakalım. Bu Entity'in adını da kendimize göre kişiselleştiriyor olmalıyız. Gerekli güncellemeleri yapmak için Entity'e sağ tıklayıp properties'i seçelim, özelliklerden Entity'nin adını EntityRehber olarak değiştirelim. Şimdilik EntityRehber adında boş bir Entity sistemde mevcut, bu entity'nin bir adet kimlik niteliğinde bir üyesi olmalı.

Entity'ye yeni bir kimlik yani identifier eklemek için identifiers bölümüne sağ tıkladıktan sonra add new identifier tuşuna tıklayalım. Ardından oluşturulan identifier'ın özelliklerinden Name özelliğini KisiID ve tipini de System.Int32 olarak belirleyelim. 



BDC Modelimizin kimlik niteliğindeki üyesini ekledikten sonra sıra geldi metodlarını oluşturmaya. Entity'nin methods bölümüne tıkladığımızda Visual Studio'da BDC Method Details penceresi görüntüleniyor olacaktır. Method Details penceresi aracılığı ile gerekli olan metodları ekleyebiliriz. Metod tipleri Visual Studio'da önceden tanımlanmıştır ve tek tıklama ile oluşturulabilir. Burada ilk olarak veri getirmek için gerekli olan ReadItem metodunu ekliyor olacağız. Method Details penceresinden Specific Finder Method'u seçerek gerekli methodu oluşturabiliriz.


ReadItem metodu oluşturulduktan sonra sıra geldi geri döndürülecek olan tipi tanımlamaya. Geri döndürülecek olan tip Method Details penceresinde ReadItem'a tıklanıldığında return parametresinde görüntüleniyor olacaktır. Parametreye tıklayıp edit diyerek tipi özelleştirebiliriz.


Edit'e tıkladıktan sonra BDC Explorer penceresi görüntüleniyor olacaktır. Bu pencereden @entityRehber parametresi genişletildikten sonra geri dönecek olan tipe erişilebilir. Bu tipin içinde yer alacak üyelerin tanımlamaları burada yapılmalıdır. EntityRehber'e sağ tıklanıp Add Type Descriptor'a tıklanarak gerekli üyeler eklenebilir. Sırası ile KisiID, Ad, Soyad, Email ve Telefon'u buraya ekliyor olacağız. Bu üyelerden KisiID'nin tipi Int32 diğerleri ise varsayılan yani string olacaktır. KisiID'nin Identifier Entity özelliği EntityRehber (BdcRehberMakale.BdcModelRehber.EntityRehber) ve Identifier özelliği de KisiID olarak atanmış olmalıdır. Bu atamaları yazmak yerine size sunulan seçimlerden seçmelisiniz.

Üyelerin tanımlanmasının ardından EntityRehber'in özelliklerine geçip burada da bir ayarlama yapılması gerekiyor. EntityRehber'in TypeName özelliğini BdcRehberMakale.Kisi, BdcModelRehber olarak ayarlıyoruz. Bunu da yine listeden seçiyoruz.


ReadItem metodu oluşturulduktan sonra sıra geldi diğer metodları oluşturmaya metod oluşturma işlemini yukarıda anlattığımız şekilde yaparak sırası ile Finder, Creator, Updater ve Deleter metodlarımızı oluşturalım. Burada dikkat edilmesi gereken bir şey vardır Visual Studio bir önceki adımda tanımlamış olduğumuz tipi tanıyacak ve bu metodlarda da otomatik olarak gerekli tanımlamalar yapılacaktır.

Metodlar oluşturululmasının ardından sıra çalışacak olan kodları yazmakta... Şu anda arka planda metod tanımlamaları yapıldı ancak doğal olarak içlerine gerekli kodların da yazılması gerekmektedir. BDC Explorer'da EntityRehber'e sağ tıklanıp View Code denildikten sonra metodların tanımlamaları görüntüleniyor olacaktır. Bu tanımlamaları aşağıdaki gibi doldurarak gerekli geliştirmeyi tamamlayabiliriz.

public static Kisi ReadItem(int kisiID)

{
     Kisi k = new Kisi();
     return k.RetrieveByID(kisiID);
}


public static IEnumerable ReadList()
{
     Kisi k = new Kisi();
     return k.RetrieveAll();
}

public static Kisi Create(Kisi newEntityRehber)
{
     Kisi k = new Kisi();
     k.Ad = newEntityRehber.Ad;
     k.Soyad = newEntityRehber.Soyad;
     k.Email = newEntityRehber.Email;
     k.Telefon = newEntityRehber.Telefon;


     k.Create();
     return k;
}


public static void Update(Kisi entityRehber)
{
     Kisi k = new Kisi();
     k.KisiID = entityRehber.KisiID;
     k.Ad = entityRehber.Ad;
     k.Soyad = entityRehber.Soyad;
     k.Email = entityRehber.Email;
     k.Telefon = entityRehber.Telefon;


     k.Update();
}


public static void Delete(int kisiID)
{
     Kisi k = new Kisi();
     k.KisiID = kisiID;


     k.Delete();
}

Geliştirmiş olduğumuz modelin kullanılabilmesi için modelin SharePoint'e gönderilmesi gerekmektedir. Visual Studio 2008 tarafında problem yaşadığımız deployment senaryolarının tamamı Visual Studio 2010'da çözülmüş durumdadır ve projeye sağ tıklandıktan sonra Deploy'a tıklayarak modeli SharePoint'e gönderebiliriz. Deploy işleminin ardından daha önceki postta belirttiğimiz şekilde External List oluşturup kullanmaya başlayabilirsiniz. SharePoint 2007 tarafında oldukça ek geliştirme ile çözebildiğimiz bu durumun SharePoint 2010'da bu kadar kolay bir şekilde çözülüyor olması gerçekten harika...

Pazartesi, Eylül 13, 2010

Yeni İşyerim: TCM | Teknoloji Çözümleri Merkezi

Kariyerimi TCM | Teknoloji Çözümleri Merkezi İş Çözümleri Departmanında sürdürüyorum. Daha önceki iş yerlerimde üstlenmiş olduğum görevlerle paralel olarak TCM'de de yoğun olarak SharePoint projelerini yürütüyor olacağım. SharePoint projelerinde; anahtar teslim proje, günlük danışmanlık, dış kaynak personel sağlama ve eğitim çözümleri ile yanınızdayız. TCM sadece SharePoint tarafında değil İş Zekası, Yazılım, Network ve Güvenlik çözümleri başlıklarında da tecrübeli ekibi ile sektöre hizmet vermektedir. İsterseniz TCM'yi biraz tanıyalım;

TCM | Teknoloji Çözümleri Merkezi
Teknoloji Çözümleri Merkezi (TCM);Türkiye'nin önde gelen bilişim şirketlerinde çeşitli pozisyonlarda uzun yıllar görev yapan bir çekirdek ekip tarafından kurulmuştur. Kuruluşu ile birlikte Türkiye'nin önde gelen şirketleri ile çalışmaya başlamış ve aldığı işler ile ekibini hızla büyütmüştür.



Özellikle SharePoint, Kurumsal Zeka, Yazılım ve Network çözümleri üzerine anahtar teslim proje ve danışmalık hizmetleri vermektedir. Bununla birlikte uzun yıllar geliştirdiği farklı dış kaynak çözümleri ile müşterilerine birçok seçenek ile hizmet vermektektedir.
 
TCM hakkında daha geniş bilgi sahibi olmak için http://www.tcm.com.tr/ adresini ziyaret edebilirsiniz.