鍍金池/ 教程/ Linux/ SSL/TLS 配置
連接器
JSPs
重寫機(jī)制
CGI
Tomcat Manager
Windows 認(rèn)證
代理支持
虛擬主機(jī)
安全性注意事項(xiàng)
如何在 Maven 中使用 Tomcat 庫
安裝
MBean 描述符
JNDI 資源
類加載機(jī)制
Tomcat Web 應(yīng)用部署
基于 APR 的原生庫
負(fù)載均衡器
安全管理
附加組件
監(jiān)控與管理
Windows 服務(wù)
集群化與會話復(fù)制
高級 IO 機(jī)制
SSI(服務(wù)器端嵌入)
WebSocket 支持
JDBC 數(shù)據(jù)源
日志機(jī)制
默認(rèn) Servlet
SSL/TLS 配置
Tomcat 的 JDBC 連接池
第一個(gè)應(yīng)用
簡介
Realm 配置

SSL/TLS 配置

Quick Start

下列說明將使用變量名 $CATALINA_BASE 來表示多數(shù)相對路徑所基于的基本目錄。如果沒有為 Tomcat 多個(gè)實(shí)例設(shè)置 CATALINA_BASE 目錄,則 $CATALINA_BASE 就會設(shè)定為 $CATALINA_HOME 的值,也就是你安裝 Tomcat 的目錄。

在 Tomcat 中安裝并配置 SSL/TLS 支持,只需遵循下列幾步即可。詳細(xì)信息可參看文檔后續(xù)介紹。

  1. 創(chuàng)建一個(gè) keystore 文件保存服務(wù)器的私有密鑰和自簽名證書:
    Windows:
    "%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
    UNIX:
    $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

    指定密碼為“changeit”。

  2. 取消對 $CATALINA_BASE/conf/server.xml 中 “SSL HTTP/1.1 Connector” 一項(xiàng)的注釋狀態(tài)。按照下文中配置一節(jié)所描述的方式進(jìn)行修改。

SSL/TLS 簡介

安全傳輸層協(xié)議(TLS)與其前輩加密套接字(SSL)都是用于保證 Web 瀏覽器與 Web 服務(wù)器通過安全連接進(jìn)行通信的技術(shù)。利用這些技術(shù),我們所要傳送的數(shù)據(jù)會在一端進(jìn)行加密,傳輸?shù)搅硪欢撕笤龠M(jìn)行解密(在處理數(shù)據(jù)之前)。這是一種雙向的操作,服務(wù)器和瀏覽器都能在發(fā)送數(shù)據(jù)前對它們進(jìn)行加密處理。

SSL/TLS 協(xié)議的另一個(gè)重要方面是認(rèn)證。當(dāng)我們初始通過安全連接與 Web 服務(wù)器進(jìn)行通信時(shí),服務(wù)器將提供給 Web 瀏覽器一組“證書”形式的憑證,用來證明站點(diǎn)的歸屬方以及站點(diǎn)的具體聲明。某些情況下,服務(wù)器也會請求瀏覽器出示證書,來證明作為操作者的“你”所宣稱的身份是否屬實(shí)。這種證書叫做“客戶端證書”,但事實(shí)上它更多地用于 B2B(企業(yè)對企業(yè)電子商務(wù))的交易中,而并非針對個(gè)人用戶。大多數(shù)啟用了 SSL 協(xié)議的 Web 服務(wù)器都不需要客戶端認(rèn)證。

SSL/TLS 與 Tomcat

一定要注意的是,通常只有當(dāng) Tomcat 是獨(dú)立運(yùn)行的 Web 服務(wù)器時(shí),才有必要去配置 Tomcat 以便利用加密套接字。具體細(xì)節(jié)可參看 Security Considerations Document。當(dāng) Tomcat 以 Servlet/JSP 容器的形式在其他 Web 服務(wù)器(比如 Apache 或 Microsoft IIS)背后運(yùn)行時(shí),通常需要配置的是主 Web 服務(wù)器,用主服務(wù)器來處理與用戶的 SSL 連接。主服務(wù)器一般會利用所有的 SSL 相關(guān)功能,將任何只有 Tomcat 才能處理的請求進(jìn)行解密后再傳給 Tomcat。同樣,Tomcat 會返回明文形式的響應(yīng),這些響應(yīng)在被傳輸?shù)接脩魹g覽器之前會被主服務(wù)器進(jìn)行加密處理。在這種情境下,Tomcat 知道主服務(wù)器與客戶端的所有通信都是通過安全連接進(jìn)行的(因?yàn)閼?yīng)用要求),但 Tomcat 自身無法參與到加密與解密的過程中。

