Целью данной статьи является документирование того, как установить безопасную связь SSL между сервером GlassFish EJB и веб-сервером GlassFish, используя сертификаты хранилища ключей со GlassFish 3.0.1.
Начиная с Java Enterprise Edition 5 технология EJB кардинально изменилась. Опираясь на идеи, представленные Spring и другими средами, новые спецификации EJB создали новый простой в использовании стандарт. Приложения могут использовать преимущества корпоративного сервера вместо использования сторонних технологий. Контейнер EJB обеспечивает легкий доступ как к локальным, так и к удаленным компонентам Enterprise Java Beans (EJB). Клиенты, такие как сервлеты, могут использовать внедрение зависимостей для получения экземпляров этих EJB-компонентов без различий в коде с использованием локальных и удаленных компонентов.
Однако использование удаленного Enterprise Java Beans приводит к сетевому трафику между сервером Enterprise, на котором размещены EJB, и клиентским приложением, использующим EJB. С сетевым трафиком возникает вероятность проблем с безопасностью, поэтому цель состоит в том, чтобы обеспечить защиту EJB-связи с помощью SSL.
Эта статья будет шпаргалкой по конфигурации. Шпаргалка предоставит соответствующую информацию, но вы сможете интегрировать ее в свои проекты. Последующие части пройдут через создание и настройку реального рабочего примера.
Шпаргалка
EJB
Создайте интерфейс @Remote для вашего EJB
Интерфейс @Remote для вас EJB определяет методы, доступные удаленным клиентам, обращающимся к удаленному EJB
@Remote
public interface AccountService {
public Account findAccount(int id);
}
Создайте @Stateless реализацию интерфейса @Remote для вашего EJB
Реализация может быть @Stateful или @Stateless, но в этом примере создайте реализацию @Stateless удаленного интерфейса.
@Stateless
public class AccountServiceBean implements AccountService
{
@Override
@PermitAll
public Account findAccount(int id)
{
System.out.println(
String.format("ENTER findAccount(%d)",id)
);
Account account = new Account();
account.setAccountId(id);
return account;
}
}
Создайте файл sun-ejb-jar.xml, который настраивает использование SSL для вашего EJB
Файл sun-ejb-jar.xml — это специальный файл конфигурации GlassFish, отвечающий за настройку EJB. Обычно EJB компилируются в JAR, а затем JAR помещаются в EAR. Файл sun-ejb-jar.xml сохраняется в каталоге META-INF JAR.
Файл sun-ejb-jar.xml должен содержать конфигурацию <ejb> для каждого EJB, который нуждается в безопасном доступе для связи SSL.
За исключением значения <ejb-name>, все остальные значения должны оставаться неизменными. Это была комбинация значений, которые я нашел для правильной работы.
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//
DTD GlassFish Application Server 3.0 EJB 3.1//EN"
"http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_1-0.dtd">
<sun-ejb-jar>
<enterprise-beans>
<ejb>
<ejb-name>
AccountServiceBean
</ejb-name>
<ior-security-config>
<transport-config>
<integrity>
required
</integrity>
<confidentiality>
required
</confidentiality>
<establish-trust-in-target>
SUPPORTED
</establish-trust-in-target>
<establish-trust-in-client>
REQUIRED
</establish-trust-in-client>
</transport-config>
<sas-context>
<caller-propagation>
supported
</caller-propagation>
</sas-context>
</ior-security-config>
</ejb>
</enterprise-beans>
</sun-ejb-jar>
Создайте файл JAR для вашего EJB
Когда вы создаете файл JAR для вашего EJB, структура каталогов должна быть:
MyBeans.jar
/META-INF
sun-ejb-jar.xml
/com
/mycompany
*.class
WAR
Создайте сервлет для вашей войны
Создайте сервлет, который использует внедрение зависимостей для получения экземпляра EJB. Помните, что с точки зрения сервлета он будет иметь дело только с локальным именем поиска JNDI и интерфейсом @Remote для EJB. Помимо этого, сервлет не знает других подробностей.
Поиск @EJB — это локальное имя поиска JNDI. Это имя существует только в пространстве имен этой WAR. Файлы web.xml и sun-web.xml настраивают, как этот локальный поиск JNDI отображается на реальный экземпляр EJB. Мне нравится использовать локальные имена поиска, потому что, когда WAR настроен правильно и поиск успешен, я уверен, что код нашел правильную вещь. Альтернатива — это магия автоматического поиска, и незнание того, как ресурс найден и введен, не очень хорошая вещь.
@WebServlet(
name="AccountServlet"
, urlPatterns= {"/account"}
)
public class AccountServlet extends HttpServlet
{
// Remember, this is a
//
// !! LOCAL JNDI LOOKUP NAME !!
//
// and this lookup name is only
// used by this WAR. How this
// local lookup name maps to a
// real EJB instance is configured
// in web.xml and sun-web.xml
@EJB(lookup="java:comp/env/ejb/Sam")
AccountService accountService;
}
Создайте web.xml для вашей WAR
Файл web.xml должен содержать элемент <ejb-ref>. Этот элемент устанавливает 2 значения.
- Локальное имя поиска JNDI, которое использует ваш файл WAR при попытке найти EJB
- Полное имя интерфейса @Remote EJB.
Вам потребуется элемент <ejb-ref> для каждого локального поиска JNDI, который выполняет WAR.
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns=
"http://java.sun.com/xml/ns/javaee"
xmlns:web=
"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID"
version="2.5"
>
<ejb-ref>
<ejb-ref-name>
ejb/Sam
</ejb-ref-name>
<remote>
org.ferris.ejb.account.AccountService
</remote>
</ejb-ref>
</web-app>
Создайте sun-web.xml для вашей WAR
Файл sun-web.xml — это файл конфигурации GlassFish для вашей WAR. Используйте файл sun-web.xml для сопоставления локального поиска JNDI с WAR с реальным расположением EJB. Наличие кода WAR только о локальном поиске JNDI делает это сопоставление простым, а также позволяет легко изменять конфигурацию между различными средами (при необходимости).
Некоторые примечания о значении для <jndi-name> ниже:
- Он отображается на нескольких строках, но на самом деле все должно быть на одной строке!
- Не пропустите ни одного из символов «:», «/» или «!» персонажи
- [SERVER_NAME] — это имя сервера GlassFish, на котором развернуты EJB-компоненты @Remote.
- [EAR_NAME] — это имя приложения EAR, которое обычно является именем файла EAR. Предположим, вы развернули файл «MyBeans.ear» в GlassFish. По умолчанию GlassFish будет использовать «MyBeans» в качестве имени приложения EAR. Это значение может быть переопределено или изменено, но обычно это имя файла EAR.
- [JAR_NAME] — это имя файла JAR внутри файла EAR, в котором содержатся компоненты. Предположим, у вас есть файл «account.jar» внутри файла «MyBeans.ear», который содержит классы EJB для информации об учетной записи. По умолчанию GlassFish будет использовать «account» в качестве имени модуля. Это значение может быть переопределено или изменено, но обычно это имя файла JAR.
- [BEAN_NAME] — это, конечно, имя бина. Он должен совпадать с тем, что находится в конфигурационном файле sun-ejb-jar.xml, развернутом с bean-компонентами.
- [FULLY_QUALIFIED_REMOTE_INTERFACE] — это значение говорит само за себя. Это полностью квалифицированный интерфейс @Remote EJB.
<!DOCTYPE
sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD
GlassFish Application Server 3.0 Servlet 3.0//EN"
"http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd"
>
<sun-web-app>
<ejb-ref>
<!--
| local JNDI lookup name your code uses
-->
<ejb-ref-name>ejb/Sam</ejb-ref-name>
<!--
| The jndi-name value is the same
| for both secure and non-secure
| configuration. The sun-ejb-jar.xml
| file on the EJB server determines
| if the two GlassFish instances should
| establish a secure communications
-->
<jndi-name>
corbaname
:
iiop
:
[SERVER_NAME]
:
3700#java
:
global
/
[EAR_NAME]
/
[JAR_NAME]
/
[BEAN_NAME]
!
[FULLY_QUALIFIED_REMOTE_INTERFACE]
</jndi-name>
</ejb-ref>
</sun-web-app>
Обмен ключами от GlassFish Keystore
Безопасная связь EJB между двумя серверами GlassFish проще всего, когда серверы могут обмениваться сертификатами и автоматически доверять друг другу. Для этого сертификаты в хранилище ключей (keystore.jks) каждого сервера GlassFish необходимо экспортировать, а затем импортировать в хранилище доверенных сертификатов (cacerts.jks) другого сервера GlassFish.
Экспорт сертификата из keystore.jks
Команда для сервера GlassFish EJB
Выполните следующую команду на сервере GlassFish EJB, чтобы экспортировать сертификат сервера GlassFish EJB.
C:> cd C: \ glassfish \ 3.1 \ glassfish \ domains \ domain1 \ config
C:> keytool.exe -export -rfc -alias s1as -keystore keystore.jks -file GlassFishEJBServer.cer
Пароль по умолчанию для keystore.jks — » Команда changeit
для веб-сервера GlassFish
Выполните следующую команду на веб-сервере GlassFish, чтобы экспортировать сертификат веб-сервера GlassFish.
C:> cd C: \ glassfish \ 3.1 \ glassfish \ domains \ domain1 \ config
C:> keytool.exe -export -rfc -alias s1as -keystore keystore.jks -file GlassFishWEBServer.cer
Пароль по умолчанию для keystore.jks — » Измени это»
Обмен сертификатами
Предположим, вы экспортировали оба сертификата, а имена файлов — GlassFishEJBServer.cer и GlassFishWEBServer.cer. Скопируйте, sftp или используйте любой протокол передачи файлов, который вам нужен для обмена файлами между серверами.
Импортируйте сертификат в cacerts.jks
Команда для сервера GlassFish EJB
Выполните следующую команду на сервере GlassFish EJB, чтобы импортировать сертификат WEB-сервера GlassFish.
C:> cd C: \ glassfish \ 3.1 \ glassfish \ domains \ domain1 \ config
C:> keytool.exe -import -noprompt -trustcacerts -alias glassfishwebserver -file GlassFishWEBServer.cer -keystore cacerts.jks
Пароль по умолчанию для cacerts.jks is команда «changeit»
для веб-сервера GlassFish
Выполните следующую команду на веб-сервере GlassFish, чтобы импортировать сертификат сервера GlassFish EJB.
C:> cd C: \ glassfish \ 3.1 \ glassfish \ domains \ domain1 \ config
C:> keytool.exe -import -noprompt -trustcacerts -alias glassfishejbserver -file GlassFishEJBServer.cer -keystore cacerts.jks
Пароль по умолчанию для cacerts.jks — «changeit»
Вывод
Целью данной статьи является документирование того, как установить безопасную связь SSL между сервером GlassFish EJB и веб-сервером GlassFish, используя сертификаты хранилища ключей со GlassFish 3.0.1. Эта цель была достигнута путем сначала документирования конфигурации модуля EJB, затем документирования конфигурации модуля WEB, а затем, наконец, документирования того, как обмениваться сертификатами между двумя серверами. Хотя в этой статье не указаны подробности о том, как на самом деле реализовать эти шаги, они должны содержать достаточно информации для интеграции в специфические настройки вашего кода / приложения / сервера. Конечно, комментируйте или связывайтесь со мной по любым вопросам.