Apache + Passenger + Rails 和客户端证书

Apache + Passenger + Rails and Client certificates

我正在尝试使用 X.509 证书对 API 用户进行身份验证,我几乎成功了。唯一的问题是如何从 Apache 获取证书信息(尤其是 PEM 证书数据)到 Rails.

这个 ENV 变量包含我需要的东西:

ENV['SSL_CLIENT_CERT']

但这似乎在生成 Passenger 进程后固定到 第一个请求,而不是为每个请求重置。

Passenger 作者对 this thread 的回答似乎证实了 ENV 变量被冻结并且不会为每个请求重置。

有什么方法可以从 Apache 获取正确的证书数据到 Rails?

我想我可以使用一些魔法来创建自定义 header,但这不太安全,因为恶意客户端也可以设置它。

在出现任何其他选项之前,我仍然选择 header 技巧:

确保 mod_headers 已加载,然后在您的虚拟主机配置文件中:

# Ensure that client can not pass certificate header
RequestHeader unset X-Api-Client-Cert
# Require client cert for API
<Location /api>
    SSLVerifyClient require
    SSLOptions +ExportCertData
    # Now export CertData via header
    RequestHeader set X-Api-Client-Cert "%{SSL_CLIENT_CERT}s"
</Location>

然后,在 Rails 代码中使用:

cert_data = request.headers['X-Api-Client-Cert']

使用什么作为 header 名称代替 X-Api-Client-Cert 并不重要。诚然 security through obscurity 不是真正的安全,但我选择使用自定义 header 名称只是为了尽量减少此 header 与真正的客户无意发送的任何内容发生冲突的可能性。