21 Ocak 2013 Pazartesi

Kerberos Yazı Dizisi - III


Kerberos Yazı Dizisi - III

Geçen yazımızda Kerberos'un altyapısından ve çalışma prensiplerinden bahsettiydik. Bu yazımızda kendi Kerberos'umuzu nasıl kodlayabilieceğimizden bahsedeceğiz ve kerberos güvenliğine farklı bir bakış açısı getirecek basit bir güvenlik framework'ü oluşturacağız.

Yazımıza başlamadan önce Kerberos'un uygulama kodlarının açık olduğunu ve İnternetten ücretsiz olarak indirebileceğinizi hatırlatalım. Bu ve önceki makalelerin Referanslar bölümünde ilgili bağlantıları bulabilirsiniz. Ayrıca İnternet üzerinde bir çok Kerberos örnek kodu da bulabilirsiniz. Genelde hepsinin yapısı ve kodlaması da benzerdir. Şifreleme ve deşifreleme algoritmaları ve gerçeklenen işlemlerin de aynı olduğu göz önüne alınırsa bu pek şaşırtıcı olmaz. Sunucular ile istemci arasında birer soket bağlantısı kurulur, bu bağlantı üzerinde şifreli olarak mesajlaşma gerçekleştirilir. Yani Kerberos kodunun temelinde soket bağlantıları vardır. .NET Sınıf kütüphanesi rahatlıkla uygulanabilecek soket kütüphanesine de sahiptir. Kerberos'u .NET ile aynı şekilde gerçeklemeniz mümkündür. Ancak bu durumda .NET teknolojilerini kullanmanızın pek bir anlamı olmaz. ANSI-C ve ya bir başka programlama dili ile de bu uygulamayı gerçekleştirebilirsiniz. Ancak bu yazımızda biz bu yolu seçmeyeceğiz.

.NET 'in iki temel bileşeni vardır; .NET Framework ve .NET Sınıf Kütüphanesi. .NET Sınıf kütüphanesiyle programlama dillerinin birbirlerine göre olan avantajlarını tek bir ara dilde birleştirme imkanınız vardır. Nu sayede dil bağımlılığınız kalmaz. .NE Framework, geliştirdiğiniz uygulamaların, .NET Framework tarafından desteklenen tüm ortam ve platformlarda çalışmasını garanti eder. Bu sayede platform ve donanım bağımlığını ortadan kaldırır. .NET' in bize sağladıkları olarak bu saydıklarımız çoğu yazılımın da en önemli problemleri arasında yer almaktadır. Örnek, Kerberos. Çoğu da aynı kod olmasına karşın; İnternet'ten farklı programlama dillerinde ve/ve ya farklı ortamlar için gerçeklenmiş bir çok Kerberos kodu bulabilirsiniz. .NET'in yardımıyla bir çok uygulama tarafından erişilebilinecek, platform ve ortam bağımsız bir kerberos uygulaması geliştirmeliyiz.

Bunun için .NET Framework'ün bize neler sağladığına bir göz atalım. Öncelikle neye ihtiyacımız olduğunu tanımlayalım; İnternet üzerinden farklı sistemler tarafında İnternet Standartlarını kullanarak erişilebilecek, uygulama mantığı gibi belirli bir işlevselliği yerine getirebilecek programlanabilir bir elemana ihtiyacımız var. Veri depolama ve haberleşme konusunda da standartlaşmış bir yapıyı kullanabilmeli, her türlü bilgiyi iletebilmelidir. Bu verdiğimiz tanım birebir XML Web Servislerinin tanımıdır. İhtiyacımız olan şey XML Web Servisleri dir. Sunucular ve istemci arasında bağlantı için kullanacağımız protokol XML Web Servisleri, dolayısiyle HTTP üzerinden SOAP olacaktır. Veri depolama ve gönderme standartı olarak da XML kullanacağız.
 
