JBoss Seam Security

Seam Framework ile ilgili yazı dizimizin bu seferki konuğu Seam Security. Kullanıcı yetkilendirme (authentication)  işlemlerinde Seam tarafından rol tabanlı tasarım şablonu ele alınarak hazırlanmıştır. Bu sayede ayrıntılı bir şekilde yetkilendirme sistemi hazırlayabilmemize olanak sağlar.

Authentication için session katmanında identity isimli bir nesne yaşamaktadır. Bu nesne içerisinde kullanıcıya ait username vb. bilgiler tutulur. Ayrıca role listeside bu nesne içerisinde yer almaktadır. Bu listeye kullanıcı oturum açarken sahip olduğu roller eklenir. Daha sonra kullanıcı herhangi bir işlem yaparken, o işlemi yapabilme yetkisinin olup olmadığı bu listeye bakılarak kontrol edilir. Dönen sonucu göre kullanıcıya işlem yapmasına izin verilir yada verilmez.

Role tabanlı yetkilendirme şablonuna bakıldığı zaman, Kullanıcılar ve Yetkiler tablosu şekilde bir model vardır. Bu iki tablo arasında ManyToMany ilişkisi kurulur. Çünkü bir kullanıcın birden fazla yetkisi olabileceği gibi, sistemde var olan bir yetkinin de birden fazla kullanıcısı olabilir. 

Seam-gen ya da Eclipse Seam Tools yardımı ile bir seam projesi oluşturduğunuz zaman, Seam tarafından otomatik olarak Authenticator.java isimli sınıf oluşturulur. Bu sınıf içerisinde boolean authenticate() prototipinde bir fonksiyon yer almaktadır. Bu fonksiyon bir kullanıcı oturum açmak istediği zaman çağrılır. Geriye true değer döndürdüğü zaman kullanıcı girişi başarılı bir şekilde gerçekleştirilmiş kabul edilir.

public boolean authenticate() {
    	try {
    		log.info("authenticating {0}", credentials.getUsername());
    		EntityManager em = (EntityManager) Component.getInstance("entityManager");
    		User user = (User) em.createQuery("FROM User user WHERE " +
    					"user.userName = :uname AND " +
    					"user.password = :pass")
    				.setParameter("uname", credentials.getUsername())
    				.setParameter("pass", credentials.getPassword())
    			.getSingleResult();
    		
    		for(Role role: user.getRoles()) {
    			identity.addRole(role.getName());
    		}
        
    	}
    	catch (Exception e) {
		e.printStackTrace();
		return false;
	}
}

Yukaridaki authenticate fonksiyonu inceledigimiz zaman veritabanindan giris yapmak isteyen kullanicinin bilgieri kontrl edilmektedir. Eger böyle bir kullanici var ise yine veritabanindan bu kullaniciya ait rolleri çekip iterasyon yolu ile identity nesnesi içinde yer alan role listesine identity.addRole() fonksiyonu ile ekliyoruz.


s:hasRole

xhtml ve java sayfalarida bir islemi yapmak için kullanicinin yetkisi olup olmadigini kontrol etmek amaci ile seam tarafindan gelistiricilere sunulmustur. Parametre string tipinde role adini almaktadir. indentity nesnesi içindeki role listesinde , parametre olarak gönderilen degerin var olup olmadigini kontrol ederek geriye boolean deger döndürür.


1) xhtml sayfasini kullanicilara sinirlamak

Seam’in framework yapisi olarak her xhtml sayfasina ait sayfa ile ayni isimde bir adet de page.xml dosyalari yer almak zorundadur. Bu page.xml sayfalarinda xhtml sayfasinda yapilan islemlere göre navigasyon tanimlamari, parametre alma / gönderme islevleri ve yetkilendirme gibi tanimlamalar yapilmaktadir. 

Bir html sayfasina giris için yetki tanimlamak istiyorsak asagidaki kodu page.xml sayfasina koyuyoruz.

<restrict>#{s:hasRole(‘yonetici')}</restrict>

Bu sekilde sayfaya girilmek istendiginde , kullanicnin role listesinde yonetici rolünün olup olmadigi kontrol edilir. Eger geriye false döner ise , kullaniciya bu sayfaya giris yetkiniz yok seklinde mesaj gösterilir.


2) xhtml sayfalarinda kullanici yetkisine göre componentleri render etmek

jsf componentlerinin hemen hemen tümünde yer alan rendered özelliginden faydanilarak yetkilendirme islemine tabi tutulabilinir. 

<h:commandButton value=”Sil”  action=”userHome.remove(user)”rendered=”#{s:hasRole(‘uye_sil')}” />

Tukaridaki örnekte Üye silme islemi yapan buton sadece uye_sil yetkisi bulanan user tarafindan görüntülenebiliniyor. uye_sil yetkisi olmayan user için s:hasRole fonksiyonundan false dönecegi için sayfada render olmayacaktir.


3) Kullanici tarafindan oturum açma bilgisini tutan degisken

Sistemde dolasan kullanicinin oturum açip açmadigini identity sinifi içerinde yer alan boolean loggedIn degiskenine bakarak ögrenebiliriz. Degiskenin degeri true ise kullanici adi ve sifre kullanilarak oturum açilmis demektir.


4) Bir sayfayi sadece oturum açan kisilere gösterebilmek

Bazi sayfalarin görüntülenebilmesi için kullanicinin oturum açmis olmasini isteyebiliriz. Örnegin kullanicinin üyelik  bilgilerini düzenlendigi bir sayfaya girilmek isteniliyorsa öncelikle oturum açmis olmasi gerekmektedir. Bu durumu page.xml sayfalarinda tanimlama yapilirken kullanilan page componentinde yer alan login-required özelligini true yaparak saglayabiliriz. 

Kullanici eger oturum açmamis bir sekilde bu sayfaya girmek istedigi taktirde öncelikle login açmasi için seam tarafindan otomatik üretilen login.xhtml sayfasina yonlendirilip kullanici adi ve sifresi ile oturum açmasi istenecektir. Oturum açma islemi basarili bir sekilde gerçeklestirilirse, otomatik olarak girmek istedigi ilgili sayfaya yönlenecektir. 


5) Java Bean sınıflarında yetki kontrolünü yapmak 

Bir fonksiyonu yetkilendirmeye tabi tutmak istiyorsak o fonksiyonun basina @Restrict annotationini eklememiz yeterlidir.

@Restrict("#{s:hasRole('admin')}")
public void delete() {

}
Bir fonksiyonu yetkilendirmeye tabi tutmak istiyorsak o fonksiyonun basina @Restrict annotationini eklememiz yeterlidir.

Kamil Örs
Software Developer






0.000105142593384 | 3.5