證書

為了實(shí)現(xiàn) SSL,Web 服務(wù)器必須對每一個(gè)接受安全連接的外部接口(IP 地址)配備相應(yīng)的證書。這種設(shè)計(jì)方式的理論在于,服務(wù)器必須提供某種可信的保證(尤其對于接收敏感信息而言),保證它的擁有者是你所認(rèn)為的角色。限于本章篇幅,不再贅述關(guān)于證書的詳細(xì)解釋,只需要把它認(rèn)為成是一種 IP 地址的“數(shù)字駕照”即可。它聲明了與站點(diǎn)相關(guān)的組織,以及一些關(guān)于站點(diǎn)擁有者或管理者的基本聯(lián)系信息。

這種“數(shù)字駕照”的持有者對其進(jìn)行了加密簽名,從而使得它極難偽造。對于參與電子商務(wù)的站點(diǎn)或者其他一些身份驗(yàn)證顯得非常重要的商業(yè)交易來說,證書通常都是從一些比較權(quán)威公正的 CA ( Certificate Authority,認(rèn)證機(jī)構(gòu))購買的,比較知名的 CA 有 VeriSign 、Thawte 等。這些證書可經(jīng)電子驗(yàn)證。實(shí)際上,CA 會保證所頒發(fā)證書的真實(shí)性,所以你完全可以放心。

不過,在很多情況下,驗(yàn)證并不是問題的關(guān)鍵。管理員可能只想保證服務(wù)器所傳輸與接收的數(shù)據(jù)是秘密的,不會被某些人通過連接來竊取。幸運(yùn)的是,Java 提供了一個(gè)簡單的命令行工具:keytool。它能輕松創(chuàng)建一個(gè)“自簽名”的證書,這種自簽名證書是由用戶生成的一種證書,未經(jīng)任何知名 CA 給予官方保證,因此它的真實(shí)性也無法確定。再說一次,是否認(rèn)證,完全根據(jù)你的需求。

運(yùn)行 SSL 通常需要注意的一些內(nèi)容

當(dāng)用戶首次訪問你站點(diǎn)上的安全頁面時(shí),頁面通常會提供給他一個(gè)對話框,包含證書相關(guān)細(xì)節(jié)(比如組織及聯(lián)系方式等),并且詢問他是否愿意承認(rèn)該證書為有效證書,然后再進(jìn)行下一步的事務(wù)。一些瀏覽器可能會提供一個(gè)選項(xiàng),允許永遠(yuǎn)承認(rèn)給出的證書的有效性,這樣就不會在用戶每次訪問站點(diǎn)時(shí)打擾他們了。但有些瀏覽器不會提供這種選項(xiàng)。一旦用戶承認(rèn)了證書的有效性,那么在整個(gè)的瀏覽器會話期間,證書都被認(rèn)為是有效的。

雖然 SSL 協(xié)議的意圖是盡可能有助于提供安全且高效的連接,但從性能角度來考慮,加密與解密是非茶館耗費(fèi)計(jì)算資源的,因此將整個(gè) Web 應(yīng)用都運(yùn)行在 SSL 協(xié)議下是完全沒有必要的,開發(fā)者需要挑選需要安全連接的頁面。對于一個(gè)相當(dāng)繁忙的網(wǎng)站來說,通常只會在特定頁面上使用 SSL 協(xié)議,也就是可能交換敏感信息的頁面,比如:登錄頁面、個(gè)人信息頁面、購物車結(jié)賬頁面(可能會輸入信用卡信息),等等。應(yīng)用中的任何一個(gè)頁面都可以通過加密套接字來請求訪問,只需將頁面地址的前綴 http: 換成 https: 即可。絕對需要安全連接的頁面應(yīng)該檢查該頁面請求所關(guān)聯(lián)的協(xié)議類型,如果發(fā)現(xiàn)沒有指定 https:,則采取適當(dāng)行為。

