Не так давно задался целью написать простой JAAS-модуль для сервера GlassFish 3, поскольку EJB Security доступна только в случае использования одного из стандартных модулей, либо своего собственного. Самым доступным и полным руководством для меня оказалась статья "Применение JAAS в Web-приложениях на glassfish v2" пользователя cy6erGn0m, но не обошлось и без неприятностей, т.к. оказалось, что в третьей версии сервера кое-что поменяли и эти ваши интернеты почти ничего об этом не говорят. В общем, я решил написать еще одно краткое руководство, в дополнение к существующему.
Создание простого JAAS-модуля
Данный модуль представляет собой обычный jar-архив даже без каких-либо дополнительных чудес сборки. Необходимым минимумом содержимого являются два класса (наследники com.sun.appserv.security.AppservRealm и com.sun.appserv.security.AppservPasswordLoginModule). Я ограничусь самой тривиальной реализацией.
LoginRealm.java :
LoginRealm.java :
/** * @author Andrey Frunt */ public class LoginRealm extends AppservRealm { @Override public String getAuthType() { return "jaas-auth"; } @Override public Enumeration getGroupNames(String string) throws InvalidOperationException, NoSuchUserException { return Collections.enumeration(Arrays.asList("admins")); } @Override protected void init(Properties props) throws BadRealmException, NoSuchRealmException { super.init(props); if (props.containsKey(JAAS_CONTEXT_PARAM)) { setProperty(JAAS_CONTEXT_PARAM, props.getProperty(JAAS_CONTEXT_PARAM)); } _logger.info("JAAS login module initialized"); } @Override public AuthenticationHandler getAuthenticationHandler() { return null; } }
LoginModule.java :
После сборки модуля его .jar файл нужно скопировать в директорию
<glassfish_dir>/glassfish/domains/<your_domain>/lib.
На этом создание самого модуля заканчивается и начинается самое интересное (настройка).
<glassfish_dir>/glassfish/domains/<your_domain>/conf
и добавляем в конец файла следующие строки:
ourLoginRealm {
jaas.auth.LoginModule required;
};
/** * @author Andrey Frunt */ public class LoginModule extends AppservPasswordLoginModule { @Override protected void authenticateUser() throws LoginException { if (_username != null && _password != null && _username.equals("admin") && _password.equals("admin")) { commitUserAuthentication(new String[]{"admins"}); } else { throw new LoginException("Incorrect credentials"); } } }Назначение данных классов можно особо не объяснять, они хорошо описаны в статье, на которую я ссылался. Замечу лишь то, что для успешной аутентификации пользователя достаточно всего лишь вызвать метод commitUserAuthentication(new String[]{"admins"}), который принимает в качестве параметра массив строк, которые содержат идентификаторы групп, к которым относится данный пользователь.
После сборки модуля его .jar файл нужно скопировать в директорию
<glassfish_dir>/glassfish/domains/<your_domain>/lib.
На этом создание самого модуля заканчивается и начинается самое интересное (настройка).
Регистрация LoginModule
Открываем для редактирования файл login.conf из директории<glassfish_dir>/glassfish/domains/<your_domain>/conf
и добавляем в конец файла следующие строки:
ourLoginRealm {
jaas.auth.LoginModule required;
};
Настройка Realm
Заходим в панель администратора сервера (по умолчанию, localhost:4848). Идем на страницу Configurations -> server-config -> Security -> Realms и нажимаем на кнопку "New" и заполняем все, как на скриншоте внизу.
Параметры:
- Realm Name - имя Realm'а, по которому мы будем ссылаться на него из приложений
- Class Name - имя класса, который наследует AppservRealm
Дополнительные параметры:
- auth-type - строка, которую возвращает метод getAuthType()
- jaas-context - имя модуля, которое мы зарегистрировали в login.conf
На этом настройка Realm'а закончена. Результатом этих действий будет появление следующих строк в
<glassfish_dir>/glassfish/domains/<your_domain>/conf/domain.xml
<security-service>
...
<auth-realm name="TestLoginRealm" classname="jaas.auth.LoginRealm">
<property name="auth-type" value="jaas-auth"></property>
<property name="jaas-context" value="ourLoginRealm"></property>
</auth-realm>
...
</security-service>
Настройка приложения
А вот тут меня ожидали грабли. Правда, кто же мог подумать, что разработчики втихую подложат такую свинью. Оказывается, с какой-то версии (я уж не стал выяснять с какой) разработчикам стукнула в голову мысль о том, что sun-web.xml - это хреновое имя для сервер-специфических настроек (уж не после покупки ли им стукнула такая мысль?). Ладно, это только мои возмущения.
В общем, чтобы Ваше приложение использовало, ранее созданный, JAAS-модуль, нужно в web.xml прописать настройку login-config.
<login-config>
<auth-method>FORM</auth-method>
<realm-name>TestLoginRealm</realm-name>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/login.html</form-error-page>
</form-login-config>
</login-config>
Ничего неординарного, обычная настройка. Зато, в отличие от базового мануала, маппинг групп на роли производится не в файле sun-web.xml, а в glassfish-web.xml. Вот такая вот подлянка от ораклятины.
glassfish-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
<context-root>/jaas-web-test</context-root>
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admins</group-name>
</security-role-mapping>
<class-loader delegate="true"/>
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class' java code.</description>
</property>
</jsp-config>
</glassfish-web-app>
Вместо заключения
Мы всегда негодуем на недостаток документации, а ведущие вендоры только поощряют это негодование своим поведением. На проблему в переименованном файле я потратил туеву хучу времени, хорошо, что я это исследовал для себя, а не в рамках реального проекта.
Вот ссылка на архив с модулем и веб-приложением. Надеюсь, кому-то данный пост пригодится.
Комментариев нет:
Отправить комментарий