JSF Spring

Anotasyonlarla Spring Security Kullanımı

Merhabalar arkadaşlar. Bu yazıda Spring çatısının güvenlik modülü olan Spring Security’nin anotasyonlarla nasıl kullanıldığını öğrenmeye çalışacağız.

Bu yazıda kullanılan projeyi Github hesabımda paylaştım. Maven projesi olduğu için IDE’nizde çalıştırabilir, test edebilirsiniz. Proje şuradadır:https://github.com/ilkgunel/SpringSecurityWithAnnotations

Daha önce şuradaki yazımda bir XML dosyası ile Spring Security’nin kullanımını anlatmaya çalışmıştım. Bu yazıda ise tamamen XML olmadan aynı işi yapmaya çalışacağız. Şimdi başlayalım 🙂

web.xml

Web.xml dosyasına şöyle bir göz gezdirdiğinizde Spring’e dair hiçbir şey göremeyeceksiniz. Yazımızın konsepti de bu. Tüm işlemler kod aracılığı ile yapılacak.

Web.xml’den anlayacağımız üzere ana sayfamız hello.xhtml.

hello.xhtml

Hello sayfasında basit bir karşılama yapıyoruz ve giriş sayfasına yönlendiren commandLink kullanıyoruz. <input type=”hidden” />’nın bulunduğu satırda bir CSRF token göndermesi yapıyoruz. Küçük bir araştırma yaptım ve Spring 4 ile birlikte CSRF token meselesinin açık olarak geldiğini gördüm. Kod içerisinden istenirse CSRF disable edilebilir fakat bu da tavsiye edilen bir durum değil.

girisYap.xhtml

Giriş yapma sayfamızda <head> etiketleri arasındaki f:event bu sayfaya istekte bulunulduğunda oturum açıl açılmadığına bakan kodu çağırıyor ve ona göre ya bu sayfayı atlıyor ya da açıyor.

p:inputText ve p:password etiketleri ile kullanıcıdan kullanıcı adı ve parolasını alıyoruz.

p:commdandButton ile de giriş yaptırıyoruz.

En alttaki h:outputLabel giriş sırasında meydana gelecek hataları ekrana yazdırmak için var.

/adminPage/adminPage.xhtml

Admin sayfasında bir karşılama mesajı ve çıkış linki yer alıyor.

/guestPage/guestPage.xhtml

Guest sayfasında bir karşılama ve çıkış linki yer alıyor.

AppConfig.java

AppConfig sınıfımız iki notasyon ile işaretli ve içinde veri tabanına bağlantı kuracak kısım ile giriş sırasındaki hataları Türkçe’ye çevirecek messages dosyasının kayda geçirilmesi yapılıyor.

@Configuration notasyonu sınıfın bir ayarlama sınıfı olduğunu bildiriyor.
@ComponentScan(value = {“myPackage”}) ifadesi kendisine value olarak verilen paketleri tarayan ve gerekli yüklemeleri yapan ifadedir. Örneğin birazdan göreceğimizspringSecurityFilterChain’i yükleme görevi olan  SpringSecurityInitializer sınıfı bu notasyon sayesinde işini yapar.

@Bean(name = “messageSource”) ile işaretli metot, giriş sırasında meydana gelen hataları kullanıcıya bildirmek için messages properties dosyasının kullanımını gösteriyor.
  @Bean(name = “dataSource”) ifadesi ile dataSource isminde az sonra başka bir sınıfta kullanacağımız bir veri kaynağı hazırlamış oluyoruz.

SecurityConfig.java

SecurityConfig sınıfımızda da bir takım ayarlama tanımlamaları var olduğundan bu sınıf da @Configurtion ile işaretli. İlave olarak bu sınıfta güvenlik ile ilgili tanımlamaları yapacağımız için @EnableWebSecurity notasyonu ile sınıfımız işaretli.

Sınıf içerisinde güvenlik işlemlerinde kullanılacak veri tabanı işlemleri için az önce tanımlananan dataSource’u @AutoWire notasyonu ile sınıfımıza enjekte ediyoruz. @AutoWire tanımlı ve gerekli olan sınıfdan bağımlılığı otomatik yükleyebilen bir notasyondur.

