in Hata Çözümleri

“Expected CSRF token not found. Has your session expired?” hatası ve çözümü

Spring Security ve Thymeleaf kullanarak bir proje geliştirirken takıldığım bir hatanın çözümünü paylaşıyorum.Öncelikle CSRF nedir ve neden kullanmalıyız buna değinelim.

CSRF uzun haliyle Cross Site Request Forgery demektir. Kısaca formdan gelen verilerin bizim uygulamamız dışından gelmesini engelleme mekanizmasıdır.CSRF anahtarı otomatik olarak üretilir.Spring Security bize böyle bir kolaylık sağlıyor.Spring Boot’ta ise bu varsayılan olarak gelmektedir.

Tek yapmamız gereken view katmanı yani thymeleaf dosyamızda form etiketinin içerisine aşağıdaki kodu eklemektir.

_csrf değişkeni CsrfToken nesnesini barındırır.${_csrf.parameterName} komutu _csrf nesnesinin getParameter() methodunu çağırır ve bu varsayılan olarak _csrf’dir.${_csrf.token} komutu ise getToken() methodunu çağırır ve bu asıl anahtarımızdır.

Devam edelim…

Eğer Spring Security konfigürasyonu için XML yerine Java kullanıyorsak CSRF’nin otomatik olarak enabled olduğunu bilelim.Bu nedenle CSRF kullanmak istemiyorsak konfigürasyonu aşağıdaki kodu eklemeliyiz.

Bir diğer ayrıntı ise WebSecurityConfigurerAdapter sınıfını extends eden konfigürasyon sınıfımızın tanımlamasında @EnableWebSecurity yerine @EnableWebMvcSecurity kullanmamız gerekiyor.

If you are using Spring MVC <form:form> tag or Thymeleaf 2.1+, and you replace @EnableWebSecurity with @EnableWebMvcSecurity, the CsrfToken is automatically included for you (using the CsrfRequestDataValueProcessor).

Spring dökümantasyonunda belirtildiği üzere; eğer Thymeleaf kullanıyorsak bu anotasyonu değiştirmemiz gerekiyor.Böylelikle CsrfToken otomatik olarak eklenecektir.

Peki bütün bunları yaptık.Csrf’yi disable yapmadık ve aktif bıraktık. @EnablebMvcSecurity anatasyonunu kullandık.Dolayısıyla Spring otomatik olarak ekleyecek. Thymeleaf dosyamızda aşağıdaki gibi;

Ama hala şu sinir bozucu hatayı alıyoruz.

Expected CSRF token not found. Has your session expired?

veya

Invalid CSRF Token ‘null’ was found on the request parameter ‘_csrf’ or header ‘X-CSRF-TOKEN’

İşte olayın çözüldüğü yer burası.Thymeleaf dökümantasyonunda belirtildiği üzere; eğer hidden bir element kullanıyorsak form’un action özelliğini th:action ile tanımlamamız gerekiyor.Böylelikle thymeleaf getExtraHiddenFields methodunu ekliyor ve eksta hidden tanımlanmış elementlerde forma ekleniyor. _csrf elementimiz hidden tanımlandığı içinde sorunumuz böylelikle çözülmüş oluyor.
Doğru hali şu şekilde olmalıdır.

Kaynaklar;
Spring Csrf
Thymeleaf Dökümantasyonu

Yorum yaz

Comment