Basic Auth , Oauth , Oauth 2.0 : Authorization Protokolleri

5 minute read

Mobil uygulama geliştirme münasebetiyle iki gündür haşır neşir olduğum, nedir ne değildir diye kafa patlatıp durduğum authorization (yetkilendirme) protokolleri hakkında yazmaya karar verdim. Öncelikle Basic Authentication ile başlayalım.

Basic Authentication

Kısaca özetlersek :

Client : Base64(username:password) -> Server

Efendim, sunucuya yaptığımız her istekte kullanıcı adı ve şifremizi base64 ile encode edilmiş şekilde gönderiyorsak bunun adına Basic Authentication diyor bu frenkler. Security konusunda güvendiğim bir arkadaş bu işin künhünü bana böyle özetledi. “Peki neden böylesi dandirik bir yola tevessül eder bu gafiller?” diye sorduğumda ise bunun aslında daha çok test ortamında yapılan bir şey olduğunu ve production’da kullanılmasının kesinlikle tavsiye edilmediğini söyledi. Ben de nacizane sonradan farkettim ki aslında gündelik hayatımda kullandığım bir authentication tipi imiş bu basic authentication. Nerede derseniz, Github’a SSH key ile bağlamadığım sunucumdan Github hesabıma herhangi bir işlem (push gibi) yapmak istediğimde her seferinde benden kullanıcı adı ve şifre istiyor. Bu da anlattığımız üzre Basic Authentication demek. Siz de basic authentication kullanan bir arkadaşınızı yorumlarda etiketlemeyi unutmayın.

Tüm bunlarla beraber SSL kullandığımız taktirde client ve server arasındaki güvenliği panik atak geçirmemize engel olacak kadar sağlayabiliyoruz. Buna rağmen bir protokolün başka güvenlik dayanaklarına ihtiyaç duymadan kendi ayakları üzerinde dosta güven düşmana korku vererek durması gerektiğine inananlardanım. Bu nedenle Basic Authentication kardeşimize rapid development esnasında sağladığı yardımlar için teşekkür ediyor fakat fazla da yüz göz olmadan yola devam ediyoruz.

Oauth2

Oauth2 ile ilgili yaklaşık bir haftadır seyreltik yoğunlukta araştırmalar yapıyorum. Bugüne dek benim için kullanıcı adı - şifre yazıp session cookie almaktan ibaret olan authentication kısmını bu denli karmaşık görünen bir hale getirdiği için ilk başlarda kendisine biraz sinirlendim. “Ne gerek var kardeşim bu kadar angaryaya” dedim. Fakat cahili olup sonradan hakkında bilgi sahibi olduğum hemen her şey gibi yanıldığımı farkettim.

Ben bu yazıda oauth2’nin anladığım kadarını, elimden gelen en anlaşılır şekilde anlatmaya çalışacağım. Şimdi başlayalım, öncelikle oauth2 nedir?

Bu soruyu internete yazdığınızda cevap olarak bir “yetkilendirme (authorization) protokolüdür” cümlesini göreceksiniz. Bunu biraz açalım.

Örneğin çalışanları kapı kapı dolaşıp emaye tencere satmaya çalışan bir şirket bizden saha elemanlarının satış performanslarını, istatistiklerini vs. takip edebilmelerini sağlayacak, mobil ve web versiyonları olan bir uygulama yapmamızı istedi. Uygulamada satış görevlisi , satış müdürü ve genel müdür şeklinde 3 farklı kullanıcı tipi olsun. Kullanıcı girişi (Authentication) ve tipine göre kullanıcının belirli işlemler yapmasına izin veren (veya yetkilendiren [ authorization ]) bir backend tasarlamamız lazım.

Şimdi bu uygulamayı kafada kurmaya başlayalım… Authentication kısmını standart session-cookie yöntemiyle hallettiğimizi varsayalım. Yani kullanıcı email ve şifresini giriyor, biz ona bir session açıp cookie yolluyoruz.

Şimdi framework seçimi vs gibi adımları atlayıp sizi doğrudan controllerların içerisine götürmek istiyorum. Evet geldik. Şu an ‘v1/api/tencereler’ endpointindeyiz. Buraya login olmuş tüm kullanıcı tipleri erişebiliyor. O halde istemci tarafına tencerelerimizi göndermeden önce yapmamız gereken şey, bu kişinin login olup olmadığını kontrol etmek. Eğer login olmuş bir kullanıcı ise tencereleri döndük.

Şimdi gelelim 2. duruma. Bu kez ‘v1/api/add/tencere’ endpointindeyiz. Buraya body’sinde “yavru ağzı renginde tencere ( { “renk” : “yavru ağzı”} )” bilgisi olan bir POST isteği ile geldik. İsminden anlaşıldığı gibi bu endpoint tencere eklemek için kullanılıyor. Buraya saha elemanı erişemez, satış müdürü ve genel müdür erişebilir. O halde yapacağımız şey öncelikle login kontrolü, ardından bu kullanıcının id’sine ulaşıp (db’den çekerek olabilir ki bu iyi olmaz) bu id’ye sahip kullanıcının bu endpointi kullanma hakkı olup olmadığını kontrol etmek. Tabii bu kontrolü yapabilmek için yine bir veritabanı sorgusu yapmamız gerekebilir , kurduğumuz backend logicine göre gerekmeye de bilir. Fakat neticede ortada değişmeyen bir gerçek var, o da şudur : yazdığımız yetkilendirme (authorization) akışı ne kadar akıllıca, performanslı veya mükemmel olursa olsun biz projenin bu kısmını evrensel bir standarta veya protokole bağlı olmadan, kendi yöntemlerimizle yapıyoruz.

