Ни для кого не секрет что сервера приложений существуют для того чтобы снять некоторую часть работы с разработчика и возложить её на уже готовые механизмы. В частности механизм аутентификации в сервере приложений Glassfish можно организовать с помощью так называемых Security Realms. Существуют несколько встроенных вариантов, такие как аутентификация через СУБД, LDAP, PAM, Certificate и обычное чтение из файла. Однако они могут нас не устроить ввиду своей ограниченности (LDAP, например, может работать только с одним наперед заданным доменом). Поэтому мы и рассмотрим создание собственного security realm’а.
Custom security realm состоит минимум из двух классов. Один из которых расширяет класс AppservRealm (com.sun.appserv.security.AppservRealm), а второй соответственно AppservPasswordLoginModule (com.sun.appserv.security.AppservPasswordLoginModule). Для получения com.sun.appserv.security.* нужно импортировать в качестве библиотеки /glassfish/modules/security.jar
В классе realm'а необходимо переопределить методы получения типа аутентификации (обычно это название realm'а) и получение групп пользователя по его имени — в данной статье мы умышленно упускаем обзор Java EE авторизации.
Соответственно здесь мы и можем реализовать гибкость механизма в получении групп по имени пользователя, например из СУБД. В данном примере используется одна группа, которая показывает что пользователь прошел аутентификацию. Property jaas-context указывается здесь чтобы связать данный класс со следующим.
В данном классе необходимо реализовать метод аутентификации. Он состоит из получения и проверки использующего его realm'а, проверки правильности введенных логина и пароля (либо других реквизитов) и наконец, получения и передачи групп пользователя.
Скомпилированные классы (пакеты с соответствующими классами внутри) кладем в директорию <домен glassfish>/lib/classes
Также мы должны определить что наш AppservPasswordLoginModule относится к определенному контексту. Нужно отредактировать файл <домен glassfish>/config/login.conf добавив «ссылку»:
В котором мы определяем контекст и ссылаемся на необходимость модуля.
Смело запускаем/перегружаем наш сервер приложений и открываем GUI администратора.
Создаем новый Security Realm. Теперь нам не нужно выбирать класс из списка, а вводим полный класс реалма: ru.khmb.security.Realm. Не забываем указать опцию jaas-context которая связывает наш realm с модулем аутентификации через контекст указанный в файле login.conf, т.е. в нашем случаи jaas-context = KHMBRealm
Всё, теперь можно пользоваться Realm'ом.
При реализации механизма источником была запись в блоге.
Update 02.08.2013:
Есть хорошее описание создания различных Security Realm'ом (областей безопасности) в книге Дэвида Хеффельфингера «Java EE 6 и сервер приложений GlassFish 3»
Custom security realm состоит минимум из двух классов. Один из которых расширяет класс AppservRealm (com.sun.appserv.security.AppservRealm), а второй соответственно AppservPasswordLoginModule (com.sun.appserv.security.AppservPasswordLoginModule). Для получения com.sun.appserv.security.* нужно импортировать в качестве библиотеки /glassfish/modules/security.jar
package ru.khmb.security; import com.sun.appserv.security.AppservRealm; import com.sun.enterprise.security.auth.realm.BadRealmException; import com.sun.enterprise.security.auth.realm.InvalidOperationException; import com.sun.enterprise.security.auth.realm.NoSuchRealmException; import com.sun.enterprise.security.auth.realm.NoSuchUserException; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; public class Realm extends AppservRealm { private static final String PARAM_JAAS_CONTEXT = "jaas-context"; private static final String GROUP_ALL = "Authenticated"; @Override public void init(Properties properties) throws BadRealmException, NoSuchRealmException { String propJaasContext = properties.getProperty(PARAM_JAAS_CONTEXT); if (propJaasContext != null) { setProperty(PARAM_JAAS_CONTEXT, propJaasContext); } } @Override public String getAuthType() { return "KHMB Realm"; } @Override public Enumeration getGroupNames(String user) throws InvalidOperationException, NoSuchUserException { Vector vector = new Vector(); vector.add(GROUP_ALL); return vector.elements(); } }
В классе realm'а необходимо переопределить методы получения типа аутентификации (обычно это название realm'а) и получение групп пользователя по его имени — в данной статье мы умышленно упускаем обзор Java EE авторизации.
Соответственно здесь мы и можем реализовать гибкость механизма в получении групп по имени пользователя, например из СУБД. В данном примере используется одна группа, которая показывает что пользователь прошел аутентификацию. Property jaas-context указывается здесь чтобы связать данный класс со следующим.
package ru.khmb.security; import com.sun.appserv.security.AppservPasswordLoginModule; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import javax.security.auth.login.LoginException; public class LoginModule extends AppservPasswordLoginModule { @Override protected void authenticateUser() throws LoginException { if (!(_currentRealm instanceof Realm)) { throw new LoginException("Realm not KHMBRealm"); } Realm realm = (Realm) _currentRealm; authenticate(_username, _password); Enumeration enumeration = null; List<String> authenticatedGroups = new LinkedList(); try { enumeration = realm.getGroupNames(_username); } catch (Exception e) { throw new LoginException("Get groups exception"); } for (int i = 0; enumeration != null && enumeration.hasMoreElements(); i++) { authenticatedGroups.add((String) enumeration.nextElement()); } commitUserAuthentication(authenticatedGroups.toArray(new String[0])); } private static void authenticate(String login, String password) throws LoginException { try { LDAP.authenticate(login, password); } catch (Exception e) { throw new LoginException("Authenticate exception:" + e.getMessage()); } } }
В данном классе необходимо реализовать метод аутентификации. Он состоит из получения и проверки использующего его realm'а, проверки правильности введенных логина и пароля (либо других реквизитов) и наконец, получения и передачи групп пользователя.
Скомпилированные классы (пакеты с соответствующими классами внутри) кладем в директорию <домен glassfish>/lib/classes
Также мы должны определить что наш AppservPasswordLoginModule относится к определенному контексту. Нужно отредактировать файл <домен glassfish>/config/login.conf добавив «ссылку»:
KHMBRealm { ru.khmb.security.LoginModule required; };
В котором мы определяем контекст и ссылаемся на необходимость модуля.
Смело запускаем/перегружаем наш сервер приложений и открываем GUI администратора.
Создаем новый Security Realm. Теперь нам не нужно выбирать класс из списка, а вводим полный класс реалма: ru.khmb.security.Realm. Не забываем указать опцию jaas-context которая связывает наш realm с модулем аутентификации через контекст указанный в файле login.conf, т.е. в нашем случаи jaas-context = KHMBRealm
Всё, теперь можно пользоваться Realm'ом.
При реализации механизма источником была запись в блоге.
Update 02.08.2013:
Есть хорошее описание создания различных Security Realm'ом (областей безопасности) в книге Дэвида Хеффельфингера «Java EE 6 и сервер приложений GlassFish 3»
