JSON Web Token (JWT) Authentication

Sümeyye Akay
Kodluyoruz
Published in
4 min readAug 9, 2020

Herkese merhaba :) Bu haftaki konumuz Spring Boot + Spring Security’de sıklıkla kullandığımız JSON Web Token (JWT).

İlk önce JWT’in ne olduğuna ve yapısını anladıktan sonra birlikte bir proje gerçekleştireceğiz. Hazırsanız başlayalım.

Spring Boot + Spring Security + JWT

JSON Web Token(JWT) Nedir?

Secure Communication

JWT iki tarafın birbirleri arasındaki veri alışverişini ve bunun doğrulamasını sağlayan JSON tabanlı RFC 7519'de tanımlanmış açık bir standarttır.

Mesela sunucu, kullanıcının yönetici ayrıcalıklarına sahip olduğunu belirten bir anahtar(token) oluşturabilir ve bunu kullanıcıya gönderebilir. Kullanıcı daha sonra bu anahtar ile kendisine tanımlanmış olan yönetici yetkisini bir istemci de kullanabilir.

JWT Çalışma Yapısı

Kullanıcı siteye bulunduğu ilk istekte site tarafından kimlik doğrulamasına oluşuyor ve web sitesi karşılık olarak JSON parçası gönderiyor. Kullanıcı tekrar sisteme giriş yapmak istediğinde bu parça ile yapıyor ve web sitesi tarafından doğrulanıyor.

Avantajları

  • JWT’ler durumsuz (stateless) oldukları için kullanıcı durumlarının elde edilmesi için veritabanı sorgulamasına gerek kalmaz.
  • Oturum yönetimi, çerezler kullanılmaksızın yapılabilir.
  • Tek bir anahtar, birden fazla arka uçta (backend) kullanılabilir.
  • Veritabanı sorgulaması ya da dosya sistemi kullanımı gerektirmediği için performanslıdır.

Dezavantajları

  • JWT anahtarı yeterince güçlü değilse kırılması daha kolay olur.

JSON Web Token(JWT) Yapısı

JWT, Base64 biçiminde kodlanmış 3 ayrı JSON parçasından oluşmaktadır. Parçalar nokta (.) sembolüyle ayrılmakta ve bir bütün olarak JWT’yi temsil etmektedir.

Bunlar header, payload ve verify signature’dan oluşmaktadır.

Bu 3 yapıyı daha yakından incelersek;

Default JWT yapısı

Header, JWT başlık bilgisi JSON biçiminde yazılmakta ve standart bazı alanları bulunmaktadır.

“alg” Veri bütünlüğünü korumak için kullanılacak cryptotic algoritmayı belirtir. İstediğiniz algoritmayı burada seçebilirsiniz.

“typ” ise JWT nesnesi olduğunu belirtir.

Payload, içinde kullanıcıya ait kimlik, zaman aşımı ve kullanıcı yetkileri gibi alanlar yer alabilir. Bunlara ek olarak eğer sistem üzerinde role tabanlı işlem yapılacaksa burada belirtilir.

Verify signature, imza kısmı token üreticisi ve tüketicisi arasındaki veri bütünlüğünü garanti etmektedir. İmza oluşturulurken JOSE başlığında tanımlı algoritma kullanılmaktadır.

JWT Çalışma Yapısı

Çalışma Yapısı

Çizimden de anlaşılacağı üzere JWT ile token bazlı sisteme giriş yapmak için belirli adımları takip eder. İlk adım kullanıcının servera userID ve password ile giriş yapması ile başlar(giriş tercihleri değişebilir). Server tarafından kimlik doğrulaması yapılır ve JWT kullanıcı tarafına geri gider. Bu değer local veya çerezlere kaydedilir ve belirteç servera gider. Kullanıcı sisteme giriş yapar.

Şimdi öğrendiklerimizi bir projede uygulayarak yapının nasıl işlediğini daha iyi anlayalım.

Yeni bir proje açalım.

Spring Boot + Spring Security

