2-сторонний SSL для веб-сервисов на GAE (java) - программирование
Подтвердить что ты не робот

2-сторонний SSL для веб-сервисов на GAE (java)

Нам нужно внедрить двухсторонний SSL в Google App Engine, где мы отправляем запросы веб-сервисов с использованием JAX-WS на сервер, поддерживающий двухстороннюю аутентификацию SSL.

Как мы можем настроить двухсторонний SSL для наших исходящих запросов веб-сервисов?

Мы знаем, что javax.net.ssl* запрещено в среде App Engine.

Вот пример нашего кода:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ListenerSoap {

    @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping")
    public void ping();
}

@WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL")
public class Listener extends Service
{
  public ListenerSoap getListenerSoap() {
   return super.getPort(new QName("http://example.com/Listener.Wsdl", 
                       "ListenerSoap"), ListenerSoap.class);
  }
}

И пример использования вышеприведенного кода:

ListenerSoap soap = new Listener().getListenerSoap();
soap.ping();

Я полагаю, что мы можем хранить хранилища ключей или любые сертификаты, необходимые в DataStore, в качестве двоичных объектов (хотя, как их загрузить, все еще lil 'расплывчато для меня).

Как мы можем настроить необходимые значения, необходимые для аутентификации этой веб-службы, используя двухсторонний SSL?

Спасибо за любую помощь

Update:

В ходе исследований я видел, как это можно сделать на традиционном сервере (один с доступом к файловой системе):

ListenerSoap soap = new Listener().getListenerSoap();
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12"

Однако в этом подходе ожидается, что client_cert.p12 будет находиться в файловой системе.

Кроме того, в GAE не допускаются SSLSocketFactory, SSLContext, KeyManager и KeyManagerFactory.

Update:

По версии GAE SDK 1.7.7. теперь это возможно:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections.

Примечания к выпуску GAE 1.7.7 SDK

4b9b3361

Ответ 1

Из моих ограниченных знаний о авторизации SSL кажется, что вам, возможно, не хватает чего-то жизненно важного здесь; сертификаты. Двухсторонний SSL требует, чтобы сертификаты клиента и сервера находились в хранилище ключей, которое может быть либо самозаверяющим сертификатом (файл pkcs12, либо pem, который вы можете легко создать с помощью нескольких команд через оболочку), либо проприетарный сертификат, выданный уполномоченной компанией, такой как Thawte или Verisign. Хотя я не уверен, что это проблема, с которой вы сталкиваетесь, но ее хорошо проверить. (Кроме того, я новичок, поэтому, пожалуйста, не уменьшайте мой ответ, просто пытаясь предложить возможные варианты.)

Ответ 2

ListenerSoap soap = new Listener().getListenerSoap();

Надеюсь, что это улучшится

Спасибо

Ответ 3

Я знаю, что вы, возможно, не захотите это услышать, но использование SSL дорого и проблематично для двусторонней коммуникации. В зависимости от того, сколько у вас контроля над сервером/клиентом, я предпочитаю простой двунаправленный канал, такой как веб-сокеты, и протокол пакетных данных, который может просто реализовать AES. Это действительно зависит от проблемы, которую вы пытаетесь решить.

Ответ 4

Похоже, существует путаница в отношении простого соединения через SSL (https://...) и так называемая "взаимная аутентификация" или "инфраструктура открытого ключа (PKI)". Фактически вы можете делать как одно, так и независимое от другого. С последним (что, на мой взгляд, относится к первому вопросу), когда вы отправляете запрос на сервер, сервер ответит вам, запрашивая сертификат, который вы должны представить для аутентификации.

Чтобы ответить на конкретный вопрос выше (загрузка хранилища ключей из двоичных данных), я не думаю, что это действительно возможно, так как это среда выполнения Java, которая захватывает ваше хранилище ключей. Единственное, что вы можете сделать, это загрузить бит из своего хранилища данных и временно записать его на диск. Необязательно удалять его, когда приложение существует. Это я сделал раньше и работает достаточно хорошо. Если вы сделаете это, я бы рекомендовал использовать место, которое может быть доступно для записи (например, System.getProperty("java.io.tmpdir"));), затем после записи файла на диск установите свойства JVM (например, System.getProperties().put( "javax.net.ssl.keyStore","...");)

Ответ 6

2-way SSL (из приложения, размещенного в GAE для внешнего мира), насколько мне известно, не поддерживается. Я попробовал пример приложения несколько месяцев назад и был расстроен, чтобы найти, что GAE даже не поддерживает эту основную функцию.. и документация также не ясна. Вы не сможете представить сертификат клиента при обращении к веб-сервису. Хранить его невозможно, к хранилищу ключей невозможно получить доступ.

Ответ 7

Для того, что я знаю о двухстороннем SSL, у вас не будет ссылки на код Java EE: два способа SSL - это безопасность транспортного уровня: когда клиентское приложение попытается создать защищенное HTTP-соединение (HTTPS) с помощью сервиса, сервер запросит сертификат и одобрит этот сертификат или нет. Если сертификат клиента одобрен, то на сторонах будет установлено защищенное соединение, и они позволяют обмениваться сообщениями через этот туннель. Но этот процесс выполняется на транспортном уровне. Ваш код (на уровне приложения) никогда не будет проинформирован об этом процессе. Чтобы установить два способа SSL, настройка выполняется на настройке сервера приложений для порта SSL.