0

force_ssl可以在 Rails 控制器上使用来请求 SSL。但是控制器有没有办法请求相互身份验证,如果是,控制器如何请求上下文,在 SSL/TLS 握手期间发现客户端提供的证书?

4

2 回答 2

1

您可以使用 request.cgi 访问您的客户端证书

certificate = request.cgi.env_table['SSL_CLIENT_CERT'].gsub(/(\n|-----(BEGIN|END) CERTIFICATE-----)/, '');

现在您可以根据此证书找到用户。

有关详细信息,请参阅http://www.scatmania.org/projects/ssl-client-certificate-authentication-in-ruby-on-rails/

我不确定这是否仅在您使用特定服务器(例如带有乘客的 apache)时才有效。

编辑:

http://www.modssl.org/docs/2.8/ssl_reference.html#ToC24也可能有用。

于 2013-09-04T12:15:59.463 回答
1

我知道这是一个老问题,但是,当您尝试了解如何使用 Rails 应用程序完成相互身份验证时,它是最热门的。我花了很多时间寻找好的文章和好的方法。所以,让我在这里分享我的发现。我希望它能帮助下一个试图找到相同答案的人。

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

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

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

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

如果您需要更多信息,请查看这篇文章。

于 2020-07-17T04:30:58.847 回答