Библиотека HTTP для Ruby с поддержкой HTTPS, сертификата клиента SSL и поддержки Keep-Alive?

Я пытаюсь написать HTTPS-клиент на Ruby. Он будет подключаться к серверу с использованием HTTPS, передавая токен аутентификации (полученный через отдельный процесс входа в систему) и сертификат клиента SSL.

Я делаю следующее с rest-client:

client = RestClient::Resource.new(url,
                         :ssl_client_cert  =>  OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
                         :ssl_client_key   =>  OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), ''),
                         :verify_ssl       =>  OpenSSL::SSL::VERIFY_NONE)

# ...

headers = {
  'X-Application' => APP_KEY,
  'X-Authentication' => @session_token,
  'content-type' => 'application/json',
  'Accept' => 'application/json'
}

response = client.post(request, headers)

Это работает, но я хотел бы использовать keep-alive, чтобы не проходить весь процесс установления соединения каждый раз, когда я хочу сделать запрос. Связанная с этим задержка делает приложение для мониторинга, которое я пишу, гораздо менее полезным.

Однако я не могу найти библиотеку Ruby, которая предлагает следующее:

  • поддержка HTTPS
  • Поддержка SSL-сертификата клиента
  • Keep-Alive

Существует запрос на вытягивание для rest-client, который должен его предоставить. https://github.com/jnunemaker/httparty имеет https://github.com/soupmatt/persistent_httparty, но если он поддерживает клиентские сертификаты SSL, для него нет документации.

Я мог бы раскошелиться на rest-client, слить запрос на включение, который к настоящему времени немного сгнил, и использовать его. Но, конечно же, я что-то здесь упускаю... существует ли существующая библиотека, которая предлагает то, что я ищу? Или какая-нибудь документация для httparty, в которой объясняется использование SSL-сертификата клиента с этой библиотекой?

Будем очень благодарны любой помощи.


person Duncan Bayne    schedule 19.09.2013    source источник
comment
OpenSSL::SSL::VERIFY_NONE обычно плохая идея. Если рабочий процесс включает минимальные стандартные проверки, вы можете обнаружить, что он не работает.   -  person jww    schedule 19.11.2016


Ответы (3)


Есть что-то, что уже работает?

Я считаю, что клиентская библиотека HTTP Faraday в настоящее время находится в центре внимания сообщества Ruby.

Он поставляется с :net_http_persistent адаптером, который поддерживает клиентские сертификаты SSL. Вероятно, вы можете сделать что-то вроде этого:

ssl_options = {
  cert: OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),
  key:  OpenSSL::PKey::RSA.new(File.read('./certificate/client-2048.key'), 'mypassword')
}
conn = Faraday.new(url: 'https://example.com', ssl: ssl_options) do |faraday|
  faraday.adapter = Faraday::Adapter::NetHttpPersistent
end

conn.get '/my-resource'

HTTPвечеринка

По спецификациям:

... результирующее соединение при предоставлении сертификатов PEM, когда схема https

  • использует предоставленный сертификат PEM
  • будет проверять сертификат

Для предоставления клиентский сертификат в формате PEM.

REST-клиент

Все не так уж и мертво — Ларри Гилберт (@L2G) все еще объединяет запросы на вытягивание и сохраняет свет на. Он кивнул, выражая общее одобрение в системе отслеживания проблем. Я подозреваю, что на данный момент это просто не на вершине его очереди приоритетов.

У парня, отправившего этот запрос на вытягивание, @byroot есть поддерживал его код в актуальном состоянии, так что вам вообще не нужно ничего делать, пока вы ждать.

person RJHunter    schedule 19.09.2013
comment
Я выбрал подход клиента REST — даже быстрее и проще, чем слияние запроса на вытягивание. Я разветвил репозиторий, содержащий его, и просто установил его со следующим в моем Gemfile: gem 'rest-client', :github => 'duncan-bayne/rest-client', :branch => 'feature-keep-alive'. Тем не менее, я исследую порт Фарадея, так как это, похоже, путь в будущее. - person Duncan Bayne; 23.09.2013
comment
И под «я расследую» я имею в виду два года спустя, в 2015 году. Но эй, лучше поздно, чем никогда… :) - person Duncan Bayne; 16.03.2015

Net::HTTP API стандартной библиотеки Ruby удовлетворяет перечисленным вами требованиям: поддержка HTTPS, поддержка сертификата клиента SSL и Keep-Alive.

Поскольку Net::HTTP можно создавать и повторно использовать без блочной семантики, его также легко обернуть в вашу собственную библиотеку.

#!/usr/bin/env ruby
#
# https://gist.github.com/sheldonh/4693e2eca35b62b22c55

require 'openssl'
require 'net/http'
require 'json'

class Gist

  DEFAULT_OPTIONS = {
    use_ssl: true,
    verify_mode: OpenSSL::SSL::VERIFY_PEER,
    keep_alive_timeout: 30,
    cert: OpenSSL::X509::Certificate.new(File.read('./client.cert.pem')),
    key: OpenSSL::PKey::RSA.new(File.read('./client.key.pem'))
  }


  def initialize(http = nil)
    if http
      @http = http
    else
      @http = Net::HTTP.start("api.github.com", 443, DEFAULT_OPTIONS)
    end
  end

  def fetch(id, file)
    response = @http.request Net::HTTP::Get.new "/gists/#{id}"
    JSON.parse(response.body)["files"][file]["content"]
  end

end


gist = Gist.new
puts gist.fetch "fc5b5c42ff2e22171f09", "gistfile1.txt"  # Lorem ipsum
puts gist.fetch "4693e2eca35b62b22c55", "gist.rb" # This script
person sheldonh    schedule 11.03.2016

Пробовали ли вы механизировать?

Согласно примерам вы можете пройти сертификацию клиента следующим образом:

require 'rubygems'
require 'mechanize'

# create Mechanize instance
agent = Mechanize.new

# set the path of the certificate file
agent.cert = 'example.cer'

# set the path of the private key file
agent.key = 'example.key'

# get the login form & fill it out with the username/password
login_form = agent.get("http://example.com/login_page").form('Login')
login_form.Userid = 'TestUser'
login_form.Password = 'TestPassword'

# submit login form
agent.submit(login_form, login_form.buttons.first)

Согласно этой теме, вам может потребоваться заставить механизировать использовать SSLV3:

page = Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE}.get "https://yourHTTPSurl"
person Paulo Fidalgo    schedule 19.09.2013
comment
OpenSSL::SSL::VERIFY_NONE обычно плохая идея. Мне непонятно, почему конфиденциальная информация, такая как пароль, передается любому серверу, который отвечает (вместо ожидаемого). - person jww; 19.11.2016