Şimdi örnek uygulamamız için gerekli alt yapıyı oluşturalım. Bunun için aynı solution'a 3 ayrı proje şablonu ekleyelim. İlki DataAccessProjects, bu proje grubunu veri tabanı erişimlerimiz için kullanacağız. Bu basit uygulamada veri tabanı erişimini Kimlik Denetim Sunucusunun kullanıcı adı ve şifre kontrolü için kullanacağız. Bu şablona sadece SecurityDataAccess projesini ekliyoruz. Bu projeye güvenlik için gerekli ADO.NET sayfalarında anlatıldığı şekilde veri tabanı işlemlerini yapabileceğimiz bir sınıf ekleyelim. Konumuz ile alakası olmadığı için bu kodun detaylarına girmiyoruz. Bu sınıfın bir şekilde Kimlik Denetim Sunucusu için gerekli veri tabanı işlemlerini yaptığını kabul edelim.

Kullanacağımız XML Web Servisleri için ikinci Proje şablonumuz olan WebServiceProjects'i oluşturalım. Bu şablona iki ayrı proje ekleyeceğiz. Birincisi olan WebServicesCommon hazırlamış olduğumuz sistemin sağlayacağı servisleri içerecek, ikincisi olan WebServicesSecurity ise Kerberos ile sağlayacağımız güvenlik sistemimizin altyapısını oluşturacak. WebServicesCommon projesine SampleService.asmx adı altında örnek bir servis oluşturalım. Şimdilik bu servisi System.Web.Services.WebService sınıfından türetelim. Daha sonra tüm web servislerimizi ortak bir sınıftan türeteceğiz. WebServicesSecurity projesine ise Kimlik Denetim Sunucusu için AuthenticationServer.asmx, Bilet Veren Sunucu içinde TicketGrantingServer.asmx servislerini ekleyelim. Yine bu servisleri şimdilik System.Web.Services.WebService sınıfından türetelim.

Son proje şablonumuzda tüm bu güvenlik sistemini bir ASP.NET web uygulaması üzerinden test edebilmemiz için bir web ara birimi sağlayacaktır. Web Servislerinin windows arabirimli uygulamalarından da çağrılabildiğini hatırlarsak, aynı kerberos kodunu hem windows hem de web ara birimi üzerinden çağırmanın mümkün olabileceğini farketmiş oluruz.
Buradan tüm kodu sizlere hazır olarak vermeyeceğim. Sizlere kullanacağınız alt yapıyı sunduktan sonra nasıl geliştirebileceğinizi aktaracağım. Ardından olması gereken fonksiyonların içlerini sizler doludaracaksınız. Bu solution'ın şu ana kadar yaptıklarımızı içeren boş halini indirmek için tıklayın...
Geçen yazımıza biraz atıfda bulunalım. İstemci ve diğer sunucular arasındaki mesajlaşmaların yer aldığı bir tablomuz vardı. Bu tabloda her sunucu ve istemci arasındaki 2 ayrı açıklama vardı. Bunlardan ilki istemcinin o sunucuya gönderdiği bilgileri, diğeri ise ilgili sunucunun bu talebe cevabını içermekteydi. İstemcinin ilgili web servisine göndereceği bilgiyi sizin tanımlayabileceğiniz bir veri yapısı içersinde web servisine parametre olarak geçirebilirsiniz. Web Servisinin sonucu da ilgili sunucunun cevabını içermelidir. Sunucuların aralarındaki mesajlar için kullanıcı ID si ve timestamp'ten oluşan benzersiz (unique) bir parametre ile session'a kaydebilirsiniz. Session' ın zaman aşımını ayarlayarak Kerberos zaman aşımı süresini de oluşturmuş olursunuz.

Oluşturmuş olduğumuz bu web servisleri Kerberos'un gerekliklerini yerine getirir ancak önemli olan sistemimizdeki tüm web servislerinin bu web servisleri üzerinden çalışmasıdır. Bunun için ilk önerim Servis sağlayıcı ve istemci arasındaki mesajlaşmaları ve kontrolleri yapan kodları gerçekleyen System.Web.Services.WebService sınıfından türeyen bir web servisi ana modülü oluşturmanız ve sisteminize ekleyeceğiniz tüm web servislerini bu ana modülden türetmenizdir. Ana modülün kurucu fonksiyonunda da gerekli fonksiyonları çağırarak, gerekli güvenlik kontrollerini de yapabilirsiniz. Bu sayede aynı kodu tekrar yazmadan tüm servislerinizde ortak bir yerde güvenliği sağlamış olursunuz.