最后,在安全連接上使用基于名稱的虛擬主機(jī)可能會造成一定的問題。這正是 SSL 協(xié)議的局限。SSL 握手過程,即客戶端瀏覽器接收服務(wù)器證書,必須發(fā)生在 HTTP 請求被訪問前。因此包含虛擬主機(jī)名稱的請求信息不能先于認(rèn)證而確定,也不可能為單個(gè) IP 地址指定多個(gè)證書。如果單個(gè) IP 地址的所有虛擬主機(jī)都需要利用同樣證書來認(rèn)證的話,那么多個(gè)虛擬主機(jī)不應(yīng)該干涉服務(wù)器通常的 SSL 操作。但是要注意一點(diǎn),多數(shù)客戶端瀏覽器會將服務(wù)器域名與證書中的多個(gè)域名(如果存在的話,)進(jìn)行對比,如果域名出現(xiàn)不匹配,則瀏覽器會向用戶顯示警告信息。一般來說,生產(chǎn)環(huán)境中,通常只有使用基于地址的虛擬主機(jī)利用 SSL。

配置

1. 準(zhǔn)備證書密鑰存儲庫

Tomcat 目前只能操作 JKSPKCS11、PKCS12 格式的密鑰存儲庫。JKS 是 Java 標(biāo)準(zhǔn)的“Java 密鑰存儲庫”格式,是通過 keytool 命令行工具創(chuàng)建的。該工具包含在 JDK 中。PKCS12 格式一種互聯(lián)網(wǎng)標(biāo)準(zhǔn),可以通過 OpenSSL 和 Microsoft 的 Key-Manager 來。

密鑰存儲庫中的每一項(xiàng)都通過一個(gè)別名字符串來標(biāo)識。盡管許多密碼存儲庫實(shí)現(xiàn)都在處理別名時(shí)不區(qū)分大小寫,但區(qū)分大小寫的實(shí)現(xiàn)也是允許的。比如,PKCS11 規(guī)范需要?jiǎng)e名是區(qū)分大小寫的。為了避免別名大小寫敏感的問題,不建議使用只有大小寫不同的別名。

為了將現(xiàn)有的證書導(dǎo)入 JKS 密碼存儲庫,請查閱關(guān)于 keytool 的相關(guān)文檔(位于 JDK 文檔包里)。注意,OpenSSL 經(jīng)常會在密碼前加上易于理解的注釋,但 keytool 并不支持這一點(diǎn)。所以如果證書里的密碼數(shù)據(jù)前面有注釋的話,在利用 keytool 導(dǎo)入證書前,一定要清除它們。

要想把一個(gè)已有的由你自己的 CA 所簽名的證書導(dǎo)入使用 OpenSSL 的 PKCS12 密碼存儲庫,應(yīng)該執(zhí)行如下命令:

openssl pkcs12 -export -in mycert.crt -inkey mykey.key
                       -out mycert.p12 -name tomcat -CAfile myCA.crt
                       -caname root -chain   

更復(fù)雜的實(shí)例,請參考 OpenSSL 文檔的相關(guān)內(nèi)容。

下面這個(gè)實(shí)例展示的是如何利用終端命令行,從零開始創(chuàng)建一個(gè)新的 JKS 密碼存儲庫,該密碼庫包含一個(gè)自簽名的證書。

Windows:

"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

(RSA 算法應(yīng)該作為首選的安全算法,這同樣也能保證與其他服務(wù)器和組件的大體的兼容性。)

該命令將在用戶的主目錄下創(chuàng)建一個(gè)新文件:.keystore。要想指定一個(gè)不同的位置或文件名,可以在上述的 keytool 命令上添加 -keystore 參數(shù),后跟到達(dá) keystore 文件的完整路徑名。你還需要把這個(gè)新位置指定到 server.xml 配置文件上,見后文介紹。例如:

Windows:

"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA
  -keystore \path\to\my\keystore

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA  
  -keystore /path/to/my/keystore     

執(zhí)行該命令后,首先會提示你提供 keystore 的密碼。Tomcat 默認(rèn)使用的密碼是 changeit(全部字母都小寫),當(dāng)然你可以指定一個(gè)自定義密碼(如果你愿意)。同樣,你也需要將這個(gè)自定義密碼在 server.xml 配置文件內(nèi)進(jìn)行指定,稍后再予以詳述。