Devam eden kısımda @AutoWire ile işaretlenmiş configureGlobal metodunda kullanıcı adını ve şifresini giren kullanıcının kimlik doğrulama ve yetkilendirme işlemi yapılıyor. usersByUsernameQuery metodu kimliği doğrulama, authoritiesByUsernameQuery metodu yetkilendirme vazifelerini üzerinlerine alıyorlar. passwordEncoder metodu da veri tabanında Hash’li bir şekilde tutulan parola ile karşılaştırma yapmak için kullanıcının girdiği parolayı verilen hash algoritmasına göre hash’leyen metotdur.

configure metodu içerisinde sayfaların erişim haklarını yazıyoruz. Örneğin guestPage dizini ve dizinin içindekilere ROLE_GUEST ya da ROLE_ADMIN yetkisine sahip kişilerin erişebileceğini söylüyoruz. loginPage metodu ile giriş sayfasını tanımlıyor, defaultSuccessUrl ile başarılı girişin yönlendirileceği sayfayı belirtiyoruz. http.logout().logoutRequestMatcher(new AntPathRequestMatcher(“/logout”)); ifadesi de kullanıcının çıkış yapabilmesini sağlayan kısımdır.

SpringMvcInitializer.java

SpringMvcInitializer sınıfı projenin çalışması için gerekli olan DispatcherServlet yüklenmesi vazifesini yerine getiriyor.

SpringSecurityInitializer.java

SpringSecurityInitializer sınıfı SpringSecurityFilterChain’i otomatik yükleme vazifesini üzerine alan sınıfdır. Bu otomatik yükleme işlemini extend ettiği AbstractSecurityWebApplicationInitializer aracılığı ile yapar.

EKRAN ÇIKTILARI

Projenin ekran çıktılarından önce veri tabanındaki kullanıcıların barındığı tabloya bakalım.

Screen Shot 2016-01-09 at 01.13.02

Ayrıca bir de yetkilendirme için kullanılan userroles tablosuna bakalım.

Screen Shot 2016-01-09 at 01.15.24

Projeyi çalıştırdığımda gelen ekran. Tarayıcıdaki URL’e /adminPage/adminPage.xhtml ya da guestPage/guestPage.xhtml eklemesi yaptığımızda güvenlik çatısında yaptığımız ayarlamalardan ötürü giriş sayfasına yönlendirileceğiz. Giriş yapmak için tıklıyorum.

Screen Shot 2016-01-09 at 00.59.47

Giriş yapma ekranı. Şimdi geçersiz şeylerle giriş denemesi yapıyorum.

Screen Shot 2016-01-09 at 01.04.47

Başarısız olan giriş denemesi neticesinde sebep bize döndürüldü. Şimdi ilkgunel – 12345 kombinasyonu ile giriş yapacağım.

Screen Shot 2016-01-09 at 01.06.15

Başarılı bir şekilde giriş yaptım ve varsayılan olarak Guest sayfasına yönlendirildim. Veri tabanında ilkgunel ROLE_GUEST yetkisine sahip. Admin erişimine açık sayfaya erişim talep edelim.

Screen Shot 2016-01-09 at 01.07.58

Access is denied uyarısı alarak admin sayfasına erişimim Spring Security tarafından engellendi. Şimdi geri gelip çıkış yapıp turgunel hesabı ile giriş yapıyorum.

Screen Shot 2016-01-09 at 01.10.33

turgunel hesabı ROLE_ADMIN yetkisinde olduğu için admin sayfasına başarılı bir erişim sağladım.

Screen Shot 2016-01-09 at 01.17.23

Bu yazıda anlatıcaklarım bu kadar arkadaşlar. XML’e hiç bulaşmadan (web.xml & Spring XML) Spring Security’nin nasıl kullanıldığını öğrenmiş olduk. Umarım faydalı ve anlaşılır bir yazı olmuştur. Varsa eleştiri ve düşüncelerinizi ya da sorularınızı yoruma yazmanızı sizden rica ederim arkadaşlar. Başka bir yazıda görüşene kadar sağlıcakla kalın.