【问题标题】:Client SSL authentication in Rails controllerRails 控制器中的客户端 SSL 身份验证
【发布时间】:2019-10-03 21:29:08
【问题描述】:

我正在运行一个 ruby​​ on rails 应用程序(rails 4.x),并且我有一个需要使用客户端证书进行身份验证的受保护资源。我需要强制客户端使用其证书进行身份验证。这甚至可以通过 Rails 控制器实现,还是在具有我的服务器证书的上层处理?

我能够从 rails 向另一台服务器发出请求并使用我的 rails 证书进行身份验证,但反过来似乎不可能。

这就是我从我的 rails 应用程序向另一台服务器进行身份验证的方式

# Example usage:
req = HttpsReq.new
response = req.http.request Net::HTTP::Get.new "/api/users"
require 'openssl'
require 'net/http'
require 'json'

class HttpsReq

  DEFAULT_OPTIONS = {
    use_ssl: true,
    verify_mode: OpenSSL::SSL::VERIFY_PEER,
    keep_alive_timeout: 30,
    ssl_version: :TLSv1_2,
    ca_file: File.join(File.dirname(__FILE__), "cacert.pem"),
    cert: OpenSSL::X509::Certificate.new(Base64.decode64(ENV['CLIENT_CERT_PEM'])),
    key: OpenSSL::PKey::RSA.new(Base64.decode64(ENV['CLIENT_KEY_PEM']), ENV['CLIENT_KEY_PASSWORD'])
  }

  def initialize(http = nil)
    if http
      @http = http
    else
      @http = Net::HTTP.start(ENV['SECURE_SERVER'], 8080, DEFAULT_OPTIONS)
    end
  end

end

【问题讨论】:

标签: ruby-on-rails ruby ssl ssl-client-authentication


【解决方案1】:

这有点可能,但你需要做一些技巧。因为只能在 TLS 握手过程中获取客户端证书。

我认为大多数 Rails Web 应用程序设计为在代理服务器或负载平衡器后面运行。而这种情况下的 TLS 握手过程在 Web 请求到达 Rails 控制器之前已经完成。

因此,您可以使用几个技巧。

  1. 使用 Ruby HTTP 客户端运行单独的端点,并提供所有必需的根证书和私钥。从 rails 控制器,您需要强制重定向到该 Ruby HTTP 客户端的端点,直到您的客户端(浏览器)成功通过客户端证书进行身份验证。
  2. 配置需要相互 TLS 身份验证的 NGINX,然后将来自 HTTP 请求的实际原始客户端证书传递给 Rails 控制器。 因此,通过这种方式,您需要为 Nginx 配置设置特殊 url 或特殊端口,并且您需要从 Rails 控制器强制重定向该端点。这个特殊的端点可以使用 HTTP 参数 (X-SSL-CERT $ssl_client_raw_cert) 代理您的实际 Rails 控制器。因此,您可以从那里读取实际的客户端证书并使用 Ruby OpenSSL 库对其进行验证。

如果您需要更多信息,please check this article

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-15
    • 2014-11-13
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多