通過Proxy向Weblogic集羣傳遞客戶端證書
過Weblogic集羣的人都知道可以使用Proxy來分發請求和實現負載均衡,這種配置方式既靈活又十分經濟,不需要額外購買昂貴的硬件負載均衡設置,十分適合中小企業採用。
在企業應用中,數據安全是非常重要的,爲了保證數據的安全性,最理想也最簡便的辦法就是使用SSL。通過使用CA證書,服務器和客戶機都能對對方的身份進行認證,在確信對方身份是可信任之後再進行業務操作,並且網絡上傳輸的數據也是加密的,這樣就能基本保證數據是安全的。一般情況下,SSL對服務器和客戶機雙方身份確認是由瀏覽器和WEB服務器來完成的,無需編程。但是,有時候應用系統也需要能取到客戶證書信息,比如需要在應用中對用戶證書中的用戶身份信息與用戶登錄應用系統的帳號進行比對,以進一步確認用戶身份。
對於多數的硬件負載均衡器,一般都支持透明的雙向SSL,即服務器和用戶證書都可以穿透負載均衡器到達對方,應用系統根本感覺不到負載均衡器的存在。但是,在使用Proxy實現的集羣中,應用系統中能否正常拿到客戶端證書信息呢?當然可以!
前兩天接到一個客戶的求援,說是他們的一個應用系統,因爲不知是什麼原因,硬件負載均衡器用不起來,只能用Proxy來實現負載均衡,現在需要啓用SSL,但是在服務器端卻取不到客戶證書信息。實話說,雖然我知道在Proxy的情況下,服務器肯定有辦法拿到客戶證書信息的,但以前也主要在有硬件負載均衡器的情況下配置集羣,還沒有專門去研究Proxy與SSL的問題,慚愧啊。既然今天遇上這事兒了,那就抽點時間演練一遍。說幹就幹,脫下外套,操傢伙上。
一、搭建環境:
搭這個環境軟件都是具備的,自己機器上裝有Weblogic8.1,只需要配置幾個以上Server來模擬集羣環境即可。我建了兩個domain,一個名爲proxydomain,在其上建了一個名爲proxyserver的Server,另一個domain名爲bizdomain,其上建了兩個Server bixserver1和bizserver2來充當集羣中的業務服務器。當然,業務服務器上佈署的應用可比HelloWorld複雜很多啊,呵呵(下面會詳細講啦)。
二、簽發CA證書
爲了使用SSL,CA證書是不可少的。爲了能得到一組互相信任的服務器證書和客戶證書,我沒有使用weblogic自帶的demo證書來配置SSL,而是用OpenSSL新簽發了一組證書,怎麼用OpenSSL來簽發證書超出本次課程範圍,想知道的同學可以另外交錢學習啊,呵呵。簽發的證書信息如下:
服務器證書
客戶證書
服務器證書可以弄一個keystore裝起來,再配置到weblogic上,我嫌麻煩,就直接把證書和私鑰拖到服務器上佈署了(大家別學我),而客戶證書和私鑰需要打包成pfx格式再安裝到操作系統中才可以。
三、配置proxy server
配置proxy server很簡單,只需要在proxydomain> Servers> proxy 頁的General 屬性頁中,把“ SSL Listen Port Enabled”和“Client Cert Proxy Enabled”勾選上,“SSL Listen Port”改成443(SSL默認端口)。然後再到“Keystores & SSL”屬性頁上,在“SSL Configuration”下面的分別設置:
Private Key File Name:=certs/server_key.pem
Server Certificate File Name:=certs/server.pem
Trusted CA File Name:=certs/root.cer
其中certs是CA證書保存目錄,物理路徑是 %weblogic安裝目錄%/user_projects/domains/proxydomain
在“Advanced Options-->Server Attributes”下面設置:
Two Way Client Cert Behavior:=Client Certs Requested And Enforced
含義就是強制要求客戶端有證書才能連接
然後再在proxydomain/applications目錄下新建一個proxy目錄(你叫其他名稱也可以,不會喫官司的),再在其下建一個目錄WEB-INF(必須是這個名,大寫),然後建兩個空的XML文件:web.xml和weblogic.xml,在web.xml裏填上:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
<display-name>weblogic代理測試</display-name>
<description>weblogic代理測試</description>
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>localhost:90|localhost:91</param-value>
</init-param>
<init-param>
<param-name>DebugConfigInfo</param-name>
<param-value>ON</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpClusterServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
在weblogic.xml裏填上:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>GBK</java-charset-name>
</input-charset>
</charset-params>
<context-root>/</context-root>
</weblogic-web-app>
再把proxydomain/applications/proxy作爲一個web應用佈署到proxyserver上,這樣,proxy服務器就配好了,啓動一下,如果看到控制檯有報錯,那麼你可以去買彩票了,小概率事件發生了。
四、配置bizserver
在bizdomain/applications目錄下新建一個目錄biz,裏面再建一個WEB-INF,然後照樣放兩個XML:web.xml和weblogic.xml。web.xml的內容是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
<display-name>weblogic代理測試_業務服務器</display-name>
<description>weblogic代理測試_業務服務器</description>
</web-app>
Weblogic.xml的內容是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "http://www.bea.com/servers/wls810/dtd/weblogic810-web-jar.dtd">
<weblogic-web-app>
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>GBK</java-charset-name>
</input-charset>
</charset-params>
<context-root>/</context-root>
</weblogic-web-app>
然後在bizdomain/applications/biz目錄下放一個非常複雜的JSP:
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.net.InetAddress" %>
<%@ page import="java.security.cert.*" %>
<%
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
%>
<%
String serverIP = InetAddress.getLocalHost().getHostAddress();
int serverPort = request.getServerPort();
String clientIP = request.getRemoteAddr();
try{
java.util.Enumeration enums = request.getHeaderNames();
java.util.ArrayList list = new java.util.ArrayList();
while(enums.hasMoreElements()) {
String name = (String)enums.nextElement();
out.print(name+":");
out.println(request.getHeader(name)+"<br>");
}
}catch(Exception ex) {
out.println(ex.getMessage());
ex.printStackTrace();
}
%>
<center>
當是客戶機IP是:<br>
<font color="red"><b><%=clientIP%></b></font>
<br><br>
當前連接的服務器是:<br>
<font color="red"><b><%=serverIP%>:<%=serverPort%></b></font>
<br><br>
</center>
<%
String certstr="";
X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
if(certs!=null) {
X509Certificate mycert=(X509Certificate)certs[0];
//out.println("Has Cert from Client!");
certstr=mycert.toString();
} else
out.println("could not get certificate from client!");
%>
Your Certificate(javax.servlet.request.X509Certificate) is Encode
As:
<br>
<%=certstr%>
</body>
接着再把biz作爲web應用程序佈署到bizserver1和bizserver2上。
五、配置Cluster
在bizdomain的console上,在 bizdomain> Clusters 頁點“Configure a new Cluster...”建一個集羣,其中:
General 下:
Name = MyCluster
Cluster Address:=localhost:90,localhost:91
Default Load Algorithm:=round-robin
然後在“Servers”頁把bizserver1和bizserver2選擇到MyCLuster。
這樣,集羣也配完了。把剛纔配置的這些機器都啓動起來。
六、測試
打開瀏覽器,輸入https://SHENG_NOTEBOOK/index.jsp,如果不出意外的話,應該會顯示以下內容:
可以看到,在mycluster中的服務器上已經得到了客戶證書。
如果連接服務器不成功的話,看看客戶證書有沒有安裝??
另外,用Apache作Proxy也是可以的,配置與本文相差不太大。