接下來會提示關(guān)于證書的一般信息,比如組織、聯(lián)系人名稱,等等。當(dāng)用戶試圖在你的應(yīng)用中訪問一個(gè)安全頁面時(shí),該信息會顯示給用戶,所以一定要確保所提供的信息與用戶所期望看到的內(nèi)容保持一致。

最后,還需要輸入密鑰密碼(key password),這個(gè)密碼是這一證書(而不是存儲在同一密碼存儲庫文件中的其他證書)的專有密碼。keytool 提示會告訴你,如果按下回車鍵,則自動使用密碼存儲庫 keystore 的密碼。當(dāng)然,除了這個(gè)密碼,你也可以自定義自己的密碼。如果選擇自定義密碼,那么不要忘了在 server.xml 配置文件中指定這一密碼。

如果操作全部正常,我們現(xiàn)在就會得到一個(gè)服務(wù)器能使用的有證書的密碼存儲庫文件。

2. 編輯 Tomcat 配置文件

Tomcat 能夠使用兩種 SSL 實(shí)現(xiàn):

  • JSSE 實(shí)現(xiàn),它是Java 運(yùn)行時(shí)(從 1.4 版本起)的一部分。
  • APR 實(shí)現(xiàn),默認(rèn)使用 OpenSSL 引擎。

詳細(xì)的配置信息依賴于所用的實(shí)現(xiàn)方式。如果通過指定通用的 protocol="HTTP/1.1" 來配置連接起,那么就會自動選擇 Tomcat 所要用到的實(shí)現(xiàn)方式。如果安裝使用的是 APR(比如你安裝了 Tomcat 的原生庫),那么它將使用 APR 的 SSL 實(shí)現(xiàn),否則就將使用 Java 所提供的 JSSE 實(shí)現(xiàn)。

由于這兩種 SSL 實(shí)現(xiàn)在 SSL 支持的配置屬性上有很大差異,所以強(qiáng)烈建議不要自動選擇實(shí)現(xiàn)方式。選擇實(shí)現(xiàn)應(yīng)該采取這種方式:在連接器protocol 屬性中,通過指定類名來確立實(shí)現(xiàn)方式。

定義 Java(JSSE)連接器,不管 APR 庫是否已經(jīng)加載,都可以使用下列方式:

<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO implementation -->
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="8443" .../>

<!-- Define a HTTP/1.1 Connector on port 8443, JSSE NIO2 implementation -->
<Connector protocol="org.apache.coyote.http11.Http11Nio2Protocol"
           port="8443" .../>

<!-- Define a HTTP/1.1 Connector on port 8443, JSSE BIO implementation -->
<Connector protocol="org.apache.coyote.http11.Http11Protocol"
           port="8443" .../>

另一種方法,指定 APR 連接器(APR 庫必須可用),則使用:

<!-- Define a HTTP/1.1 Connector on port 8443, APR implementation -->
<Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="8443" .../>

如果使用 APR,則會出現(xiàn)一個(gè)選項(xiàng),從而可以配置另一種 OpenSSL 引擎。

<Listener className="org.apache.catalina.core.AprLifecycleListener"
          SSLEngine="someengine" SSLRandomSeed="somedevice" />

默認(rèn)值為:

<Listener className="org.apache.catalina.core.AprLifecycleListener"
          SSLEngine="on" SSLRandomSeed="builtin" />

所以要想使用 APR 實(shí)現(xiàn),一定要確保 SSLEngine 屬性值不能為 off。該屬性值默認(rèn)為 on,如果指定的是其他值,它也會成為一個(gè)有效的引擎名稱。

SSLRandomSeed 屬性指定了一個(gè)熵源。生產(chǎn)系統(tǒng)需要可靠的熵源,但熵可能需要大量時(shí)間來采集,因此測試系統(tǒng)會使用非阻塞的熵源,比如像“/dev/urandom”,從而能夠更快地啟動 Tomcat。

最后一步是在 $CATALINA_BASE/conf/server.xml 中配置連接器,$CATALINA_BASE 表示的是 Tomcat 實(shí)例的基本目錄。Tomcat 安裝的默認(rèn) server.xml 文件中包含一個(gè)用于 SSL 連接器的 <Connector> 元素的范例。為了配置使用 JSSE 的 SSL 連接器,你可能需要清除注釋并按照如下的方式來編輯它。

<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="${user.home}/.keystore" keystorePass="changeit"
           clientAuth="false" sslProtocol="TLS"/>

