10 Şubat 2008

JBoss için Login Module Tanımlanması ve Rol Bazlı EJB Güvenliği

Java Authentication and Authorization Service (JAAS) ve EJB Güvenliği adlı yazımda JAAS'dan kısaca bahsetmiştim. JAAS'ın kullandığı bir yapı olan Login Module kavramının ne olduğuna da kısaca değinmiştim. Login Module login işleminin gerçekleştiği birimlerdir. Her sistem farklı tipte login gerçekleştirebilir. Kimisi basit kullanıcı adı ve şifre bilgileri ile bu işlemi yaparken kimisi sertifika bazlı işlem yapabilir. JBoss'da kendi içinde JAAS'ı kullanmaktadır. Bu nedenle JBoss üzerinde çalıştırdığınız EJB'lere rol bazlı erişim sağlamak istiyorsanız JBoss'un kendi sunduğu bir login modül kullanabilirsiniz yada kendiniz oluşturabilirsiniz. Burada kendimiz nasıl oluştururuz ona bakalım.

Yazacağınız login module JBoss'un sunduğu AbstractServerLoginModule abstract sınıfını extend etmelidir. Bu linkte kaynak kodunu görebilirsiniz (Ayrıca bu sınıfı kullanan JBoss login modülleri olan UsernanePasswordLoginModule ve DatabaseServerLoginModule sınıflarının kodları da incelenmesi gerekmektedir). Bu nedenle yazacağınız kod getRoleSets() ve getIdentity() metodlarını override etmelidir. Tabi bunlarla kalmamak lazım. Bir de login işlemini gerçekleştiren login() metodu var. Bu metod bu sınıfta implemente edilmiş ama biz kendimize uygun bir login modül oluşturacağımız için bu metodu da override etmemiz gerekir. Ayrıca login module ilklendirilirken kullandığınız seçenekler var ise initialize() metodunu da override etmek gerekir. Genel olarak sınıf aşağıdaki gibi olacaktır:

package com.ornek;

public class MyLoginModule extends AbstractServerLoginModule {

...

/*

burada options parametresi login modül'e verilen optionları barındırır, callbackHandler giriş bilgilerini barındırır, subject de rol bilgilerini tutar.

*/

public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {

...

}

/*

login işlemi burada gerçekleştirilir. işlem başarılı ise mutlaka süper sınıfta tanımlanmış loginOk değişkeni true değerine atanmalıdır. Aksi takdirde süper sınıftaki commit metodu çalışmaz.
*/

public boolean login() throws LoginException {

}

...

super.loginOk = true;

...

}

/*

Login olan kullanıcının role gruplarını oluşturan bir metoddur ve override edilmesi gerekir. Bu metod override edildiğinde kullanıcının role bilgilerini barındıran en azından “Roles” adında bir Group oluşturulmalıdır.

*/

protected Group[] getRoleSets() throws LoginException {

...

}

/*

Kullanıcının birincil giriş bilgisini içeren Principal nesnesini döndürür.

Bu metod genelde login metodu içinde oluşturulan Principal nesnesini döndürür.

*/

protected Principal getIdentity() {

...

}

Kendi modülünüzü yazdıktan sonra bunun Jboss’a tanıtılması gerekmektedir. Bunun için login module sınıfınızı jar haline getirin ve Jboss deploy kütüphanelerini (/server/default/lib) arasına oluşturduğunuz jar’ı kopyalayın. Daha sonra deploy konfigürasyonlarının olduğu dizin (/server/default/conf) altındaki login-config.xml dosyasını açın. Bu dosyaya kendi login modulünüzü ekleyeceksiniz. Zaten dosyanın başında nasıl yapcağınız anlatılıyor. Örneğin yukarıdaki sınıfı şu şekilde eklenebilir:





Görüldüğü üzere kendi yazacağınız login module sınıfında yukarıdaki üç metodu override etmeniz yeterli olacaktır. login metodu düzgün olarak çalıştığında ve super.loginOk = true ise süper sınıf kendi içindeki commit metodunu çalıştıracak ve kullanıcının rol bilgilerini oluşturan getRoleSets metodunu çağıracak. Bütün işlemler bittiğinde kullanıcıya ait giriş ve rol bilgilerini barındıran bir Subject nesnesi oluşturulacak. Bu nesne ejb metodları çağırılırken çağıranın rol bilgilerinin kontrolü için kullanılacak. Örnek:

@Remote

public interface MyEJB {

public void myMethod();

}


@SecurityDomain(“MyLoginModule”)

@Stateless

public MyEJBImpl implements MyEJB {

@RolesAllowed(“MyRoleName”)

public void myMethod() {

...

}

}

Yukarıdaki örnekte EJB metodları çalıştırılmadan önce MyLoginModule ismindeki login modülün çalıştırılacağı ve kullanıcının girişinin gerçekleştirileceği SecurityDomain annotation’ı ile belirtilmiştir. SecurityDomain annotation’ı içine vereceğiniz login module ismi login-config.xml dosyasında tanımlı olmalıdır. Kullanıcı girişi gerçekleştirildiğinde istenilen ejb metodu çağırılır aksi takdirde hata verilir.

Bir EJB metodu olan myMethod’a sadece MyRoleName rolundeki kullanıcıların erişebileceği @RolesAllowed annotation’ı ile gösterilmiştir. Bu annotation içine birden fazla rol yazabilirsiniz @RolesAllowed(“Role1”, “Role2”, ...) şeklinde. İşte bu annotation içindeki rol bilgileri login module tarafında oluşturulan Subject nesnesinin içindeki rol bilgisiyle karşılaştırılır. Eğer Subject nesnesi bu rollerden birisini barındırıyorsa metod çalıştırılır. Aksi takdirde çalıştırılmaz.