İlk olarak yeni bir kimlik doğrulama API’si oluşturalım ve gelen her talebi geçerli JWT için inceleyelim ve yetkilendirelim.

Projemize başlarsak eğer basit bir controller yapısı oluşturalım.

Sırada SecurityConfig.java classını oluşturmakta. Bu sınıfımız WebSecurityConfigurerAdapter’ dan extends alacaktır. Bu sayede varsayılan yapılandırma alanlarını yaparız.

configure metodunu @override ederek veritabanı yapılandırmamızı burada yaparız.

Bu metodla basit bir UserDetailsService kullanarak standart senaryoya kıyasla ek esneklik sağlamak için Spring Security’de bir Kimlik Doğrulama Sağlayıcısının nasıl kurulacağını göreceğiz.

Kodumuzun daha anlaşılır olması için bu kısımda kullanıcı adı ve şifreyi bir array list olarak verdik. Siz isterseniz bu kısımda veritabanından da bu bilgileri çekebilirsiniz.

Tekrar SecurityConfig.java sınıfımıza dönecek olursak,

Password işlemlerimizin şifreli bir biçimde kaydedilmesini istersek eğer PasswordEncoder metodunu eklememiz gerekmektedir.

Artık şifremiz belirli bir şifreleme algoritması ile tutulacaktır. Buna ek olarak BCryptPasswordEncoder da fazlasıyla tercih edilmektedir.

Bu kısıma kadar yazdığımız kodlarda hala json web token(JWT) den bahsetmedik.Dolayısıyla projemizde güvenlik açıkları söz konusu artık genel ayarlamaları yaptıktan sonra sırada projemize tokenlar nasıl oluşturulur onu görmek kaldı.

pom.xml içinde kullanacağımız paketleri ekliyoruz.

Jwt.util sınıfı oluşturuyoruz. Bu sınıf içerisinde oluşturulan metodlar defaulttur. Biz ihtiyacımız olan kısımda metoda müdahale ederek gerekli tanımlamaları yaparız. Bu sınıfı bütün projelerinizde kullanabilirsiniz.

AuthenticationRequest.java(input) sınıfımız saysinde postman üzerinden post işleminde bulunmak istediğimizde json olarak username ve password göndermemiz için bu sınıfa ihtiyacımız var.

Göndermiş olduğumuz değerleri bize token olarak dönmesi için ilk önce bir AuthenticationResponse.java(output) yani kimlik doğrulama yanıtı dönecek bir sınıf oluşturuyoruz.

LoginController içinde post işleminde bulunacağımız bir metod daha ekliyoruz.

Bu sayede kullanıcı adını ve şifremizi girdikten sonra bize bir JWT değeri dönecektir. Eklediğimiz bu isteği SecurityConfig içinde yetkilendirmede belirtmemiz gerekmektedir.

Böylelikle sadece belirli bir JWT değerine sahip olan kullanıcıların sisteme giriş yapması sağlanacaktır.

Role bazlı yapılacak işlemleri HttpSecurity içinde yaparız.

Uygulamamızı çalıştırarak postman üzerinden login isteği gönderelim.

Girdiğimiz username ve password için bir jwt token elde ettik. Şimdi bu token ile giriş yapabilmek için yine postman üzerinden,

Eğer ki authorization seçeneğine tıklamazsak bize Access Denied yani yetkimiz olmadığı için bu sayfayı görüntüleyemezdik.

Bearer yazdıktan sonra elde ettiğimiz JWT’yi buraya ekliyoruz.

Projemize genel olarak bakarsak Json Web Token hakkında genel bir bilgiye sahip olduk ve bir proje ile nasıl kullanıldığını basit bir şekilde görmüş olduk.

Böylece genel olarak JWT hakkında genel bir bilgi sahibi edindik. Bundan sonra ki yazımda JWT kullanarak kullanıcı bazlı işlemler nasıl yapılır onu inceleyeceğiz ve bu sefer bu işlemleri veritabanı üzerinden yapacağız.

Bir daha ki yazımda görüşmek üzere 👋🏻

--

--