İkinci önerim ise, biraz daha karışık olabilir. Ondan önce tasarladığımız bu sisteme biraz eleştiri getirelim. Şu an ki tasarımı ve kullanımıyla XML Web Servisleri
ne kadar güvenli? Bu konuyla ilgili bir çok makale bulunmaktadır. Hazırlamış olduğumuz web servislerinin güvenliğinin nasıl sağlanacağı konusunda yazılmış en iyi iki makale Matt Powell'a ait olan "Defending Your XML Web Service against Hackers, Part I, II" adlı makalelerdir. Ama yine de benim size önerim GXA(Global XML Web Services Architecture) 'dır. GXA, XML Web Servislerinin bir adım öndeki halidir. Web servislerinin B2B ve B2C servisleri olarak kullanılmasını amaçladığından çok daha güvenlidir. Ayrıca GXA'nın hareket(transaction) desteği de vardır. Uygulamayı gerçekleştirirken GXA'yı kullanarak hazırladığımız sistemi çok daha güvenli bir hale getirmiş oluruz. Şimdi ikinci önerime geri dönersek; bu güvenliği sağlama işini de bir web servisine yüklersek ve hareket(transaction) içerisinden bunların yönetimini yaparsak sistemimizi çok daha mantıklı bir hale getirmiş oluruz. Tasarlamış olduğumuz sistem gelişmeye ve geliştirmeye çok müsait olduğundan üzerine daha bir çok eklenti yapılabilir. Size bir kaç öneri daha çok kısa bir kod ile SOAP'în header bilgisine ulaşmanız ve kendi özel header bilgilerinizi eklemeniz mümkün ve buheaderi SOAP header' ı üzerinden gelip gelmediğini  her web servisine erişimde kontrol ederek sistemin güvenlik kontrollerinizi çok daha alt seviyelere indirmeniz mümkün. SOAP header'ina nasıl kendi header bilgilerinizi ekleyeceğiniz konumuzun dışında olmasına karşın basit bir örnek bunu belirtmek istiyorum.
using System;
using System.Web.Services;
using System.Web.Services.Protocols;
 
// SoapHeader sınıfından türeyen SOAP headerımızı tanımlayalım



public class MyHeader : SoapHeader
{
   public DateTime Created;
   public long Expires;
}
 
[WebService(Namespace="http://www.contoso.com")]
public class MyWebService : System.Web.Services.WebService
{
   // SoapHeader sınıfından türeyen bir sınıf üyesi ekleyelim
   public MyHeader timeStamp;
 
   // SoapHeader özelliğimizi uygulayalım
   [WebMethod]
   [SoapHeader("timeStamp", Direction=SoapHeaderDirection.InOut)]
   public string HelloWorld()
   {
      if (timeStamp == null)
         timeStamp = new MyHeader();
         
      timeStamp.Expires = 60000;
      timeStamp.Created = DateTime.UtcNow;
         
      return "Hello World";
   }
}
MSDN, Using SOAP Headers makalesindeki örnek kod


Bir sonraki yazımızda Kerberos'un ne kadar güvenli olduğunu ve güvenliğinin kırılıp kırılamayacağını inceleyeceğiz. Şimdiden üzülerek belirteyim ki, Kerberos kırılması imkansız bir güvenlik sistemi değil! Bir sonraki yazımızda buluşuncaya kadar güvende kalın !!!

Referanslar
[1] Ücretsiz kaynak kodları için Massachusetts Institute of Technology
Yazar : Yunus Emre ALPÖZEN
e-Posta : yemre@msakademik.net

Hiç yorum yok:

Yorum Gönder

isterseniz anonim seçeneginden kayıtsız gönderebilirsiniz iyi günler