Я потратил много времени на это, но я наконец нашел пример, который действительно работает. Он основан на Glassfish и Netbeans, но я думаю, вы могли бы заставить его работать в других средах (например, Eclipse и Tomcat), если поигрались с ним.
http://java.sun.com/webservices/reference/tutorials/wsit/doc/WSIT_Security9.html#wp162511
Проблема, которую я обнаружил, заключается в том, что вы хотите использовать свои собственные сертификаты, а не те, которые поставляются с предустановленной стеклянной рыбой.
Примечание: я не эксперт по безопасности. Не развертывайте это в производственной среде!
Для этого я использую NetBeans 6.9, JDK 1.6, GlassFish 3.0.1 и OpenSSL v1.0 (я использую неофициальные бинарные файлы Win32)
# Create the CA
mkdir ca server client
cd ca
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.pem
echo 02 > serial.txt
cd ..
# Creating the Server Keystore
openssl req -days 3650 -newkey rsa:1024 -keyout server/server.key -out server/server.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in server/server.req -out server/server.crt
openssl pkcs12 -export -inkey server/server.key -in server/server.crt -out server/server.p12 -name server
keytool -importkeystore -destkeystore server/server.jks -deststoretype jks -srckeystore server/server.p12 -srcstoretype pkcs12
keytool -exportcert -alias server -keystore server/server.jks -file server/server.cer
# Create the Client Keystore
openssl req -days 3650 -newkey rsa:1024 -keyout client/client1.key -out client/client1.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in client/client1.req -out client/client1.crt
openssl pkcs12 -export -inkey client/client1.key -in client/client1.crt -out client/client1.p12 -name client1
keytool -importkeystore -destkeystore client/client1.jks -deststoretype jks -srckeystore client/client1.p12 -srcstoretype pkcs12
keytool -exportcert -alias client1 -keystore client/client1.jks -file client/client1.cer
# Import public keys and certificates into each others keystores
keytool -import -noprompt -trustcacerts -alias client1 -file client/client1.cer -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias server -file server/server.cer -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\cacerts.jks"
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\Java\jdk1.6\jre\lib\security\cacerts"
move "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks.backup"
copy server\server.jks "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks"
В консоли администратора GlassFish включите Security на своем http-слушателе, отметьте поля SSL3, TLS и Client Authentication, задайте для NickName сертификата сервер, хранилище ключей для config \ keystore.jks, хранилище доверенных сертификатов для config \ keystore.jks, алгоритм доверия для PKIX и оставьте максимальную длину сертификата на уровне 5.
В NetBeans создайте новый проект веб-приложения. В рамках этого создайте новый веб-сервис.
Код моего веб-сервиса выглядел так:
@WebService()
public class ListProducts {
@Resource WebServiceContext context;
@WebMethod(operationName = "listProducts")
public String listProducts() {
return context.getUserPrincipal().toString();
}
}
Щелкните правой кнопкой мыши веб-службу и выберите «Изменить атрибуты веб-службы». Установите флажок Безопасное обслуживание и выберите Безопасность взаимных сертификатов в качестве механизма безопасности. Нажмите кнопку «Настроить ...» и установите флажок «Зашифровать подпись». Теперь снимите флажок «Использовать параметры разработки по умолчанию» и нажмите кнопку «Keystore». Установите местоположение вашего хранилища ключей server.jks и выберите псевдоним server
. Сделайте то же самое для конфигурации хранилища доверенных сертификатов (хотя здесь вам не нужно выбирать псевдоним).
Импортируйте клиентский сертификат client1.p12 в ваш браузер. Разверните свой веб-сервис на Glassfish. Откройте веб-службу в браузере и перейдите к развернутому WSDL через HTTPS. Загрузите WSDL и любые другие схемы. Переименуйте любые ссылочные схемы в локальные копии, чтобы при использовании WSDL2Java NetBeans не использовал никакие удаленные ресурсы. (Этот абзац объясняется тем, что вы ограничивали свой WSDL для клиентов с утвержденным сертификатом, но NetBeans не может извлечь его удаленно, поскольку у него нет доступа к рассматриваемому сертификату).
Создать новый проект Java. Создайте новый клиент веб-службы. При появлении запроса укажите NetBeans на сохраненный файл WSDL. Импортируйте файлы библиотеки METRO2.0 (C:\Program Files\Netbeans 6.9\enterprise\modules\ext\metr\webservices-*.jar
). Мой код выглядел так:
public static void main(String[] args) {
System.getProperties().put("javax.net.ssl.keyStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
System.getProperties().put("javax.net.ssl.keyStorePassword", "changeit");
System.getProperties().put("javax.net.ssl.trustStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
System.getProperties().put("javax.net.ssl.trustStorePassword", "changeit");
System.out.println(new ListProductsService().getListProductsPort().listProducts());
}
Скопируйте файл webservices-api.jar в каталог Java \ jdk1.6 \ jre \ lib \ endorsed.
Щелкните правой кнопкой мыши ссылку на веб-службу и выберите «Изменить атрибуты веб-службы». Задайте местоположение хранилища ключей для client1.jks и установите псевдоним client1
. Задайте расположение хранилища доверенных сертификатов для client1.jks и установите псевдоним server
.
Надеюсь, теперь вы можете запустить свой клиент, и вы должны увидеть результат примерно так:
EMAILADDRESS=bob@anonymous.org, CN=Bob Smith, OU=Something, O=SomethingElse, L=AnyTown, ST=AnyState, C=US