Как получить сертификат клиента из запроса отдыха в Java - PullRequest
0 голосов
/ 27 февраля 2019

Я использую Jersey для REST сервера в Java и Jetty в качестве веб-сервера.У меня есть self signed сертификаты.Я хочу получить данные сертификата клиента из полученного HTTP-запроса.Как получить информацию от HttpServletRequest?

Один метод:

X509Certificate certs[] = (X509Certificate[])httpRequest.getAttribute("javax.servlet.request.X509Certificate");

Это правильно?Это приводит к исключению,

Error [Ljava.lang.Object; cannot be cast to [Ljava.security.cert.X509Certificate 

Должен ли я включить какие-либо дополнительные JAR?Или есть какой-нибудь способ получить детали сертификата клиента?

Я тоже сталкивался,

httpRequest.getHeader("ssl_client_cert");

Мне кажется, что оба способа не работают.Как узнать подробности?

1 Ответ

0 голосов
/ 01 марта 2019

Во-первых, убедитесь, что ваш ServerConnector, который обрабатывает SSL / TLS.Далее, у этого ServerConnector должен быть SslConnectionFactory с настроенным объектом HttpConfiguration.К этому объекту HttpConfiguration должен быть добавлен SecureRequestCustomizer.

На языке встроенной пристани это выглядит так ...

        // SSL Context Factory
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath("/path/to/keystore");
        sslContextFactory.setKeyStorePassword("password");
        sslContextFactory.setKeyManagerPassword("secret");
        sslContextFactory.setTrustStorePath("/path/to/keystore");
        sslContextFactory.setTrustStorePassword("password");


        // SSL HTTP Configuration
        HttpConfiguration https_config = new HttpConfiguration(http_config);
        https_config.addCustomizer(new SecureRequestCustomizer()); // <-- THIS LINE

        // SSL Connector
        ServerConnector sslConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
            new HttpConnectionFactory(https_config));
        sslConnector.setPort(8443);
        server.addConnector(sslConnector);

Если вы используете ${jetty.home} и ${jetty.base} разделите на автономную Jetty, тогда вы захотите убедиться, что jetty-ssl.xml присутствует в вашей конфигурации ...

$ cd /path/to/my-jetty-base
$ java -jar /path/to/jetty-home/start.jar --list-config

Java Environment:
-----------------
 java.home = /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/jre (null)
 java.vm.vendor = Oracle Corporation (null)
 java.vm.version = 25.202-b08 (null)
 java.vm.name = Java HotSpot(TM) 64-Bit Server VM (null)
 java.vm.info = mixed mode (null)
 java.runtime.name = Java(TM) SE Runtime Environment (null)
 java.runtime.version = 1.8.0_202-b08 (null)
 java.io.tmpdir = /var/folders/w5/mmnzpk0n369dntp4nszlc8h40000gn/T/ (null)
 user.dir = /path/to/my-jetty-base (null)
 user.language = en (null)
 user.country = US (null)

Jetty Environment:
-----------------
 jetty.version = 9.4.15.v20190215
 jetty.tag.version = master
 jetty.home = /path/to/jetty-home
 jetty.base = /path/to/my-jetty-base

...(snip lots of output)...

Jetty Active XMLs:
------------------
 ${jetty.home}/etc/jetty-threadpool.xml
 ${jetty.home}/etc/jetty.xml
 ${jetty.home}/etc/jetty-webapp.xml
 ${jetty.home}/etc/jetty-plus.xml
 ${jetty.home}/etc/jetty-annotations.xml
 ${jetty.home}/etc/jetty-deploy.xml
 ${jetty.home}/etc/jetty-http.xml
 ${jetty.home}/etc/jetty-ssl.xml      <-- THIS LINE
 ${jetty.home}/etc/jetty-ssl-context.xml
 ${jetty.home}/etc/jetty-https.xml
 ${jetty.home}/etc/jetty-jaas.xml
 ${jetty.home}/etc/jetty-rewrite.xml
 ${jetty.base}/etc/demo-rewrite-rules.xml
 ${jetty.base}/etc/test-realm.xml

После того, как вы проверили эту конфигурацию базового уровня, вы можете использовать дажеиспользуя эти атрибуты.

Далее, когда вы делаете запрос к этому защищенному соединителю, различные фильтры и сервлеты будут иметь доступ к ряду атрибутов запроса, которые могут оказаться полезными для вас.

Этиэто определенные спецификацией Servlet атрибуты, которые SecureRequestCustomizer добавляет к входящему HttpServletRequest.

  • javax.servlet.request.X509Certificate содержит массив объектов java.security.cert.X509Certificate.
  • javax.servlet.request.cipher_suite содержит ваш согласованный шифрsuite как объект String.
  • javax.servlet.request.key_size содержит размер ключа как объект Integer.
  • javax.servlet.request.ssl_session_id содержит идентификатор сеанса SSL как объект String.

Это пользовательские атрибуты Jetty, которые SecureRequestCustomizer добавляет к входящим HttpServletRequests.

  • org.eclipse.jetty.servlet.request.ssl_session содержит активный объект java.net.ssl.SSLSession для этого соединения.

Так как вы видите общий Object[] из вашей попытки использовать атрибут, возможно, вам следует отладить и посмотреть, что эти объекты на самом деле.

Учтите, что что-то вне контроля Jetty могло бы заменить их или сделатьони недоступны для Jetty в форме спецификации сервлета до того, как вы попытались получить к ним доступ.

  • Известно, что несколько сторонних библиотек безопасности изменяли эти атрибуты в прошлом.
  • Или выне завершают соединение TLS / SSL на Jetty, например на брандмауэре / маршрутизаторе / балансировщике нагрузки (haproxy, nginx, apache httpd или различное оборудование) (что означает, что Jetty не может видеть сертификат).
  • Выне используется обычный ServerConnector (например, UnixSocketConnector, LocalConnector или пользовательский Connector)
  • Или у вас есть 3rd сторона безопасности в вашей реализации Java.
Object certs[] = httpRequest.getAttribute("javax.servlet.request.X509Certificate");
for(Object cert: certs) {
  System.out.printf("DEBUG: Cert[%s] = %s%n", cert.getClass().getName(), cert);
}
...