E yapalım kardeşim iki tuşa bastık diye elimiz mi yoruldu? Hem bir proje için yaparız diğer projelerde önceden yazdığımızı kullanırız.

Şeklinde bir itirazla gelebilirsiniz. Şimdi bu mantıkta yanlış olan şeyleri yazalım:

  • Aynı kodu sonraki projelerde kullanmak bize avantaj sağlasa da bu yazdığımız yetkilendirme sistemi görüldüğü üzere generic değil. Yani daha fazla kullanıcı rolü işin içine girdiğinde kodu tanınmaz hale getirene dek değiştirmemiz bile icab edebilir. Bu da güzel bir çözüm olmaz.

  • Pek tabii ki çok daha performanslı yetkilendirme sistemleri yazılabilir fakat biz gelen her istek için veritabanına bakıldığını varsaymıştık. Her istek için bunu yapmak son derece maliyetli ve kötü bir çözümdür, bu da cümle kompüter alemine ayandır. Bunun yerine keşke ne ram’e ne db’ye gitmeden stateless şekilde login kontrollerini ve user rollerini belirleyebileceğimiz bir sistem olsaydı… Öyle olsa herhalde o yolu tercih ederdik…

  • Bizim yaşadığımız sorunları yıllarca yaşamış/gözlemlemiş abilerimiz, ablalarımız , amcalarımız , teyzelerimiz ve eser miktarda nenelerimiz dedelerimiz var. Neticesinde bu sorunu halletmenin o gün için en verimli ve dünyaca kabul edilmiş çözümünü protokol haline getirip bize sunmuşlar. Bu imkanı değerlendirmek aklın gereğidir diyoruz.

İşte günümüzde o imkan oauth2‘dir diyebiliriz.

Oauth2 bize şunu söyler : Kardeşim sen her projende authorization kısmı için yeniden bir logic tasarlıyor , adeta tekerleği tekrar tekrar icat ediyorsun. Bunu yaparken de veritabanına gitmek gibi gafletlere düşüyorsun. Ben sana bir güzellik yapayım : sana authentication ve authorization adımları için genel bir akış(flow) göstereyim. Piyasada hemen her framework için bu akışı gerçekleyecek şekilde yazılmış kütüphaneleri de bulacaksın. Sen projenin authorization kısmının temel konfigürasyonlarını yapıp gerisini bu kütüphanelere emanet et. Böylece her hem seferinde authorization logici için kafa patlatmaktan kurtulmuş hem de sorununa verimlilik açısından kaliteli ve evrensel bir çözüm sağlamış olursun.

Evet, geldik oauth2’nin iç yapısından bahsetmeye.

Oauth2 Roles

Başlamadan önce hemen bu kısmı anlamak için faydalı bir link verelim ;

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Uçtan uca Oauth2 akışında rol oynayan 4 eleman vardır:

  1. Resource Owner: User
  2. Client: Application
  3. Authorization Server
  4. Resource Server

Resource Owner : User

Sen, ben , o. Uygulamayı kullanan şahıs. Kullanıcı adı ve şifreyi yazan kimse.

Client: Application

Kullanıcının kullanmakta olduğu uygulama. Örneğin twitter hesabımızdan tweetlerimizi çekebilen bir blog uygulaması.

Authorization Server

Verdiğimiz bilgileri doğrulaması halinde bizi yetkilendiren sunucu.

Resource Server

Blog uygulaması örneği üzerinden gidersek bu Twitter oluyor. Twitter hesabının sahibi biziz (Resource owner) , bu hesabın datasını tutan da Twitter (Resource Server).

Evet, bir çok eleman gördük bir çok eleman tanıdık. Şimdi geldik en civcivli bölüme. Yani olay akışlarına.

Abstract Protocol Flow

Application Registration (Uygulamanın kaydedilmesi)

Uygulamanın oauth2 servisini kullanabilmesi için önceden Authorization Server’a tanıtılmış yani kaydedilmiş olması gerekiyor. Bunun için Auth. Server’ına aşağıdaki bilgileri tanımlıyoruz :

  1. Application Name
  2. Application Website
  3. Redirect URI or Callback URL

Eğer daha temel konfigürasyonlarına müdahele edebildiğimiz bir oauth servisi kullanıyorsak (örneğin kendi oauth servisimiz), şunları da tanımlayabiliyoruz;

  1. Client Type (Confidental or Public)
  2. Authorization Grant Type (Authorization Code , Implicit , Resource Owner Password-Based veya Client Credentials)

İlk 3’e kadarki maddeler linkini verdiğim digitalocean dokumantasyonunda yazanlar. Bunlar Google, Facebook vs.’nin oauth servisini kullanmak istediğimizde bizden istenenler. Bununla beraber biz kendi oauth sistemimizi kullanıyor da olabiliriz. Eğer kendi sistemimizi kullanıyorsak, yetkilendirme servisinin Client Type , Authorization Grant Type gibi özelliklerini de istediğimiz gibi ayarlayabiliriz. Tabii ki hizmetini dışarıdan kullandığımız sistemlerin bize bunlara müdahale edebilme serbestisini vermemesi gayet doğal. Bu iki maddenin açıklamasını sonraya bırakıyorum.

Bu tanıtma işlemi neticesinde Auth. Server bize Client ID ve Client Secret isimli 2 token veriyor. Bu tokenları client uygulamasında kullanmak üzere saklıyoruz.

Aylar sonra gelen edit: Yazarımızin burada dikkati dağılıp kendisi yaziya olan ilgisini kaybetmistir. Yazının devamını günün birisinde bitirmeye niyetli olduğunu belirtip “Bana müsade hacı” diyerek çayından bir fırt alıp gitmistir. Hepinize selamı var.

Leave a comment