2012-01-04 93 views
1

我有一個使用mod_ssl來執行客戶端認證的SSL的Apache服務器。 Apache顯然設置了包含用戶證書等的環境變量(請參閱this mod_ssl doc),但我無法從System.getProperty()獲取它們。如何在Java中獲取Apache環境變量?

我已經在httpd-ssl.conf文件中設置了SSLOptions -StdEnvVars + ExportCertData(這是正確的地方?)無濟於事。

+0

你如何將Apache的請求傳遞給你的Java代碼/你的Java代碼是如何執行的?僅當您的Java代碼作爲CGI運行時,纔會傳遞環境變量,這聽起來不太可能。 – 2012-01-04 16:20:30

+0

它實際上是Apache上的ColdFusion,並且有一個調用我的Java代碼的cfm頁面。 – Mermeister 2012-01-04 16:28:49

回答

3

一位同事發現this web site,其中包含答案。實質上,這需要將環境變量設置爲特殊標題。兩個集合需要操作:一個初始化爲空白並避免僞造,另一個檢索並設置實際值。爲你想要的每一個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

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文檔似乎並不保證後者。)
+0

System.getenv確實會返回更多的Apache env vars,但不會返回我需要的SSL_ *變量。也許問題出在我如何或在哪裏使用SSLOptions指令? – Mermeister 2012-01-04 16:30:46

+0

@ user682604:我對你沒有明確的答案,但我已經更新了我的「答案」,並提供了一些想法。 – ruakh 2012-01-04 18:27:32