APR 連接器會使用很多不同的屬性來設(shè)置 SSL,特別是密鑰和證書。 APR 配置范例如下:

<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
           protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="8443" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           SSLCertificateFile="/usr/local/ssl/server.crt"
           SSLCertificateKeyFile="/usr/local/ssl/server.pem"
           SSLVerifyClient="optional" SSLProtocol="TLSv1+TLSv1.1+TLSv1.2"/>

每個(gè)屬性所用的配置信息與選項(xiàng)都是強(qiáng)制的,可查看 HTTP 連接器配置參考文檔中的 SSL 支持部分。一定要確保對所使用的連接器采用正確的屬性。BIO、NIO 以及 NIO2 連接器都使用 JSSE,然而APR以及原生的連接器則使用 APR。

port屬性指的是 Tomcat 用以偵聽安全連接的 TCP/IP 端口號。你可以隨意改變它,比如改成 https 的默認(rèn)端口號 443。但是在很多操作系統(tǒng)中,在低于 1024 的端口上運(yùn)行 Tomcat 必須進(jìn)行一番特殊的配置,限于篇幅,本文檔不再贅述。

如果在這里,你更改了端口號,那么也應(yīng)該在 非 SSL 連接器的 redirectPort 屬性值。從而使 Tomcat 能夠根據(jù) Servlet 規(guī)范,自動對訪問帶有安全限制(指定需要 SSL)頁面的用戶進(jìn)行重定向。

配置完全部信息后,你應(yīng)該像往常一樣,重新啟動 Tomcat,從而能夠利用 SSL 來訪問任何 Tomcat 所支持的 Web 應(yīng)用了。比如:

https://localhost:8443/

你將看到跟往常一樣的 Tomcat 主頁面(除非你修改了 ROOT 應(yīng)用)。如果出現(xiàn)問題,這樣做沒有任何效果,請看下面的故障排除小節(jié)。

從 CA 處安裝證書

如果想從 CA(比如 verisign.com、thawte.com、trustcenter.de)處獲取并安裝證書,請閱讀之前的內(nèi)容,然后按照下列操作進(jìn)行:

創(chuàng)建一個(gè)本地證書簽名請求(CSR)

為了從選擇的 CA 處獲取證書,必須創(chuàng)建一個(gè)證書簽名請求(CSR)。CA 通過 CSR 來創(chuàng)建出一個(gè)證書,用來證明你的網(wǎng)站是“安全的”。創(chuàng)建 CSR 的步驟如下:

  • 創(chuàng)建一個(gè)本地自簽名證書(如前文所述):
    keytool -genkey -alias tomcat -keyalg RSA
    -keystore <your_keystore_filename>
注意:在某些情況下,為了創(chuàng)建一個(gè)能耐生效的證書,你必須在“first- and lastname”字段中輸入網(wǎng)站的域名(比如:`www.myside.org`)。
  • 然后利用下列代碼創(chuàng)建 CSR:
    keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr
    -keystore <your_keystore_filename>

現(xiàn)在,我們得到了一個(gè) certreq.csr 的文件,可以把它提交給 CA 了(CA 的網(wǎng)站上應(yīng)有關(guān)于如何提交的文檔),審核通過后就會收到一個(gè)證書。

導(dǎo)入證書

接下來可以把證書導(dǎo)入到本地密鑰存儲庫中。首先你需要把鏈證書(Chain Certificate)或根證書(Root Certificate)導(dǎo)入到密鑰存儲庫中。然后繼續(xù)導(dǎo)入證書。

    keytool -import -alias root -keystore <your_keystore_filename>
    -trustcacerts -file <filename_of_the_chain_certificate>
  • 最后導(dǎo)入你的新證書:
    keytool -import -alias tomcat -keystore <your_keystore_filename>
    -file <your_certificate_filename>

疑難排解

