【问题标题】:How to get Apache environment variables in Java?如何在 Java 中获取 Apache 环境变量?
【发布时间】:2012-02-02 12:16:20
【问题描述】:

我有一个使用 mod_ssl 的 Apache 服务器来执行客户端身份验证 SSL。 Apache 显然设置了包含用户证书等的环境变量(参见this mod_ssl doc),但我无法从 System.getProperty() 中获取它们。

我在 httpd-ssl.conf 文件中设置了 SSLOptions -StdEnvVars +ExportCertData(这是正确的地方吗?)无济于事。

【问题讨论】:

  • 您如何将请求从 Apache 传递到您的 Java 代码/您的 Java 代码是如何执行的?只有当您的 Java 代码作为 CGI 运行时,环境变量才会被传递,这听起来不太可能。
  • 它实际上是 Apache 上的 ColdFusion,并且有一个 cfm 页面可以调用我的 Java 代码。

标签: java apache coldfusion environment-variables


【解决方案1】:

一位同事发现了this web site,其中包含答案。本质上,这需要将环境变量设置为特殊标头。需要两个 set 操作:一个是初始化为空白以避免伪造,另一个是检索和设置实际值。对您想要的每个SSL environment variables 执行此操作。

   # initialize to a blank value to avoid http header forgeries
   RequestHeader set SSL_CLIENT_CERT    ""

   # set the actual value
   RequestHeader set SSL_CLIENT_CERT    "%{SSL_CLIENT_CERT}s"

这使得我们的 ColdFusion 页面可以使用该值。在我们的例子中,必须先将其转换为 Java 字符串,然后才能传递到应用程序的 Java 部分。

   clientpem = javacast("string", GetHttpRequestData().Headers.SSL_CLIENT_CERT);

【讨论】:

  • 为什么需要2套?第二组不会从客户端抽任何标头吗?
【解决方案2】:

System.getProperty(...) 获取系统属性,与环境变量不同。对于环境变量,请使用System.getenv(...)。如that method's Javadoc 中所述:

系统属性环境变量在概念上都是名称和值之间的映射。这两种机制都可用于将用户定义的信息传递给 Java 进程。环境变量具有更全局的影响,因为它们对定义它们的进程的所有后代可见,而不仅仅是直接的 Java 子进程。在不同的操作系统上,它们可能具有细微的不同语义,例如不区分大小写。由于这些原因,环境变量更有可能产生意想不到的副作用。最好尽可能使用系统属性。当需要全局效果或外部系统接口需要环境变量时(如PATH),应使用环境变量。


更新以回应下面的 OP 评论:我真的不知道答案,但我会列出一些你可以尝试帮助缩小问题范围的事情(其中一些你可能已经试过了):

  • 请记住在对主要配置文件进行任何更改后重新启动 Apache,因为它会在启动时处理它们。 (我打赌你已经知道了,但似乎值得一提,以防万一。)
  • ExportCertData 的文档提到“附加 CGI/SSI 环境变量”(与 StdEnvVars 控制的“标准集”相对)。文档没有明确说明ExportCertData 完全独立于StdEnvVars;如果您在没有首先获得标准集的情况下无法获得这些附加变量,我不会感到震惊。所以,SSLOptions +StdEnvVars +ExportCertData 可能值得一试。 (即使第一次尝试并不能解决问题,我建议您坚持使用+StdEnvVars,直到您找到确实有效的解决方案,并且只有然后切换到-StdEnvVars,因为您可以确保这样做是可以的。)
  • SSLOptions 被记录在 .htaccess 中工作,所以你可能想尝试把它放在那里(因为这绕过了 httpd-ssl.confhttpd.conf 之类的问题)。
  • 文档说此配置是“提供几项 SSL 信息作为附加环境变量到 SSI 和 CGI​​ 命名空间”(强调我的)。我不确定这在 ColdFusion 调用 Java 的上下文中意味着什么。在同一目录中创建一个真正的 CGI 脚本并确认它也没有接收到这些变量可能是值得的。
  • 我对 ColdFusion 了解不多。是否有可能以某种方式将这些环境变量识别为敏感变量,因此不将它们传递给 Java 程序? (或者它可能对传递给外部程序的环境变量的长度有限制?)可能值得在cfm页面中添加代码来检查这些变量,看看是否有区别.
  • 在您的 Java 代码中,new java.util.ArrayList<String>((System.getenv().keySet()).toString() 将是一个 String,其中包含您正在获得的所有环境变量的(长)列表。可能值得对其进行检查,只是看看键是否由于某种原因与您的预期有些不同。 (ArrayList 部分可能是不必要的——在我的系统上只有 System.getenv().keySet().toString() 有效——但 JDK 文档似乎不能保证后者。)

【讨论】:

  • System.getenv 确实返回了更多的 Apache 环境变量,但没有返回我需要的 SSL_* 变量。也许问题在于我如何或在何处使用 SSLOptions 指令?
  • @user682604:我没有给你一个明确的答案,但我已经更新了我的“答案”,提出了一些可以尝试的想法。
【解决方案3】:

使用System.getenv(String),而不是System.getProperty(String),检索环境变量。

【讨论】:

    猜你喜欢
    • 2013-12-04
    • 1970-01-01
    • 2013-08-10
    • 2017-04-14
    • 2012-05-14
    • 2012-11-05
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    相关资源
    最近更新 更多