Есть рабочее J2EE приложение (А), которое использует внутреннюю аутентификацию и авторизацию не используя JAAS и также собственную библиотеку в качестве движка. Задача переписать это приложение так, что бы уйти от старого движка, но делать это по частям. Новое приложение (Б) должно использовать JAAS. Т.е. на переходном этапе приложение должно использовать одновременно и старый движок и новый (части А и Б).
Функционально логику работы приложения удалось разделить, остался вопрос аутентификации/авторизации.
Все страницы нового приложения защищены с использованием <security-constraint/> в web.xml
У приложения А есть login screen куда вводится имя пользователя и пароль. Задача: при аутентификации пользователем в части А пройти аутентификацию и в части Б.
Для этого я написал LoginModule который содержит всю логику аутентификации.
Сам по себе он работает. Если посылать запрос j_security_check?j_username=username&j_password=passwd то после успешной аутентификации в сессии появляется пользователь username, имя котрого я могу получить через req.getRemoteUser().
Вопрос 1: Как мне провести аутентификацию в логин модуле не посылая запрос j_security_check?
Я делал так:
создал LoginContext и MyCallbackHandler(), описав там handle() инициализирущий должным образом имя пользователя и пароль.
Все этапы аутентификации проходят успешно. Subject создается правильно. А getRemoteUser возвращает null.
И на страницы защищенные <security-constraint/> меня не пускают
Вопрос 2: Как поместить subject в сессию так, что бы логин модуль понимал, что аутентификация уже выполнена.
Хм... Сумбурно получилось, но если коротко: надо выполнить аутентификацию не посылая запроса j_security_check.
Здравствуйте, Аноним, Вы писали:
А>Для этого я написал LoginModule который содержит всю логику аутентификации. А>Сам по себе он работает. Если посылать запрос j_security_check?j_username=username&j_password=passwd то после успешной аутентификации в сессии появляется пользователь username, имя котрого я могу получить через req.getRemoteUser().
Вот этот момент не очень понятен. Для j_security_check (контейнероной аутентификации) LoginModule вроде как не нужен. Как ты их связал?
А>Вопрос 1: Как мне провести аутентификацию в логин модуле не посылая запрос j_security_check? А>Все этапы аутентификации проходят успешно. Subject создается правильно. А getRemoteUser возвращает null. А>И на страницы защищенные <security-constraint/> меня не пускают
Твоя реализация JAAS и security контейнера кажется не связаны.
А>Вопрос 2: Как поместить subject в сессию так, что бы логин модуль понимал, что аутентификация уже выполнена. А>Хм... Сумбурно получилось, но если коротко: надо выполнить аутентификацию не посылая запроса j_security_check.
Если кратко — надо подружить аутентификацию контейнера и твою реализацию JAAS. Может я немного путаюсь в терминах, просто совершенно недавно обнаружил у себя пробел в знаниях в этой области. Заполняю.
А>Приложение работает под JBoss4.0, SAS7/SAS8.
Вот тут-то и начинается самое интересное. Вышеописаная задача она контейнеро-зависимая. Смотрел login-config.xml в JBoss? Там тебе и нужно прописать свои классы. Скорее всего свою реализацию LoginModule.
Re: JAAS. Как поместить remoteUser в сессию?
От:
Аноним
Дата:
07.06.06 14:00
Оценка:
Может ты не в курсе, что юзер из веб-контекста и юзер из ежб-контекста — это разные вещи?
Здравствуйте, Аноним, Вы писали:
А>Может ты не в курсе, что юзер из веб-контекста и юзер из ежб-контекста — это разные вещи?
По-моему при нормальной настройке контейнер должен предоставлять единообразную аутентикацию и single sign on для обоих типов J2EE приложений. И вообще причем здесь EJB?
Re[3]: JAAS. Как поместить remoteUser в сессию?
От:
Аноним
Дата:
07.06.06 14:05
Оценка:
Здравствуйте, Blazkowicz, Вы писали:
B>По-моему при нормальной настройке контейнер должен предоставлять единообразную аутентикацию и single sign on для обоих типов J2EE приложений. И вообще причем здесь EJB?
Здравствуйте, Аноним, Вы писали:
B>>По-моему при нормальной настройке контейнер должен предоставлять единообразную аутентикацию и single sign on для обоих типов J2EE приложений. И вообще причем здесь EJB?
А>Это кому это что он должен?)) А>Ткни-ка в спеку!
Another benefit is that the user's identity passes between the Web application and enterprise application components without any additional code. The container transfers the user's identity during calls from the Web application to other components such as EJBs.
Сейчас отправимся ковырять спеку в поисках истины.
Здравствуйте, Blazkowicz, Вы писали:
А>>Для этого я написал LoginModule который содержит всю логику аутентификации. А>>Сам по себе он работает. Если посылать запрос j_security_check?j_username=username&j_password=passwd то после успешной аутентификации в сессии появляется пользователь username, имя котрого я могу получить через req.getRemoteUser().
B>Вот этот момент не очень понятен. Для j_security_check (контейнероной аутентификации) LoginModule вроде как не нужен. Как ты их связал?
Если по порядку:
приложение А использует свой сервлет для обработки запросов и содержит свою внутреннюю аутентификацию и авторизацию.
При этом переделываются некоторые модули существующего проиложения с использованим JSF/Spring/Hibernate и вся аутуентификация переностися на уровень JAAS.
Логин модуль правильно зарегистрирован в login-config в JBoss.
И все работает, если использовать login.jsp с фромой, посылающей запрос j_security_check.
Но у меня уже есть в старом приложении форма для ввода пароля и я бы хотел провести дополнительную аутентификацию вручную. Да это и получается, но только в LoginContext-е, а мне надо, что бы пользователь с его ролями был зарегистирован в сессии.
B>Вот тут-то и начинается самое интересное. Вышеописаная задача она контейнеро-зависимая. Смотрел login-config.xml в JBoss? Там тебе и нужно прописать свои классы. Скорее всего свою реализацию LoginModule.
Здравствуйте, Аноним, Вы писали:
B>>По-моему при нормальной настройке контейнер должен предоставлять единообразную аутентикацию и single sign on для обоих типов J2EE приложений. И вообще причем здесь EJB?
А>Это кому это что он должен?)) А>Ткни-ка в спеку!
The JSP page performs the remote method call to the enterprise bean, using
the user’s credential to establish a secure association between the JSP page
and the enterprise bean (as shown in Figure J2EE.3-5). The association is
implemented as two related security contexts, one in the web server and one
in the EJB container.
The EJB container is responsible for enforcing access control on the
enterprise bean method. It consults the security policy (derived from the
deployment descriptor) associated with the enterprise bean to determine the
security roles that are permitted access to the method. For each role, the EJB
container uses the security context associated with the call to determine if it can
map the caller to the role.
Как-то все очень туманно. Даже выделеное болдом нельзя тарктовать однозначно.
Re[5]: JAAS. Как поместить remoteUser в сессию?
От:
Аноним
Дата:
07.06.06 15:02
Оценка:
Здравствуйте, Blazkowicz, Вы писали:
Не. Тут пишут про то, что можно с жсп-хи авторизоваться на доступ к методам ejb.
Речи о соответствии между ролями и правами определенными в web-приложении с ролями и правами определенными в в ejb-приложении нету.
Даже можешь и не искать нет такого дескриптора по спеке, в котором можно такое соответствие прописать.
Я думал, что это самом собой очевидно. У каждого свой контекст, свои обязанности и как их связывать — это уже кто-как захочет.
Здравствуйте, Аноним, Вы писали:
А>>Может ты не в курсе, что юзер из веб-контекста и юзер из ежб-контекста — это разные вещи? А>Я думал, что это самом собой очевидно. У каждого свой контекст, свои обязанности и как их связывать — это уже кто-как захочет.
Юзер это по твоему и контекст и роли? А по-моему юзер это Principal и не вижу каких-то очевидных препядствий тому чтобы контейнер передавал его из одного контекста в другой.
Здравствуйте, dkud, Вы писали:
D>Если по порядку:
D>приложение А использует свой сервлет для обработки запросов и содержит свою внутреннюю аутентификацию и авторизацию. D>При этом переделываются некоторые модули существующего проиложения с использованим JSF/Spring/Hibernate и вся аутуентификация переностися на уровень JAAS.
D>Логин модуль правильно зарегистрирован в login-config в JBoss. D>И все работает, если использовать login.jsp с фромой, посылающей запрос j_security_check.
D>Но у меня уже есть в старом приложении форма для ввода пароля и я бы хотел провести дополнительную аутентификацию вручную. Да это и получается, но только в LoginContext-е, а мне надо, что бы пользователь с его ролями был зарегистирован в сессии.
Теперь понятно. К сожалению я не гуру в этом вопросе. Но сдается мне что код получится очень JBoss/Tomcat специфичный. Именно Tomcat занимается тем что по j_security_check помещает Principal в сессию.
Я вот смотрю сейчас исходники 4го томката. Попробуй такой вариант: взять HttpSession в сервлете прикастить её к org.apache.catalina.Session и setPrincipal туда.
Re[7]: JAAS. Как поместить remoteUser в сессию?
От:
Аноним
Дата:
07.06.06 15:15
Оценка:
Забавно.
То есть, прописал я вот роль admin в web-inf и кто-то залогинелся под этой ролью, а контейнер "обязуется передать это" в ejb-метод.
А тут оказывается, что для вызова этого метода в дескрипторе ejb-приложения уже прописан какой-то Administrator. И что делать контейнеру??
Он должен "подумать" и как-то связать их что ли?? Это на основании чего? имени?
Согласен.
А>То есть, прописал я вот роль admin в web-inf и кто-то залогинелся под этой ролью, а контейнер "обязуется передать это" в ejb-метод. А>А тут оказывается, что для вызова этого метода в дескрипторе ejb-приложения уже прописан какой-то Administrator. И что делать контейнеру?? А>Он должен "подумать" и как-то связать их что ли?? Это на основании чего? имени?
А че бы и нет? Хотя как контейнер сможет перекинуть Principal из сессии в InitialContext мне не ясно. Скорее всего ты прав. А вышеуказанная статья ввела меня в заблуждение.
Здравствуйте, Blazkowicz, Вы писали:
B>Я вот смотрю сейчас исходники 4го томката. Попробуй такой вариант: взять HttpSession в сервлете прикастить её к org.apache.catalina.Session и setPrincipal туда.
Мысль интересная, но, во-первых, под JBoss-ом 4 сессия в request-е живет org.apache.catalina.session.StandardSessionFacade, а ему Princial не подсунешь , а, во-вторых, уж больно оно "tomcatозависимое" получилось бы.
А по-хорошему видимо его не заставить.
Получается, что использовать контейнерую идентификацию вместе с приложением не выйдет. А очень жаль...
Здравствуйте, Аноним, Вы писали:
А>То есть, прописал я вот роль admin в web-inf и кто-то залогинелся под этой ролью, а контейнер "обязуется передать это" в ejb-метод.
не путай роли и юзеров. зайти под именем JamesBond и получить привилегию Admin значит (с точностью до реализации — там имеют право быть вариации), что в LoginModule будет сформирован Subject с Principal("JamesBond"), среди publicCredentials которого будет Role("Admin").
что касается прозрачного распространения security-контекста — оно действительно требуется спецификациями. и касается всего субъекта, а не только принципала.
другое дело, что наличие public credential Role("Admin") может по-разному трактоваться механизмами авторизации web- и ejb-контейнеров
Здравствуйте, <Аноним>, Вы писали:
А>Есть рабочее J2EE приложение (А), которое использует внутреннюю аутентификацию и авторизацию не используя JAAS и также собственную библиотеку в качестве движка. Задача переписать это приложение так, что бы уйти от старого движка, но делать это по частям. Новое приложение (Б) должно использовать JAAS. Т.е. на переходном этапе приложение должно использовать одновременно и старый движок и новый (части А и Б).
А>Функционально логику работы приложения удалось разделить, остался вопрос аутентификации/авторизации.
А>Задача: при аутентификации пользователем в части А пройти аутентификацию и в части Б.
Вот отсюда вероятно и пошли все проблемы. Почему бы A и B не поментья местами и префразировать задачу так Задача: при аутентификации пользователем в части Б пройти аутентификацию и в части А.
Т.е. аутентифицируешь пользователя при помощи JAAS realm-а, слегка переделываю форму логина. Вешаешь филтр, который уже на основе принципала из getUserPrincipal делает аутентификацию в части A.
Здравствуйте, Lucker, Вы писали:
А>>Задача: при аутентификации пользователем в части А пройти аутентификацию и в части Б. L>Вот отсюда вероятно и пошли все проблемы. Почему бы A и B не поментья местами и префразировать задачу так L>Задача: при аутентификации пользователем в части Б пройти аутентификацию и в части А.
L>Т.е. аутентифицируешь пользователя при помощи JAAS realm-а, слегка переделываю форму логина. Вешаешь филтр, который уже на основе принципала из getUserPrincipal делает аутентификацию в части A.
К сожелению, этого сделать нельзя, потому что исходники движка старого прилоежния закрыты. А login screen реализован в недрах этой библиотеки. Есть только callback при login-е который я могу обработать.
Здравствуйте, dkud, Вы писали:
D>Мысль интересная, но, во-первых, под JBoss-ом 4 сессия в request-е живет org.apache.catalina.session.StandardSessionFacade, а ему Princial не подсунешь , а, во-вторых, уж больно оно "tomcatозависимое" получилось бы.
Грязный хак провалился. Что не может не радовать.
D>А по-хорошему видимо его не заставить. D>Получается, что использовать контейнерую идентификацию вместе с приложением не выйдет. А очень жаль...
L>Задача: при аутентификации пользователем в части Б пройти аутентификацию и в части А.
L>Т.е. аутентифицируешь пользователя при помощи JAAS realm-а, слегка переделываю форму логина. Вешаешь филтр, который уже на основе принципала из getUserPrincipal делает аутентификацию в части A.
Хотя предолжение очень дельное. Выбило меня из колеи на которой я уже начал зацикливаться. Спасибо, за свежую мысль.