Java中如何获取Apache环境变量?

发布于 2024-12-24 23:45:44 字数 192 浏览 1 评论 0原文

我有一个 Apache 服务器,使用 mod_ssl 进行客户端身份验证的 SSL。 Apache 显然设置了包含用户证书等,但我无法从 System.getProperty() 获取它们。

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

I have an Apache server using mod_ssl to do client-authenticated SSL. Apache apparently sets environment variables (see this mod_ssl doc) that contain the user's certificate, etc, but I can't get them from System.getProperty().

I've set SSLOptions -StdEnvVars +ExportCertData in the httpd-ssl.conf file (is that the right place?) to no avail.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伴梦长久 2024-12-31 23:45:44

一位同事发现了此网站,其中包含答案。本质上,这需要将环境变量设置为特殊标头。需要两个设置操作:一个用于初始化为空白并避免伪造,第二个用于检索并设置实际值。对您想要的每个 SSL 环境变量 执行此操作。

   # 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);

A coworker discovered this web site, which contains the answer. Essentially, this requires the environment variables to be set as special headers. Two set operations are needed: one to initialize to blank and avoid forgery, and a second to retrieve and set the actual value. Do this for each of the SSL environment variables that you want.

   # 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"

This made the value available to our ColdFusion page. In our case, this had to be converted to a Java string before being passed into the Java part of the application.

   clientpem = javacast("string", GetHttpRequestData().Headers.SSL_CLIENT_CERT);
兔姬 2024-12-31 23:45:44

System.getProperty(...) 获取系统属性,它与环境变量不同。对于环境变量,请使用 System.getenv(...)。如 中所述该方法的 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((System.getenv().keySet()).toString() 将是一个 String,其中包含您正在获取的所有环境变量的(长)列表可能值得检查它,只是为了看看键是否由于某种原因与您期望的有所不同(The. ArrayList 部分可能是不必要的— 在我的系统上,System.getenv().keySet().toString() 有效 — 但 JDK 文档似乎并不能保证后者。)

System.getProperty(...) gets a system property, which is not the same as an environment variable. For environment variables, use System.getenv(...). As explained in that method's Javadoc:

System properties and environment variables are both conceptually mappings between names and values. Both mechanisms can be used to pass user-defined information to a Java process. Environment variables have a more global effect, because they are visible to all descendants of the process which defines them, not just the immediate Java subprocess. They can have subtly different semantics, such as case insensitivity, on different operating systems. For these reasons, environment variables are more likely to have unintended side effects. It is best to use system properties where possible. Environment variables should be used when a global effect is desired, or when an external system interface requires an environment variable (such as PATH).


Update in response to OP comment below: I really don't know the answer, but I'll list some things you can try to help narrow down the problem (some of which you may already have tried):

  • Remember to restart Apache after any change to the main configuration files, since it processes them on start-up. (I'm betting you already know this, but it seems worth mentioning, just in case.)
  • The documentation for ExportCertData speaks of "additional CGI/SSI environment variables" (as opposed to "the standard set" controlled by StdEnvVars). The documentation doesn't explicitly say that ExportCertData is completely independent of StdEnvVars; it wouldn't shock me if you can't get those additional variables without first getting the standard set. So, it may be worth trying SSLOptions +StdEnvVars +ExportCertData. (Even if that doesn't fix the problem on the first try, I'd suggest sticking with +StdEnvVars until you have a solution that does work, and only then switching to -StdEnvVars, since you can then make sure that it's O.K. to do so.)
  • SSLOptions is documented to work in an .htaccess, so you might want to try putting it there (since that bypasses the question of httpd-ssl.conf vs. httpd.conf and whatnot).
  • The documentation says that this configuration is "to provide several items of SSL information as additional environment variables to the SSI and CGI namespace" (emphasis mine). I'm not sure what that means in the context of ColdFusion-invoked Java; it may be worth creating a real CGI script in the same directory and confirming that it doesn't receive these variables, either.
  • I don't know much about ColdFusion. Is it possible that it's somehow recognizing these environment variables as sensitive, so not passing them to the Java program? (Or is it possible that it has a limit on the length of an environment variable that it will pass to an external program?) It may be worth adding code in the cfm page to check for these variables, just to see if there's a difference.
  • Inside your Java code, new java.util.ArrayList<String>((System.getenv().keySet()).toString() will be a String containing a (long) list of all environment variables that you are getting. It may be worth examining it, just to see if maybe the keys look a bit different for some reason from what you'd expect. (The ArrayList part is probably unnecessary — on my system just System.getenv().keySet().toString() works — but the JDK documentation doesn't seem to guarantee the latter.)
看透却不说透 2024-12-31 23:45:44

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

Use System.getenv(String), not System.getProperty(String), to retrieve environment vars.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文