Концепция многоразовой сессии входа в систему в вызовах rmi ejb - PullRequest
3 голосов
/ 05 января 2012

Это не простой вопрос, просто потому, что я переосмысливаю нашу архитектуру для защиты нашей службы EJB 3.0 с помощью логина и безопасности.

У нас есть приложение EJB3.0 на JBoss 5.1, которое предлагает различные службыклиенту SWT для чтения и записи данных.Чтобы использовать службу, клиент должен войти в систему с действительным именем пользователя и паролем, которые ищет SpringSecurity на сервере LDAP.SpringSecurity генерирует идентификатор сеанса, который передается обратно клиенту для повторного использования при любом дальнейшем вызове службы.

client                            server
   |                                |
   |-> login(user/password)-------->|
   |                                |
   | <------- sessionId ------------| 
   |                                |
   |-->serviceXy(sessionId,param1)->|

Ситуация кажется ясной.Мы храним sessionId в нашем собственном объекте контекста, который является первым параметром каждого метода службы.В каждом методе службы есть перехватчик, который считывает идентификатор сеанса из данного объекта контекста и проверяет, является ли сеанс все еще действительным.Клиенту необходимо сначала вызвать службу входа в систему, чтобы получить объект контекста, заполненный sessionId, и повторно использовать этот объект контекста при последующих вызовах службы.

public class OurContext {
    private String sessionId;
}


@Stateless
@Interceptors(SecurityInterceptor.class)
public OurServiceImpl implements OurService {

    public void doSomething(OurContext context, String param1) {
        [...]
    }
}

В этом решении мне не нравится решение - решениекаждого метода службы с параметром контекста.Разве в вызовах rmi нет такого механизма, как сеанс http?Я думаю о том, чтобы поместить наш контекстный объект в какой-то сеанс, который создается в клиенте (?) Сразу после входа в систему и передается на сервер при каждом вызове службы, чтобы SecurityInterceptor мог читать sessionId из этого «магического контекста».".

Примерно так:

OurContext ctx = service.login("user","password");
Magical(Jboss)Session.put("securContext", ctx);
service.doSomething("just the string param");

Ответы [ 3 ]

2 голосов
/ 05 января 2012

Поскольку вы уже используете сервер приложений, похоже, вам следует использовать встроенные механизмы защиты EJB, обычно предоставляемые через JAAS. В строке 4.x jboss, если вы реализовали свой собственный плагин JAAS для jboss, вы можете получить доступ к «специальной» контекстной карте (аналогичной описанной вами), которая передается по удаленным запросам (с помощью инфраструктуры удаленного вызова jboss). ). Я не использовал jboss некоторое время, поэтому не уверен, как это соотносится с продуктом 5.1, но я должен представить, что он имеет аналогичные возможности. Это предполагает, конечно, что вы готовы реализовать что-то специфичное для jboss.

1 голос
/ 23 февраля 2012

В EJB есть несколько видов механизмов сеанса, но все они запускаются, когда начинается удаленный вызов, и заканчиваются, когда это заканчивается. На старом - это контекст транзакции (Адам Бин писал об этом некоторое время назад), а на более новом - Session Session Scope.

Вопреки распространенному мнению, эта область не только отражает область сеанса http, но в отсутствие сеанса http (как для удаленных вызовов) она представляет собой единую цепочку вызовов или доставку сообщений (для mdbs).

При таком сеансе ваш удаленный SWT-клиент по-прежнему должен передавать sessionId удаленной службе, но любые локальные bean-объекты, вызываемые оттуда, могут забрать его из этого сеанса "cdi".

Другой вариант подобен тому, что говорит jtahlborn: с вашим собственным модулем входа в систему вы можете вернуть пользовательский принципал вместо стандартного. Ваш код может сначала запросить обычного участника, а затем попытаться привести его.

Проблема в том, что этот материал зависит от контейнера, и JBoss всегда забывает об этом. Он почти всегда ломается после каждого обновления, и пользователям приходится биться и кричать, чтобы исправить это в какой-то следующей версии (только чтобы увидеть, как он снова ломается в версии после этого). Без поддержки JBoss это бесконечная битва.

Еще один вариант - позволить пользователю войти в систему с помощью sessionId в качестве имени. Модуль входа в систему может быть простым модулем, который принимает все и просто помещает принципала в контекст безопасности с sessionId как «имя». Это немного странно, но мы успешно использовали это для получения любых данных, которые могут быть выражены строкой в ​​контексте безопасности. Конечно, вы должны позволить своему клиенту проводить здесь обычную проверку подлинности контейнера, что, в первую очередь, обходится без использования Spring Security.

0 голосов
/ 24 февраля 2012

Мы пошли на другой подход, который является переносимым и не зависит от конкретного сервера приложений.Кроме того, наша реализация безопасности освобождает нас от ограничений подхода EJB (который, как я думал, был закрыт 2 десятилетия назад ... но возник снова).

Взгляд сверху вниз:

Существует сервер, предоставляющий классам методы для работы с одними и теми же данными.Клиент (ы) предоставляют данные и вызывают определенные методы.

Наш подход состоит в том, чтобы поместить все данные (и, следовательно, связь между клиентом и сервером) в «Бизнес-объект».Каждый BO расширяет суперкласс.Этот суперкласс содержит идентификатор сеанса.Метод login предоставляет и возвращает этот идентификатор.Каждый клиент должен только скопировать идентификатор, полученный в одном BO, в следующий, который он отправляет на сервер.Каждый метод, который может быть вызван удаленно (или локально), сначала получает объект сеанса с полученным идентификатором.Метод возврата объекта сеанса также проверяет ограничения безопасности (которые основаны на разрешениях, а не на ролях, как в подходе EKB).

...