Pozitif ve Negatif Kimlik Dogrulama

By Kenan Sevindik

Geçenlerde katıldığım bir eğitimde gördüğüm bir kod parçası üzerinde birkaç noktayı sizinle paylaşmak istiyorum. Eğitimde bir web uygulamasına login olmaya çalışan kullanıcıların kimlik denetimlerinin pozitif ve negatif kimlik doğrulama yaklaşımları ile yapılması karşılaştırılıyor ve negatif kimlik doğrulama yaklaşımının sağlamlığını ifade etmek için de bu kod parçacıkları kullanılıyordu. Şimdi kod parçacıklarına bakalım. (Örneklerde anlatılmak istenen asıl konudan sapmadan kodlar üzerinde küçük oynamalar yaptığımı söylemeliyim.)

private boolean authenticatePositively(String username, String password) {
    boolean authenticated = true;
    try {
        User user = null; //find user with given username
        if(user.getPassword() != password)
            authenticated = false;
            if(!user.isAccountNonLocked())
            authenticated = false;
    } catch(Exception ex) {
        authenticated = false;
    }
    return authenticated;
}

Yukarıdaki örnek, pozitif kimlik doğrulama yaklaşımını gösteriyor. Pozitif kimlik doğrulama ile anlatılmak istenen, authenticated değişkeninin daha metodun başında true olarak set edilip, ancak kimlik doğrulama algoritmasındaki adımlardan herhangi birinde başarısızlık söz konusu olduğunda değişkenin false olarak set edilmesidir. Ancak bu durumlarda kullanıcının sisteme girişi engellenir. Diğer bütün durumlar için kullanıcı sisteme girmeye hak kazanacaktır.

private boolean authenticateNegatively(String username, String password) {
    boolean authenticated = false;
    try {
        User user = null; //find user with given username
        if(user.getPassword() != password)
            throw new Exception("error");
        if(!user.isAccountNonLocked())
            throw new Exception("error");
        authenticated = true;
    } catch(Exception ex) {
        authenticated = false;
    }
    return authenticated;
}

Bu örnek ise negatif kimlik doğrulamayı anlatıyor. Burada ise authenticated değişkeni başlangıçta false olarak set ediliyor. Daha sonra kimlik doğrulama algoritmasının adımları birer birer işletiliyor. Herhangi bir adımda hata olursa bir Exception fırlatılıyor, Exception aynı metod içerisinde yakalanıyor ve kullanıcının sisteme girmeye hak kazanması engelleniyor. Hata olmazsa son adımda authenticated değişkeni true olarak set ediliyor.

İlk örnekteki problemler gayet nettir. Eğer kimlik denetimi adımlarından herhangi birisinde beklenmedik bir hata meydana gelirse ve bu hata Exception bloğunda ele alınırken authenticated değişkeni false olarak set edilmezse, kullanıcı yeterli bir denetime tabi tutulmadan sisteme erişmeye hak kazanabilir. Bir diğer problem de exception handling kısmındadır. Eğer metod içerisinde daha spesifik bir exception yakalamak gerekirse, önceki exception bloğundaki authenticated = false ifadesi erişilmez olacaktır. Programcı, yeni eklenecek her exception catch bloğuna da authenticated = false ifadesini eklemeyi hatırlamalıdır. Bu, kısmen implicit bilgi olduğundan, kod üzerinde değişiklik yaparken rahatlıkla gözden kaçabilir.

Metod sonucunu tutan değişkenlerin daha metodun başında, her zaman olumsuz/negatif bir değer ile initialize edilmesi, sadece kimlik doğrulama ile ilgili kodlarda değil, geliştirilen herhangi bir kod parçası için izlenmesi gereken bir yaklaşımdır. İkinci örnekte bu hata düzeltiliyor ve authenticated değişkeni daha metodun başında false olarak set edilip, ancak mevcut kimlik doğrulama adımları başarılı biçimde sonlanırsa trueya çevriliyor. Ancak ikinci örnekte başka bir kötü programlama pratiğine de kapı aralanmış: ikinci metod içerisinde kimlik denetim adımlarındaki herhangi bir başarısız durum Exception fırlatılarak belirleniyor ve aynı metodun içerisinde bu exceptionlar catch bloğu ile ele alınıyor.

Buradaki kötü pratik, exceptionların program kontrol akışını (control flow) yönetmek için kullanılmasıdır. Exceptionların bir nevi GOTO ifadesi yerine kullanılması söz konusu oluyor. Exceptionların beklenmedik ve ele alınması mümkün olmayan durumları ifade etmek için tasarlandığını aklımızdan çıkarmamak gerekir. Bunların program kontrol akışını yönetmek için kullanılması, her ne kadar günümüz derleyicileri ve yorumlayıcıları için çok büyük problem olmasa da uygulama içerisinde gereksiz bir “overhead” yaratması da söz konusudur.

private boolean authenticateNegatively2(String username, String password) {
     boolean authenticated = false;
     User user = null; //find user with given username
     if(user.getPassword() == password && user.isAccountNonLocked())
         authenticated = true;
     return authenticated;
 }

Yukarıda kimlik doğrulama metodunun yeniden düzenlenmiş halini görüyorsunuz. Burada authenticated değişkenine defansif biçimde önce false değeri set ediliyor. Ardından kimlik doğrulama kontrolleri tek bir if ifadesinde gerçekleştiriliyor. Ancak ifade doğru olduğunda authenticated değişkeni trueya set ediliyor. Kısacası, basitlik ile kaliteli kod arasında da yakın bir ilişki olduğunu buradan da görebiliriz. Sizce bu kimlik değerlendirme metodu daha fazla nasıl iyileştirilebilir?

Share: X (Twitter) LinkedIn