16 Şubat 2015 Pazartesi

MS.Net kodlarını gizlemek

Üzerinde çalıştığım projelerden birinde uygulama kodlarını yetkisiz kişilerden saklamak için kodların saklanması gerekiyordu. Önemli noktalardan biri eskiden reflector ile yaptığımız şekilde kodları msil kodundan tekrar c# koduna çevirebiliyoruz. reflector'ü redgate aldıktan sonra paralı olarak sunmaya başladı. Bu arada da alternatif çözümlerde çıktı tabii. Benim en çok kullandığım Ilspy . Ayrıca telerik'inde bedava dağıttığı JustDecompile adlı bir alternatif'te mevcut. arasak dahada çıkacağına eminim. Neyse konumuza tekrar geri gelelim. Amacımız bu araçlarla uygulama kodlarımıza geri dönülememesi. Bunun için obfuscation araçları kullanılıyor. Nedir bu obfuscation derseniz. Kelime anlamı şaşırtmaca olan bu işlem bize yazdığımız kodların çalışmasını engellemeden kodu karıştırarak decompiler toollarının kodu görmesini önlemeyi sağlıyor. Yani kodumuz gizlenmiş oluyor. Birçok alternatif var. paralı olanların yanında birde bedava var. benim işimi çok iyi gördü :


http://yck1509.github.io/ConfuserEx/

kullanımı ile ilgili olarak : http://stackoverflow.com/questions/24154502/how-to-use-confuserex adresini kullanabilirsiniz.

bütün alternatifleri görmek için ise :
http://en.wikipedia.org/wiki/List_of_obfuscators_for_.NET

10 Şubat 2015 Salı

NHibernate ile Update Sorgusu Oluşturma

NHibernate ile hiç Entity'i alıp üzerinde değişiklik yapıp sonrada update komutunu çalıştırmadan sadece sorgu ile bir işlem yapmak bazen çok daha iyidir. Bu benimde kullandığım yöntemlerden bir tanesi. Örnek olarak EUser ismindeki entity içerisindeki LastOperationDateTime alanını her sayfa isteğinde o anki tarih ve saat ile set etmek istiyorum. O zaman bunu uzun yoldan EUser entity'sini çek sonrada değeri değiştir ve kaydet yöntemi ile yapmak biraz maaliyetli oluyor. Bu noktada benim yaptığım ise bir update sorgusu yazmak :

public DateTime SetLastOperationDateTime(long userId)
{
    var dateTime = DateTime.Now;
    //Session.CreateQuery("UPDATE EUser SET LastOperationDateTime = :dt where Id = :id")
    //    .SetDateTime("dt", dateTime)
    //    .SetInt64("id", userId)
    //    .ExecuteUpdate();
    var q = Session.GetNamedQuery("SetLastOperationDateTime");
    q.SetDateTime("dt", dateTime);
    q.SetInt64("id", userId);
    q.ExecuteUpdate();
 
    return dateTime;
}

yukarıda 2 ayrı örnek bulunmakta yorum satırları içine aldığım benim hql i kontrol ettiğim normal hql query'si oluşturma yöntemi. Bu yöntem eğer bu sorguyu birden fazla kere kullanacaksanız yavaş kalabilir. Bende bu yüzden hql ile ilgili bir problem olmadığına karar verdiğimde bunu named query haline getiriyorum. Kısaca named query sorguları NHibernate'in kullanıma hazırlandığı sırada bir kere derlemesi ve sonrasında bu derlenmiş sorguları kullanarak daha hızlı çalışması anlamına geliyor. Şimdide kısaca nasıl kullanıldığına bakalım :
1. Önce projenizde bir hbm.xml dosyası oluşturmanız lazım :
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <query name="SetLastOperationDateTime">
    UPDATE EUser 
    SET LastOperationDateTime = :dt 
    where Id = :id
  </query>
</hibernate-mapping>

Bu dosyalar NHibernate'in mapping bilgilerini de tutmakta. Ama ben Fluent NHibernate kullandığım için mapping'lerim sınıflar şeklinde. Bu dosyada sadece Named Query'ler için ayrılmış durumda. unutmamamız gereken en önemli nokta bu dosyaların istediğimiz gibi çalışabilmesi için mutlaka Build Action olarak Embeded Resource olarak seçilmelerinin gerekliliği.


birde eğer Fluent NHibernate kullanıyorsanız bu dosyaların kullanıma alınabilmeleri için FluentConfiguration'da Mapping metodu içine şu satırı da eklemek gerekmekte :
m.HbmMappings.AddFromAssemblyOf<DBConfig>();

DBConfig benim projem içindeki named query'lerin bulunduğu assembly içindeki bir class.

Bu konudaki başka örnekler için :
NHibernate Update query : http://bit.ly/1ARmnfF
Execute UPDATE and return the record just updated using NHibernate CreateSQLQuery method? : http://bit.ly/1zRosoS

C# ile makina veya Domain kullanıcı bilgilerine erişim

Bu iş için Directory Service kütüphanesi içinde zaten alt seviyeli sınıflar mevcut idi ancak bir üst seviyeli sınıf ile işlemi daha kolay hale getirmişler :

string userName = string.Empty;
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "Your Domain Name")) 
{
    UserPrincipal user = new UserPrincipal(pc);
    user = UserPrincipal.FindByIdentity(pc, "User ID Will Come here");
    if (user != null)
    {
        userName = user.GivenName + " " + user.Surname;
    }
    else
    {
        //return string.Empty;
        userName = "User Not Found";
    }
}
Burada dikkat ederseniz önce veri almak istediğimiz yapıya ulaşmak adına bir bağlantı aracı açıyoruz. Bu araç ile hem makina hemde domain'e aynı arayüzden ulaşmak mümkün. Yukarıdaki örnekte domain'e ulaşma gözükmekte. Eğer ContextType parametresini ContextType.Machine olarak ayarlarsanız o zaman makina üzerinden de bilgi alabilirsiniz. Bir örnek şöyle olabilir :

  private bool IsValidWindowsUser(string userName, string password)
  {
       using (var p = new PrincipalContext(ContextType.Machine))
            return p.ValidateCredentials(userName, password);
  }

Api Dokümansasyonu için MSDN : http://bit.ly/1AdjRPt
Yukardaki örnekleri aldığım stackoverflow başlıkları :
how to get currently loggedin windows account from an asp.net page : http://bit.ly/1FrXZQE
C# - Not able to validate local machine user when “.\” is pre-append with username : http://bit.ly/1zECAD2