简体   繁体   中英

How to get Apache environment variables in Java?

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.

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

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 OK 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.)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM