Как вручную установить/распространить информацию о контексте безопасности, например. Принципал для JBoss 7 (через JBoss Remoting 2)

Я использую jboss remoting 2.5.4.SP3 для предоставления удаленного доступа к EJB на сервере JBoss 7.1 как из веб-приложения, так и из других экземпляров JBoss. Я делаю это вручную из-за проблем с удаленным доступом к EJB в JBoss 7.1, в частности (но не только) из-за невозможности доступа к одному и тому же (интерфейсному) компоненту на нескольких серверах одновременно. Я использую remoting2, потому что у remoting3 нет документации.

У меня есть удаленная работа с использованием TransporterHandle/TransporterClient с использованием транспорта сокетов, но в методах, вызываемых через это удаленное соединение, сервер хочет найти принципала из ejbContext. Я не могу найти способ вручную установить принципала или другую контекстную информацию о безопасности/идентификации. В пределе я был бы рад просто установить принципала при вызове метода ejb — все входящие вызовы относятся к локальным компонентам EJB3 — или даже установить его специально для EJBContext.

Я нашел много информации о Spring (которую я не использую), но, похоже, ничего не соответствует моему конкретному контексту.


person Antony Blakey    schedule 17.05.2012    source источник


Ответы (3)


А теперь правильный способ сделать это:

На стороне клиента я получаю контекст безопасности и упаковываю домен безопасности и информацию о субъекте для передачи на сервер вместе с вызовом. SecurityDomain представляет собой строку, а SubjectInfo сериализуем:

Map m = new HashMap();
SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
if (securityContext != null) {
    m.put("SUBJECT-INFO", securityContext.getSubjectInfo());
    m.put("SECURITY-DOMAIN", securityContext.getSecurityDomain());
}
response = remotingClient.invoke(request, m);

Карта m отправляется с вызовом через удаленное взаимодействие jboss. На стороне сервера я извлекаю информацию о безопасности и устанавливаю контекст для вызова следующим образом:

SecurityContext oldContext = SecurityContextAssociation.getSecurityContext();
SubjectInfo si = (SubjectInfo) invocation.getRequestPayload().get("SUBJECT-INFO");
String domain = (String) invocation.getRequestPayload().get("SECURITY-DOMAIN");
if (si != null) {
    SecurityContext sc = new JBossSecurityContext(domain);
    sc.setSubjectInfo(si);
    SecurityContextAssociation.setSecurityContext(sc);
}
try {
    return super.invoke(invocation);
} finally {
    SecurityContextAssociation.setSecurityContext(oldContext);
}

Работает как шарм!

person Antony Blakey    schedule 19.05.2012
comment
Спасибо за конкретное решение JBoss. У меня такая же потребность, которую я пытаюсь решить неконтейнерным способом: stackoverflow.com/questions/12213734/ - person Yves Martin; 04.09.2012

Взгляните на jboss-ejb-client.properties. Существует также пример quickstart с использованием удаленного клиента для поиска EJB.

person James R. Perkins    schedule 17.05.2012
comment
Я могу сделать все это. Что мне нужно знать, так это как получить доступ и установить контекст безопасности в JBoss 7.1, когда я не нахожусь в сервлете, EJB или другом компоненте EE. Допустим, пользователь сделал веб-запрос через сервлет и прошел аутентификацию. Затем я хочу получить участника, вошедшего в систему, но я не могу внедрить Session/EJBContext, потому что я нахожусь в обычном коде. Мне нужен принципал, чтобы я мог передать его через сокетное соединение. Затем, на другой стороне соединения сокета, мне нужно установить принципала, чтобы последующий EJBContext.getCurrentPrincipal и др. возвращал принципала, который пришел через сокет. - person Antony Blakey; 18.05.2012
comment
Извините за недоразумение. Я на самом деле не эксперт по безопасности, но я знаю из того ограниченного, что я сделал, AS 7 использует множество обработчиков обратных вызовов для работы с битами безопасности. Эта ссылка может помочь community.jboss.org/wiki/SecurityFAQ . - person James R. Perkins; 18.05.2012
comment
Да, в этом FAQ есть информация, которую я искал, но не смог найти. Спасибо. - person Antony Blakey; 19.05.2012

Я решил свою основную проблему, хотя и не так, как я надеялся.

Я поставил фильтр сервлета на все входящие запросы, записывая request.getUserPrincipal в локальный поток. Затем я могу получить доступ к этому в коде, отличном от EE, и найти принципала, делающего запрос. Затем, когда я звоню своему серверу приложений, я использую возможность JBoss Remoting прикреплять метаданные к каждому вызову, чтобы передать Принципала по сети. Мне пришлось скопировать TransporterClient, чтобы сделать это, потому что его частные конструкторы и другие не позволяют переопределять функциональные возможности, необходимые для присоединения метаданных для каждого запроса (в отличие от каждого соединения). На стороне сервера я беру входящего участника и устанавливаю его в локальный поток. Затем в последующем коде, который обращается к EJBContext.getCallerPrincipal, я также ищу входящего участника из локального потока, и если он не равен нулю (следовательно, мы находимся в удаленном вызове EJB), я использую его, если вызывающий участник является анонимным. Если он не анонимный, то он должен быть каким-то образом установлен после входящего вызова, поэтому в этом случае я игнорирую входящего Принципала.

В целом, это гораздо более специализированное решение, чем я надеялся, и оно не проливает света на то, как я могу выполнять общее распространение контекста в JBoss 7.1 по сети.

person Antony Blakey    schedule 18.05.2012