以下列出了一些在設(shè)置 SSL 通信時(shí)經(jīng)常會遇到的問題及其解決方法:

  • 當(dāng) Tomcat 啟動時(shí),出現(xiàn)這樣的異常信息:“ava.io.FileNotFoundException: {some-directory}/{some-file} not found.”

    這很有可能是因?yàn)?Tomcat 無法在指定位置處找到密鑰存儲庫。默認(rèn)情況下,密鑰存儲庫文件應(yīng)以 .keystore 為后綴,位于用戶的 home 目錄下(也許很你的設(shè)置不同)。如果密鑰存儲庫文件在別處,則需要在 Tomcat 配置文件<Factory> 元素中添加一個(gè) keystoreFile 屬性。

  • 當(dāng) Tomcat 啟動時(shí),出現(xiàn)這樣的異常信息:“java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect.”

    假如排除了有人惡意篡改密鑰存儲庫文件的因素,那么出現(xiàn)這樣的異常,最有可能是因?yàn)?Tomcat 現(xiàn)在所用的密碼不同于你當(dāng)初創(chuàng)建密鑰存儲庫文件時(shí)所用密碼。為了解決這個(gè)問題,你可以重新創(chuàng)建密鑰存儲庫文件,或者在 Tomcat 配置文件<Connector> 元素中添加或更新一個(gè) keystoreFile 屬性。注意:密碼都是區(qū)分大小寫的。

  • 當(dāng) Tomcat 啟動時(shí),出現(xiàn)這樣的異常:“java.net.SocketException: SSL handshake error javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled.”

    出現(xiàn)這樣的異常,很有可能是因?yàn)?Tomcat 無法在指定的密鑰存儲庫中找到服務(wù)器密鑰的別名。查看一下 Tomcat 配置文件<Connector> 元素中所指定的 keystoreFilekeyAlias 值是否正確。注意keyAlias 值可能區(qū)分大小寫。

如果出現(xiàn)了其他問題,可以求助 TOMCAT-USER 郵件列表,你可以在該郵件列表內(nèi)找到之前消息的歸檔文件,以及訂閱和取消訂閱的相關(guān)信息。Tomcat 郵件列表的鏈接是:http://tomcat.apache.org/lists.html。

在應(yīng)用中使用 SSL 跟蹤會話

這是一個(gè) Servlet 3.0 規(guī)范中的新功能。由于它將 SSL 會話 ID 關(guān)聯(lián)到物理的客戶端服務(wù)器連接上,所以導(dǎo)致了一些約束與局限:

  • Tomcat 必須有一個(gè)屬性 isSecure 設(shè)為 true 的連接器。
  • 如果 SSL 連接器通過代理或硬件加速器來管理,則它們必須填充 SSL 請求報(bào)頭(參見 SSLValve),從而使 SSL 會話 ID 可見于 Tomcat。
  • 如果 Tomcat 終止了 SSL 連接,則不可能采用會話重復(fù),因?yàn)?SSL 會話 ID 在兩個(gè)端點(diǎn)處都是不一樣的。

為了開啟 SSL 會話跟蹤,只需使用上下文偵聽器將上下文的跟蹤模式設(shè)定為 SSL 即可(如果還開啟了其他跟蹤模式,則會優(yōu)先使用它)。如下所示:

package org.apache.tomcat.example;

import java.util.EnumSet;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.SessionTrackingMode;

public class SessionTrackingModeListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        // Do nothing
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        ServletContext context = event.getServletContext();
        EnumSet<SessionTrackingMode> modes =
            EnumSet.of(SessionTrackingMode.SSL);

        context.setSessionTrackingModes(modes);
    }

}

注意:SSL 會話跟蹤是針對 BIO、NIO 以及 NIO2 連接器來實(shí)現(xiàn)的,目前還沒有針對 APR 連接器的實(shí)現(xiàn)。

其他技巧

要想從請求中訪問 SSL 會話 ID,可使用:

String sslID = (String)request.getAttribute("javax.servlet.request.ssl_session_id");

關(guān)于這一方面的其他內(nèi)容,可參看Bugzilla

為了終止 SSL 會話,可以使用:

// Standard HTTP session invalidation
session.invalidate();

// Invalidate the SSL Session
org.apache.tomcat.util.net.SSLSessionManager mgr =
    (org.apache.tomcat.util.net.SSLSessionManager)
    request.getAttribute("javax.servlet.request.ssl_session_mgr");
mgr.invalidateSession();

// Close the connection since the SSL session will be active until the connection
// is closed
response.setHeader("Connection", "close");

注意:由于使用了 SSLSessionManager 類,所以這段代碼是專門針對 Tomcat 的。當(dāng)前只適用于 BIO、NIO 以及 NIO2 連接器,不適合 APR/原生連接器。