這些部分引用了可從 BEA 的 dev2dev 網(wǎng)站聯(lián)機(jī)獲得的示例代碼,WebLogic Server 分發(fā)的以下位置也包括了這些示例代碼:
SAMPLES_HOME\server\examples\src\examples\security\sslclient
sslclient
目錄包含 instructions.html
文件、ant
生成文件以及下列 Java 和 JavaServer 頁(yè) (.jsp
) 文件:
Java 安全套接口擴(kuò)展(Java Secure Socket Extension,簡(jiǎn)稱 JSSE)是一組支持和實(shí)現(xiàn) SSL 和 TLS v1 協(xié)議的包,可使得這些功能能夠通過(guò)編程方式使用。BEA WebLogic Server 支持使用安全套接口層(Secure Sockets Layer,簡(jiǎn)稱 SSL)加密 WebLogic Server 客戶端和服務(wù)器、Java 客戶端、Web 瀏覽器以及其他服務(wù)器之間傳輸?shù)臄?shù)據(jù)。
WebLogic Server 的 JSSE 實(shí)現(xiàn)可由 WebLogic 客戶端使用,但并不是必需的。其他 JSSE 實(shí)現(xiàn)也可用于它們?cè)诜?wù)器之外的客戶端代碼。
在 WebLogic 服務(wù)器端應(yīng)用程序使用 SSL 時(shí),適用下列限制:
其他提供程序可能與 WebLogic Server 一起使用,但未測(cè)試的提供程序不大可能即時(shí)工作。有關(guān)使用 WebLogic Server 支持的 JCE 提供程序的詳細(xì)信息,請(qǐng)參閱“確保 WebLogic Server 安全”中的配置 SSL。
WebLogic Server 為安全套接口層 (SSL) 加密的通信使用 HTTPS 端口,在此端口上僅可以使用 SSL。
注意: | 為了在 WebLogic 客戶端實(shí)現(xiàn)安全性,必須在 Java 客戶端上安裝 WebLogic Server 軟件分發(fā)包。 |
Java 客戶端使用 Java 命名和目錄接口 (JNDI) 將憑據(jù)傳送給 WebLogic Server。Java 客戶端通過(guò)獲取 JNDI InitialContext
來(lái)建立與 WebLogic Server 的連接。然后,Java 客戶端使用 InitialContext
,在 WebLogic Server JNDI 樹中查找所需的資源。
注意: | JAAS 是首選的身份驗(yàn)證方法;但是,此身份驗(yàn)證提供程序的 LoginModule 只支持用戶名和密碼身份驗(yàn)證。因此,對(duì)于客戶端證書身份驗(yàn)證(也稱作雙向 SSL 身份驗(yàn)證),應(yīng)該使用 JNDI。要使用 JAAS 進(jìn)行客戶端證書身份驗(yàn)證,必須編寫自定義身份驗(yàn)證提供程序(其 LoginModule 能進(jìn)行證書身份驗(yàn)證)。 |
要指定用戶和用戶憑據(jù),請(qǐng)?jiān)O(shè)置表 5-1 中列出的 JNDI 屬性。
這些屬性存儲(chǔ)在傳遞給 InitialContext
構(gòu)造方法的散列表中。
清單 5-1 說(shuō)明了如何在 Java 客戶端使用單向 SSL 證書身份驗(yàn)證。有關(guān)雙向 SSL 身份驗(yàn)證代碼示例,請(qǐng)參閱清單 5-4, 使用 JNDI 的雙向 SSL 證書身份驗(yàn)證客戶端示例。
...
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3s://weblogic:7002");
env.put(Context.SECURITY_PRINCIPAL, "javaclient");
env.put(Context.SECURITY_CREDENTIALS, "javaclientpassword");
ctx = new InitialContext(env);
注意: | 有關(guān) JNDI 上下文和線程以及如何避免潛在 JNDI 上下文問(wèn)題的信息,請(qǐng)參閱“WebLogic JNDI 編程”中的 JNDI 上下文和線程和如何避免潛在的 JNDI 上下文問(wèn)題。 |
要實(shí)現(xiàn)在 WebLogic Server 上使用 SSL 身份驗(yàn)證的 Java 客戶端,請(qǐng)使用 Java JDK 5.0 應(yīng)用程序編程接口(Application Programming Interface,簡(jiǎn)稱 API)和 WebLogic API 的組合。
表 5-2 列出并描述了用于實(shí)現(xiàn)證書身份驗(yàn)證的 Java API 包。表 5-2 中的信息是從 Java API 文檔獲取的,并附帶批注,以添加 WebLogic Server 特定信息。有關(guān) Java API 的詳細(xì)信息,請(qǐng)參閱位于 http://java.sun.com/j2se/1.5.0/docs/api/index.html 和 http://java.sun.com/j2ee/1.4/docs/api/index.html 的 Javadoc。
表 5-3 列出并描述了用于實(shí)現(xiàn)證書身份驗(yàn)證的 WebLogic API 包。有關(guān)詳細(xì)信息,請(qǐng)參閱 Javadocs for WebLogic Classes。
HostnameVerifier 可實(shí)現(xiàn) weblogic.security.SSL.HostnameVerifier
接口。
HandshakeCompletedListener 可實(shí)現(xiàn) javax.net.ssl.HandshakeCompletedListener
接口。SSL 客戶端用它來(lái)接收有關(guān)在給定 SSL 連接上完成 SSL 握手的通知。
TrustManager 可實(shí)現(xiàn) weblogic.security.SSL.TrustManager
接口。
有關(guān)可實(shí)現(xiàn)上述組件的完整工作 SSL 身份驗(yàn)證客戶端,請(qǐng)參閱與 WebLogic Server 一同提供的 SSLClient 示例應(yīng)用程序(位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下)。此示例也可從 BEA 的 dev2dev 站點(diǎn)聯(lián)機(jī)獲得
有關(guān) JSSE 身份驗(yàn)證的詳細(xì)信息,請(qǐng)參閱 Sun 的“Java Secure Socket Extension (JSSE) Reference Guide”,可在以下位置找到:http://java.sun.com/j2se/1.5.0/docs/guide/security/jsse/JSSERefGuide.html。
可以使用 URL 對(duì)象執(zhí)行從充當(dāng)客戶端的 WebLogic Server 實(shí)例到另一個(gè) WebLogic Server 實(shí)例的出站 SSL 連接。weblogic.net.http.HttpsURLConnection
類為客戶端提供了指定安全上下文信息(包括客戶端的數(shù)字證書和私鑰)的方法。
weblogic.net.http.HttpsURLConnection
類提供了一些用于實(shí)現(xiàn)下列功能的方法:確定協(xié)商的密碼組、獲取/設(shè)置主機(jī)名驗(yàn)證器、獲取服務(wù)器的證書鏈以及獲取/設(shè)置 SSLSocketFactory
以便新建 SSL 套接口。
SSLClient 代碼示例使用 weblogic.net.http.HttpsURLConnection
類執(zhí)行出站 SSL 連接。SSLClient 代碼示例可從 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 examples.security.sslclient
包獲取。
此部分使用這些示例說(shuō)明了如何編寫各種類型的 SSL 客戶端。提供了下列類型的 SSL 客戶端示例:
SSL 客戶端許可要求:任何使用 WebLogic SSL 類 (weblogic.security.SSL) 來(lái)調(diào)用 Enterprise JavaBean (EJB) 的獨(dú)立 Java 客戶端必須使用 BEA 許可文件。在運(yùn)行客戶端應(yīng)用程序時(shí),請(qǐng)?jiān)O(shè)置下列系統(tǒng)屬性:
以下是一個(gè)運(yùn)行使用許可文件默認(rèn)位置 (c:\bea
) 的命令的示例:
java -Dbea.home=c:\bea \
-Djava.protocol.handler.pkgs=weblogic.net my_app
SSLClient 示例說(shuō)明了如何使用 WebLogic SSL 庫(kù)通過(guò)使用 URL
和 URLConnection
對(duì)象執(zhí)行傳出 SSL 連接。它顯示如何從獨(dú)立應(yīng)用程序以及 WebLogic Server 中的Servlet 執(zhí)行此連接。
注意: | 充當(dāng) SSL 客戶端的 WebLogic Server 為傳出 SSL 連接使用服務(wù)器的標(biāo)識(shí)證書。默認(rèn)情況下,在 WebLogic Server 上運(yùn)行并使用先前描述的 SSL API 的應(yīng)用程序不會(huì)共享服務(wù)器的標(biāo)識(shí)證書,僅是信任。 |
清單 5-2 顯示了 SSLClient 示例的代碼片段,完整的示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 SSLClient.java
文件中。
package examples.security.sslclient;
import java.io.*;
import java.net.URL;
import java.security.Provider;
import javax.servlet.ServletOutputStream;
...
/*
* 使用 WebLogic SSL 客戶端類,
* 此方法包含如何使用 URL 和 URLConnection 對(duì)象
* 創(chuàng)建新 SSL 連接的示例。
*/
public void wlsURLConnect(String host, String port,
String sport, String query,
OutputStream out)
throws Exception {
...
URL wlsUrl = null;
try {
wlsUrl = new URL("http", host, Integer.valueOf(port).intValue(),
query);
weblogic.net.http.HttpURLConnection connection =
new weblogic.net.http.HttpURLConnection(wlsUrl);
tryConnection(connection, out);
}
...
wlsUrl = new URL("https", host, Integer.valueOf(sport).intValue(),
query);
weblogic.net.http.HttpsURLConnection sconnection =
new weblogic.net.http.HttpsURLConnection(wlsUrl);
...
SSLSocketClient 示例說(shuō)明了如何使用 SSL 套接口直接轉(zhuǎn)至安全端口,以連接到 WebLogic Server 實(shí)例服務(wù)的 JSP,并顯示該連接的結(jié)果。它顯示了如何實(shí)現(xiàn)下列功能:
HostnameVerifier
和 TrustManager
初始化 SSLContext
SSLSocketFactory
javax.net.ssl.HandshakeCompletedListener
接口weblogic.security.SSL.HostnameVerifier
類的虛擬實(shí)現(xiàn),以驗(yàn)證此示例連接到的服務(wù)器是否在所需的主機(jī)上運(yùn)行 清單 5-3 顯示了 SSLSocketClient 示例的代碼片段,完整的示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 SSLSocketClient.java
文件中。(sslclient
目錄中的 SSLClientServlet 示例是一個(gè)簡(jiǎn)單的 SSLClient 的 Servlet 包裝示例。)
package examples.security.sslclient;
import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLSocket;
import weblogic.security.SSL.HostnameVerifier;
import weblogic.security.SSL.SSLContext;
import weblogic.security.SSL.SSLSocketFactory;
import weblogic.security.SSL.TrustManager;
...
SSLContext sslCtx = SSLContext.getInstance("https");
File KeyStoreFile = new File ("mykeystore");
...
// 打開(kāi)密鑰庫(kù)、檢索私鑰和證書鏈
KeyStore ks = KeyStore.getInstance("jks");
ks.load(new FileInputStream("mykeystore"), null);
PrivateKey key = (PrivateKey)ks.getKey("mykey",
"testkey".toCharArray());
Certificate [] certChain = ks.getCertificateChain("mykey");
sslCtx.loadLocalIdentity(certChain, key);
HostnameVerifier hVerifier = null;
if (argv.length < 3)
hVerifier = new NulledHostnameVerifier();
else
hVerifier = (HostnameVerifier)
Class.forName(argv[2]).newInstance();
sslCtx.setHostnameVerifier(hVerifier);
TrustManager tManager = new NulledTrustManager();
sslCtx.setTrustManager(tManager);
System.out.println(" Creating new SSLSocketFactory with SSLContext");
SSLSocketFactory sslSF = (SSLSocketFactory)
sslCtx.getSocketFactory();
System.out.println(" Creating and opening new SSLSocket with
SSLSocketFactory");
// 使用 createSocket(String hostname, int port)
SSLSocket sslSock = (SSLSocket) sslSF.createSocket(argv[0],
new Integer(argv[1]).intValue());
System.out.println(" SSLSocket created");
HandshakeCompletedListener mListener = null;
mListener = new MyListener();
sslSock.addHandshakeCompletedListener(new MyListener());
...
在使用證書身份驗(yàn)證時(shí),WebLogic Server 會(huì)將數(shù)字證書發(fā)送到請(qǐng)求客戶端。客戶端將檢查數(shù)字證書,以確保其可信、未過(guò)期,并且與提供它的 WebLogic Server 實(shí)例相匹配。
使用雙向 SSL 身份驗(yàn)證(一種相互身份驗(yàn)證的方式)時(shí),請(qǐng)求客戶端也需要向 WebLogic Server 提供數(shù)字證書。如果將 WebLogic Server 的實(shí)例配置為雙向 SSL 身份驗(yàn)證,則請(qǐng)求客戶端需要提供來(lái)自指定的一組證書頒發(fā)機(jī)構(gòu)的數(shù)字證書。WebLogic Server 只接受由可信證書頒發(fā)機(jī)構(gòu)簽名的數(shù)字證書。
有關(guān)如何配置雙向 SSL 身份驗(yàn)證的 WebLogic Server 的信息,請(qǐng)參閱“確保 WebLogic Server 安全”中的配置 SSL。
下列部分描述了可在 WebLogic Server 中實(shí)現(xiàn)的幾種不同的雙向 SSL 身份驗(yàn)證方式。
在 Java 客戶端中使用 JNDI 進(jìn)行雙向 SSL 身份驗(yàn)證時(shí),請(qǐng)使用 WebLogic JNDI Environment
類的 setSSLClientCertificate()
方法。此方法可為客戶端身份驗(yàn)證設(shè)置私鑰和 X.509 數(shù)字證書鏈。
要將數(shù)字證書傳送到 JNDI,請(qǐng)創(chuàng)建在包含 DER 編碼數(shù)字證書的文件上打開(kāi)的 InputStreams
數(shù)組,并在 JNDI 散列表中設(shè)置該數(shù)組。數(shù)組中的第一個(gè)元素必須包含在 Java 客戶端的私鑰文件上打開(kāi)的 InputStream
。第二個(gè)元素必須包含在 Java 客戶端的數(shù)字證書文件上打開(kāi)的 InputStream
。(此文件包含 Java 客戶端的公鑰。)其他元素可能包含根證書頒發(fā)機(jī)構(gòu)的數(shù)字證書,以及證書鏈中任何數(shù)字證書的簽名者。如果某個(gè)數(shù)字證書不是直接由服務(wù)器的可信證書頒發(fā)機(jī)構(gòu)發(fā)行的,則 WebLogic Server 可通過(guò)證書鏈對(duì) Java 客戶端的數(shù)字證書進(jìn)行身份驗(yàn)證。
可以使用 weblogic.security.PEMInputStream 類讀取存儲(chǔ)在增強(qiáng)型私人郵件(Privacy Enhanced Mail,簡(jiǎn)稱 PEM)文件中的數(shù)字證書。此類提供了可通過(guò) PEM 文件對(duì) Base64 編碼證書進(jìn)行解碼的篩選器。
清單 5-4 說(shuō)明了如何在 Java 客戶端中使用雙向 SSL 身份驗(yàn)證。
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.jndi.Environment;
import weblogic.security.PEMInputStream;
import java.io.InputStream;
import java.io.FileInputStream;
public class SSLJNDIClient
{
public static void main(String[] args) throws Exception
{
Context context = null;
try {
Environment env = new Environment();
// 設(shè)置連接參數(shù)
env.setProviderUrl("t3s://localhost:7002");
// 如果您正在使用 UserNameMapper 接口,
// 那么下兩個(gè)設(shè)置方法是可選的。
env.setSecurityPrincipal("system");
env.setSecurityCredentials("weblogic");
InputStream key = new FileInputStream("certs/demokey.pem");
InputStream cert = new FileInputStream("certs/democert.pem");
// 如果 key/cert 在文件中,那么包裝輸入流
key = new PEMInputStream(key);
cert = new PEMInputStream(cert);
env.setSSLClientCertificate(new InputStream[] { key, cert});
env.setInitialContextFactory(Environment.DEFAULT_INITIAL_CONTEXT_FACTORY);
context = env.getInitialContext();
Object myEJB = (Object) context.lookup("myEJB");
}
finally {
if (context != null) context.close();
}
}
}
調(diào)用 JNDI getInitialContext()
方法時(shí),Java 客戶端和 WebLogic Server 將執(zhí)行相互身份驗(yàn)證,其方式與 Web 瀏覽器執(zhí)行相互身份驗(yàn)證以獲取安全 Web 服務(wù)器連接相同。如果不能驗(yàn)證數(shù)字證書,或不能在默認(rèn)(活動(dòng))安全領(lǐng)域中對(duì) Java 客戶端的數(shù)字證書進(jìn)行身份驗(yàn)證,將引發(fā)異常。通過(guò)身份驗(yàn)證的用戶對(duì)象存儲(chǔ)在 Java 客戶端的服務(wù)器線程上,并用于檢查可控制 Java 客戶端訪問(wèn)任何受保護(hù) WebLogic 資源的權(quán)限。
在使用 WebLogic JNDI Environment
類時(shí),必須為對(duì) getInitialContext()
方法的每個(gè)調(diào)用新建一個(gè) Environment
對(duì)象。指定 User
對(duì)象和安全憑據(jù)后,用戶及其關(guān)聯(lián)憑據(jù)都將保持 Environment
對(duì)象中的設(shè)置。如果嘗試重新設(shè)置它們,然后調(diào)用 JNDI getInitialContext()
方法,則將使用初始的用戶和憑據(jù)。
在 Java 客戶端中使用雙向 SSL 身份驗(yàn)證時(shí),WebLogic Server 將獲取每個(gè)客戶端 JVM 的唯一 Java 虛擬機(jī) (JVM) ID,以便 Java 客戶端和 WebLogic Server 之間的連接始終不變。除非連接由于沒(méi)有活動(dòng)而超時(shí),只要 Java 客戶端的 JVM 繼續(xù)執(zhí)行,連接就會(huì)持續(xù)存在。Java 客戶端能夠可靠地協(xié)商新 SSL 連接的惟一方法是停止其 JVM,并運(yùn)行 JVM 的其他實(shí)例。
清單 5-4, 使用 JNDI 的雙向身份驗(yàn)證客戶端示例 中的代碼可生成對(duì)實(shí)現(xiàn) weblogic.security.providers.authentication.UserNameMapper
接口的 WebLogic 標(biāo)識(shí)聲明提供程序的調(diào)用。如果數(shù)字證書有效,則實(shí)現(xiàn) UserNameMapper
接口的類將返回用戶對(duì)象。WebLogic Server 將此通過(guò)身份驗(yàn)證的用戶對(duì)象存儲(chǔ)在 WebLogic Server 中 Java 客戶端的線程上,在線程嘗試使用受默認(rèn)(活動(dòng))安全領(lǐng)域保護(hù)的 WebLogic 資源時(shí),此用戶對(duì)象將用于后續(xù)授權(quán)請(qǐng)求。
注意: | CLASSPATH 必須指定 weblogic.security.providers.authentication.UserNameMapper 接口的實(shí)現(xiàn)。 |
如果您尚未配置可執(zhí)行基于證書的身份驗(yàn)證的標(biāo)識(shí)聲明提供程序,則通過(guò)新建 JNDI InitialContext
,并在 JNDI SECURITY_PRINCIPAL
和 SECURITY_CREDENTIALS
屬性中提供新用戶名和密碼,在具有 SSL 連接的 JVM 中運(yùn)行的 Java 客戶端便可更改 WebLogic Server 用戶標(biāo)識(shí)。在進(jìn)行 SSL 連接后,不使用由 Java 客戶端傳遞的任何數(shù)據(jù)證書。新 WebLogic Server 用戶可繼續(xù)使用與初始用戶的數(shù)字證書協(xié)商的 SSL 連接。
如果您已經(jīng)配置了執(zhí)行基于證書的身份驗(yàn)證的標(biāo)識(shí)聲明提供程序,WebLogic Server 將把數(shù)據(jù)證書從 Java 客戶端傳遞到實(shí)現(xiàn) UserNameMapper
接口的類,UserNameMapper
類可將數(shù)字證書映射到 WebLogic Server 用戶名。因此,如果要在使用基于證書的標(biāo)識(shí)聲明時(shí)設(shè)置新用戶標(biāo)識(shí),將無(wú)法更改標(biāo)識(shí)。這是因?yàn)閷?duì)于每個(gè) Environment
,只在 JVM 發(fā)出第一個(gè)連接請(qǐng)求時(shí)處理數(shù)字證書。
警告: | 限制:在使用雙向 SSL 和 JNDI 時(shí),不支持多個(gè)并發(fā)用戶從單一客戶端 JVM 登錄到 WebLogic Server。如果多個(gè)登錄在不同線程上執(zhí)行,結(jié)果將無(wú)法確定,并可能導(dǎo)致一個(gè)用戶的請(qǐng)求在其他用戶的登錄上執(zhí)行,從而使某個(gè)用戶可以訪問(wèn)其他用戶的數(shù)據(jù)。WebLogic Server 不支持來(lái)自單一客戶端 JVM 的多個(gè)基于證書的并發(fā)登錄。有關(guān) JNDI 上下文和線程,以及如何避免潛在的 JNDI 上下文問(wèn)題的信息,請(qǐng)參閱“WebLogic JNDI 編程”中的 JNDI 上下文和線程和如何避免潛在的 JNDI 上下文問(wèn)題。 |
在使用雙向 SSL 時(shí),WebLogic Server 在建立 SSL 連接時(shí)可驗(yàn)證 Web 瀏覽器或 Java 客戶端的數(shù)字證書。但是,數(shù)字證書不會(huì)將 Web 瀏覽器或 Java 客戶端標(biāo)識(shí)為 WebLogic Server 安全領(lǐng)域中的用戶。如果 Web 瀏覽器或 Java 客戶端請(qǐng)求受安全策略保護(hù)的 WebLogic Server 資源,則 WebLogic Server 需要 Web 瀏覽器或 Java 客戶端具有標(biāo)識(shí)。為了處理此要求,WebLogic 標(biāo)識(shí)聲明提供程序允許啟用用戶名映射器,此映射器可將 Web 瀏覽器或 Java 客戶端的數(shù)字證書映射到 WebLogic Server 安全領(lǐng)域中的用戶。用戶名映射器必須是 weblogic.security.providers.authentication.UserNameMapper
接口的實(shí)現(xiàn)。
可以選擇使用 weblogic.security.providers.authentication.UserNameMapper
接口的默認(rèn)實(shí)現(xiàn) DefaultUserNameMapperImpl
,或開(kāi)發(fā)自己的實(shí)現(xiàn)。
WebLogic 標(biāo)識(shí)聲明提供程序可為下列類型的標(biāo)識(shí)聲明標(biāo)記類型調(diào)用 UserNameMapper
接口的實(shí)現(xiàn):
如果您需要映射不同類型的證書,請(qǐng)編寫自己的 UserNameMapper
接口實(shí)現(xiàn)。
要實(shí)現(xiàn)可將數(shù)字證書映射到用戶名的 UserNameMapper
接口,請(qǐng)編寫可執(zhí)行下列操作的 UserNameMapper
類:
可以在服務(wù)器到服務(wù)器通信中使用雙向 SSL 身份驗(yàn)證,在此通信中其中一個(gè) WebLogic Server 實(shí)例充當(dāng)另一個(gè) WebLogic Server 實(shí)例的客戶端。通過(guò)在服務(wù)器到服務(wù)器通信中使用雙向 SSL 身份驗(yàn)證,即使沒(méi)有更常用的客戶端/服務(wù)器環(huán)境,您也可以擁有可靠的、高度安全的連接。
清單 5-5 顯示了如何建立從在某個(gè) WebLogic Server 實(shí)例中運(yùn)行的 servlet,到第二個(gè)稱為 server2.weblogic.com
的 WebLogic Server 實(shí)例的安全連接示例。
FileInputStream [] f = new FileInputStream[3];
f[0]= new FileInputStream("demokey.pem");
f[1]= new FileInputStream("democert.pem");
f[2]= new FileInputStream("ca.pem");
Environment e = new Environment ();
e.setProviderURL("t3s://server2.weblogic.com:443");
e.setSSLClientCertificate(f);
e.setSSLServerName("server2.weblogic.com");
e.setSSLRootCAFingerprints("ac45e2d1ce492252acc27ee5c345ef26");
e.setInitialContextFactory
("weblogic.jndi.WLInitialContextFactory");
Context ctx = new InitialContext(e.getProperties())
在清單 5-5 中,WebLogic JNDI Environment
類創(chuàng)建的散列表用于存儲(chǔ)下列參數(shù):
setProviderURL
- 指定充當(dāng) SSL 服務(wù)器的 WebLogic Server 實(shí)例的 URL。WebLogic Server 實(shí)例充當(dāng) SSL 客戶端來(lái)調(diào)用此方法。URL 用于指定為在 SSL 協(xié)議上構(gòu)建的 WebLogic Server 專用協(xié)議的 t3 協(xié)議。SSL 協(xié)議可保護(hù)兩個(gè) WebLogic Server 實(shí)例之間的連接和通信。setSSLClientCertificate
- 指定用于 SSL 連接的私鑰和證書鏈。使用此方法可指定一個(gè)輸入流數(shù)組,此數(shù)組由私鑰(數(shù)組中的第一個(gè)輸入流)以及 X.509 證書鏈(這構(gòu)成了數(shù)組的剩余輸入流)組成。證書鏈中的每份證書是鏈中位于它前面的證書的發(fā)行方。setSSLServerName
- 指定充當(dāng) SSL 服務(wù)器的 WebLogic Server 實(shí)例的名稱。在 SSL 服務(wù)器將其數(shù)字證書提供給充當(dāng) SSL 客戶端的 WebLogic Server 時(shí),會(huì)將使用 setSSLServerName
方法指定的名稱與此數(shù)字證書中的公用名稱字段進(jìn)行比較。為使主機(jī)名驗(yàn)證獲得成功,這兩個(gè)名稱必須相匹配。此參數(shù)用于防止中間人攻擊。setSSLRootCAFingerprint
- 指定可表示一組可信證書頒發(fā)機(jī)構(gòu)的數(shù)字代碼,從而基于可信證書指紋指定信任。從充當(dāng) SSL 服務(wù)器的 WebLogic Server 實(shí)例接收的證書鏈的根證書,必須與使用此方法指定的指紋之一匹配,才能達(dá)到可信的目的。此參數(shù)用于防止中間人攻擊。它提供了附加的默認(rèn)信任級(jí)別,此級(jí)別對(duì)于在 WebLogic Server 上運(yùn)行的客戶端而言,是由 WebLogic Server 信任配置指定的。 注意: | 有關(guān) JNDI 上下文和線程,以及如何避免潛在的 JNDI 上下文問(wèn)題的信息,請(qǐng)參閱“WebLogic JNDI 編程”中的 JNDI 上下文和線程和如何避免潛在的 JNDI 上下文問(wèn)題。 |
要在某個(gè) Servlet(或其他任何服務(wù)器端 Java 類)中對(duì) Java 客戶端進(jìn)行身份驗(yàn)證,必須檢查客戶端是否提供一份數(shù)字證書,如果是,檢查此證書是否由可信的證書頒發(fā)機(jī)構(gòu)發(fā)行。Servlet 開(kāi)發(fā)人員負(fù)責(zé)詢問(wèn) Java 客戶端是否擁有有效的數(shù)字證書。在使用 WebLogic Servlet API 開(kāi)發(fā) Servlet 時(shí),必須通過(guò) HTTPServletRequest
對(duì)象的 getAttribute()
方法訪問(wèn)有關(guān) SSL 連接的信息。
WebLogic Server Servlet 中支持下列特性:
javax.servlet.request.X509Certificate
java.security.cert.X509Certificate []
- 可返回一組 X.509 證書。 javax.servlet.request.cipher_suite
- 可返回 HTTPS 使用的表示密碼組的字符串。javax.servlet.request.key_size
- 可返回一個(gè)整數(shù)(0、40、56、128、168),此整數(shù)表示對(duì)稱(批量加密)密鑰算法的位大小。 weblogic.servlet.request.SSLSession
javax.net.ssl.SSLSession
-可返回 SSL 會(huì)話對(duì)象,此對(duì)象包含創(chuàng)建和最后使用對(duì)象的密碼組和日期。 您有權(quán)訪問(wèn)數(shù)字證書中定義的用戶信息。在您獲取 javax.servlet.request.X509Certificate
特性時(shí),它是 java.security.cert.X509Certificate
類型的數(shù)組。您只需將數(shù)組轉(zhuǎn)換為此類型,并檢查證書。
主機(jī)名驗(yàn)證器可驗(yàn)證進(jìn)行 SSL 連接的主機(jī)是預(yù)定方還是授權(quán)方。如果 WebLogic 客戶端或 WebLogic Server 實(shí)例充當(dāng)另一個(gè)應(yīng)用服務(wù)器的 SSL 客戶端,則主機(jī)名驗(yàn)證器非常有用。它幫助防止中間人攻擊。
注意: | 示范數(shù)字證書是在安裝期間生成的,以便其包含安裝 WebLogic Server 軟件的系統(tǒng)的主機(jī)名。因此,在使用示范證書進(jìn)行開(kāi)發(fā)和測(cè)試時(shí)應(yīng)保留主機(jī)名驗(yàn)證。 |
在默認(rèn)情況下,作為 SSL 握手的一項(xiàng)功能,WebLogic Server 會(huì)將 SSL 服務(wù)器證書主題 DN 的 CN 字段與用于連接到服務(wù)器的 URL 中的主機(jī)名進(jìn)行比較。如果這些名稱不匹配,則刪除此 SSL 連接。
刪除 SSL 連接是由 SSL 客戶端引起的,此客戶端可根據(jù)服務(wù)器的數(shù)字證書對(duì)服務(wù)器的主機(jī)名進(jìn)行驗(yàn)證。如果需要除默認(rèn)行為之外的行為,可以關(guān)閉主機(jī)名驗(yàn)證,或注冊(cè)自定義主機(jī)名驗(yàn)證器。關(guān)閉主機(jī)名驗(yàn)證將使 SSL 連接容易受到中間人的攻擊。
可以使用下列方式關(guān)閉主機(jī)名驗(yàn)證:
您可以編寫自定義主機(jī)名驗(yàn)證器。weblogic.security.SSL.HostnameVerifier
接口提供了回調(diào)機(jī)制,以便此接口的實(shí)施者能夠提供是否允許連接到 URL 的主機(jī)名的策略。此策略可以基于證書,也可以取決于其他身份驗(yàn)證方案。
要使用自定義主機(jī)名驗(yàn)證器,請(qǐng)創(chuàng)建可實(shí)現(xiàn) weblogic.security.SSL.HostnameVerifier
接口的類,并定義可捕獲服務(wù)器安全標(biāo)識(shí)信息的方法。
注意: | 此接口采用新樣式證書并將替換已不再使用的 weblogic.security.SSL.HostnameVerifierJSSE 接口。 |
在可以使用自定義主機(jī)名驗(yàn)證器之前,需要使用下列方式實(shí)現(xiàn)指定實(shí)現(xiàn)的類:
清單 5-6 顯示了 NulledHostnameVerifier 示例的代碼片斷;完整的示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 NulledHostnameVerifier.java
文件中。此代碼示例包含始終返回比較結(jié)果為 true 的 NulledHostnameVerifier
類。通過(guò)此示例,WebLogic SSL 客戶端可以連接到任何 SSL 服務(wù)器,無(wú)論服務(wù)器的主機(jī)名和數(shù)字證書 SubjectDN 的比較結(jié)果如何。
public class NulledHostnameVerifier implements
weblogic.security.SSL.HostnameVerifier {
public boolean verify(String urlHostname, javax.net.ssl.SSLSession session) {
return true;
}
}
weblogic.security.SSL.TrustManager
接口提供執(zhí)行以下功能:
注意: | 此接口采用新樣式證書并將替換已不再使用的 weblogic.security.SSL.TrustManagerJSSE 接口。 |
當(dāng) SSL 客戶端連接到 WebLogic Server 實(shí)例時(shí),服務(wù)器會(huì)將其數(shù)字證書鏈提供給客戶端以進(jìn)行身份驗(yàn)證此鏈可能包含無(wú)效的數(shù)字證書。SSL 規(guī)范中規(guī)定在發(fā)現(xiàn)無(wú)效證書時(shí),客戶端應(yīng)該刪除 SSL 連接??梢允褂?TrustManager
接口的自定義實(shí)現(xiàn),來(lái)控制何時(shí)繼續(xù)或中斷 SSL 握手。使用信任管理器可以忽略某些驗(yàn)證錯(cuò)誤,還可以根據(jù)需要執(zhí)行驗(yàn)證檢查,然后決定是否繼續(xù)握手。
可使用 weblogic.security.SSL.TrustManager
接口創(chuàng)建信任管理器。此接口包含一組證書驗(yàn)證的錯(cuò)誤代碼。也可以對(duì)對(duì)等方證書執(zhí)行其他驗(yàn)證,并根據(jù)需要中斷 SSL 握手。在驗(yàn)證數(shù)字證書后,weblogic.security.SSL.TrustManager
接口將使用回調(diào)功能替換數(shù)字證書的驗(yàn)證結(jié)果。可以通過(guò) setTrustManager()
方法將信任管理器的實(shí)例與 SSL 上下文相關(guān)聯(lián)。
您只能以編程方式設(shè)置信任管理器;不能通過(guò)管理控制臺(tái)或在命令行上定義其用法。
注意: | 使用信任管理器可能會(huì)影響性能,具體取決于所執(zhí)行的檢查。 |
清單 5-7 顯示了 NulledTrustManager 示例的代碼片斷;完整的示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 NulledTrustManager.java
文件。SSLSocketClient 示例使用自定義信任管理器。SSLSocketClient 顯示了如何通過(guò)使用帶信任管理器的 SSL 上下文設(shè)置新的 SSL 連接。
package examples.security.sslclient;
import weblogic.security.SSL.TrustManager;
import java.security.cert.X509Certificate;
...
public class NulledTrustManager implements TrustManager{
public boolean certificateCallback(X509Certificate[] o, int validateErr) {
System.out.println(" --- Do Not Use In Production ---\n" +
" By using this NulledTrustManager, the trust in" +
" the server's identity is completely lost.\n" + " --------------------------------");
for (int i=0; i<o.length; i++)
System.out.println(" certificate " + i + " -- " + o[i].toString());
return true;
}
}
CertPathTrustManager weblogic.security.SSL.CertPathTrustManager
利用默認(rèn)安全領(lǐng)域的已配置證書路徑驗(yàn)證提供程序執(zhí)行附加驗(yàn)證(例如撤銷檢查)。
默認(rèn)情況下,服務(wù)器中使用出站 SSL 的應(yīng)用程序代碼只能訪問(wèn)內(nèi)置的 SSL 證書驗(yàn)證。但是,應(yīng)用程序代碼可以指定 CertPathTrustManager,以便訪問(wèn)管理員已經(jīng)為服務(wù)器配置的任何其他證書驗(yàn)證。如果想要應(yīng)用程序代碼也能運(yùn)行證書路徑驗(yàn)證器,則應(yīng)用程序代碼應(yīng)使用 CertPathTrustManager。
setUseConfiguredSSLValidation()
方法來(lái)達(dá)到此目的。此項(xiàng)為默認(rèn)設(shè)置。 setBuiltinSSLValidationAndCertPathValidators()
方法來(lái)達(dá)到此目的。setBuiltinSSLValidationOnly()
方法來(lái)達(dá)到此目的。 javax.net.ssl.HandshakeCompletedListener
接口定義了 SSL 客戶端接收有關(guān)給定 SSL 連接上 SSL 協(xié)議握手完成的通知的方式。清單 5-8 顯示了 MyListener 示例的代碼片斷;完整的示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄下的 MyListener.java
文件。
package examples.security.sslclient;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import javax.net.ssl.HandshakeCompletedListener;
import java.util.Hashtable;
import javax.net.ssl.SSLSession;
...
public class MyListener implements HandshakeCompletedListener
{
public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent
event)
{
SSLSession session = event.getSession();
System.out.println("Handshake Completed with peer " +
session.getPeerHost());
System.out.println(" cipher: " + session.getCipherSuite());
Certificate[] certs = null;
try
{
certs = session.getPeerCertificates();
}
catch (SSLPeerUnverifiedException puv)
{
certs = null;
}
if (certs != null)
{
System.out.println(" peer certificates:");
for (int z=0; z<certs.length; z++)
System.out.println(" certs["+z+"]: " + certs[z]);
}
else
{
System.out.println("No peer certificates presented");
}
}
}
SSLContext
類用于以編程方式配置 SSL,并保留 SSL 會(huì)話信息。每個(gè)實(shí)例都可以使用將用于執(zhí)行身份驗(yàn)證的密鑰、證書鏈和可信 CA 證書進(jìn)行配置。使用同一 SSLContext 創(chuàng)建,并用于連接到同一 SSL 服務(wù)器的 SSL 套接口可能重用 SSL 會(huì)話信息。是否實(shí)際重用會(huì)話信息取決于 SSL 服務(wù)器。
有關(guān)會(huì)話緩存的詳細(xì)信息,請(qǐng)參閱“確保 WebLogic Server 安全”中的 SSL 會(huì)話行為。要將信任管理器類的實(shí)例與其 SSL 上下文相關(guān)聯(lián),請(qǐng)使用 weblogic.security.SSL.SSLContext.setTrustManager()
方法。
只能以編程方式設(shè)置 SSL 上下文;不能使用管理控制臺(tái)或命令行進(jìn)行設(shè)置。Java new
表達(dá)式或 SSLContext
類的 getInstance()
方法可以創(chuàng)建 SSLContext
對(duì)象。getInstance()
方法是靜態(tài)的,它可生成實(shí)現(xiàn)指定的安全套接口協(xié)議的新 SSLContext
對(duì)象。 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄中的 SSLSocketClient.java
示例提供了使用 SSLContext
類的示例。SSLSocketClient 示例顯示了如何新建將使用 SSLContext
新建 SSL 套接口的 SSL 套接口工廠。
清單 5-9 顯示了使用 getInstance()
方法進(jìn)行實(shí)例化的示例。
import weblogic.security.SSL.SSLContext;
SSLcontext sslctx = SSLContext.getInstance ("https")
可以使用 URL
對(duì)象執(zhí)行從充當(dāng)客戶端的某個(gè) WebLogic Server 實(shí)例到另一個(gè) WebLogic Server 實(shí)例的出站 SSL 連接。WebLogic Server 支持出站 SSL 連接的單向和雙向 SSL 身份驗(yàn)證。
對(duì)于單向 SSL 身份驗(yàn)證,可使用 java.net.URL
, java.net.URLConnection
和 java.net.HTTPURLConnection
類通過(guò)使用 URL
對(duì)象進(jìn)行出站 SSL 連接。清單 5-10 顯示了同時(shí)支持 HTTP 和 HTTPS URL 且僅使用這些 Java 類(即不需要 WebLogic 類) simpleURL
的類。要在 WebLogic Server 上為單向 SSL 身份驗(yàn)證 (HTTPS) 使用 simpleURL
類,只需在系統(tǒng)屬性中為 java.protocols.handler.pkgs
定義“weblogic.net
”即可。
注意: | 因?yàn)?a >清單 5-10 中顯示的 simpleURL 示例默認(rèn)會(huì)執(zhí)行信任和主機(jī)名檢查,所以此示例需要連接到默認(rèn)情況下可信并且會(huì)傳遞主機(jī)名檢查的真正 Web 服務(wù)器。否則,必須在命令行上替換信任和主機(jī)名檢查。 |
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.io.IOException;
public class simpleURL
{
public static void main (String [] argv)
{
if (argv.length != 1)
{
System.out.println("Please provide a URL to connect to");
System.exit(-1);
}
setupHandler();
connectToURL(argv[0]);
}
private static void setupHandler()
{
java.util.Properties p = System.getProperties();
String s = p.getProperty("java.protocol.handler.pkgs");
if (s == null)
s = "weblogic.net";
else if (s.indexOf("weblogic.net") == -1)
s += "|weblogic.net";
p.put("java.protocol.handler.pkgs", s);
System.setProperties(p);
}
private static void connectToURL(String theURLSpec)
{
try
{
URL theURL = new URL(theURLSpec);
URLConnection urlConnection = theURL.openConnection();
HttpURLConnection connection = null;
if (!(urlConnection instanceof HttpURLConnection))
{
System.out.println("The URL is not using HTTP/HTTPS: " +
theURLSpec);
return;
}
connection = (HttpURLConnection) urlConnection;
connection.connect();
String responseStr = "\t\t" +
connection.getResponseCode() + " -- " +
connection.getResponseMessage() + "\n\t\t" +
connection.getContent().getClass().getName() + "\n";
connection.disconnect();
System.out.println(responseStr);
}
catch (IOException ioe)
{
System.out.println("Failure processing URL: " + theURLSpec);
ioe.printStackTrace();
}
}
}
對(duì)于雙向 SSL 身份驗(yàn)證,weblogic.net.http.HttpsURLConnection
類為客戶端提供了一種指定安全上下文信息(包括客戶端的數(shù)字證書和私鑰)的方法。此類的實(shí)例表示到遠(yuǎn)程對(duì)象的 HTTPS 連接。
SSLClient 示例代碼演示了使用 WebLogic URL
對(duì)象執(zhí)行出站 SSL 連接(請(qǐng)參閱清單 5-11)。清單 5-11 中顯示的代碼示例摘自 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄中的 SSLClient.java
文件。
wlsUrl = new URL("https", host, Integer.valueOf(sport).intValue(),
query);
weblogic.net.http.HttpsURLConnection sconnection =
new weblogic.net.http.HttpsURLConnection(wlsUrl);
...
InputStream [] ins = new InputStream[2];
ins[0] = new FileInputStream("clientkey.pem");
ins[1] = new FileInputStream("client2certs.pem");
String pwd = "clientkey";
sconnection.loadLocalIdentity(ins[0], ins[1], pwd.toCharArray());
完整工作的 SSL 身份驗(yàn)證示例與 WebLogic Server 產(chǎn)品一起提供。此示例位于 SAMPLES_HOME\server\examples\src\examples\security\sslclient
目錄。有關(guān)此示例的描述,以及如何生成、配置和運(yùn)行此示例的說(shuō)明,請(qǐng)參閱示例目錄中的 package.html
文件??梢孕薷拇舜a示例,然后重新使用。
http://edocs.weblogicfans.net/wls/docs92/security/SSL_client.html
聯(lián)系客服