總結主要來源于網上的一些文章和論壇的記錄以及我自已的一些想法.
CAS (Central Authentication Service) 是 Yale 大學的 ITS 開發的一套 JAVA 實現的開源
的 SSO(single sign-on) 的服務(主要是2.0,到3.0為ja-sig)。
關鍵字
TGC(ticket-granting cookie)--------- 受權的票據證明
KDC( Key Distribution Center ) ---------- 密鑰發放中心
Service ticket(ST) --------- 服務票據, 由 KDC 的 TGS 發放。 任何一臺 Workstation 都需要擁有一張有效的 Service Ticket 才能訪問域內部的應用 (Applications) 。 如果能正確接收 Service Ticket ,說明在 CASClient-CASServer 之間的信任關系已經被正確建立起來 , 通常為一張數字加密的證書
Ticket Granting tieckt(TGT) --------- 票據授權票據,由 KDC 的 AS 發放。即獲取這樣一張票據后,以后申請各種其他服務票據 (ST) 便不必再向 KDC 提交身份認證信息 ( 準確術語是 Credentials) 。
authentication service (AS) --------- 認證用服務,索取 Crendential ,發放 TGT
ticket-granting service (TGS) --------- 票據授權服務,索取 TGT ,發放 ST
CAS 單點服務器的認證過程,所有應用服務器收到應用請求后,檢查 ST 和 TGT ,如果沒有或不對,轉到 CAS 認證服務器登陸頁面,通過安全認證后得到 ST 和 TGT 再重定向到相關應用服務器,在會話生命周期之內如果再定向到別的應用,將出示
ST 和 TGT 進行認證 , 注意 , 取得 TGT 的過程是通過 SSL 安全協議的 ( 換句話說就是如果不用 ssl 協議 , 每訪問一個應用服務,就得重新到認證服務中心認證一次 ) ,關于 SSL 的相關描述可以查看附錄 .
白話描述 :
單點登陸 , 無非就是提供給用戶一次登陸 , 多個系統共享用戶信息的操作 .
這個是怎么操作的呢 ? 有簡單的方法 , 當用戶訪問其他系統的時候 , 寫個 URL 帶上用戶的 ID 和 PASS 提交到相應的系統就可以了 . 這也是一種方法
那 CAS 是怎么操作的呢 ? 或則是 KRB(Kerberos 是一個加密認證協議,允許網絡用戶不使用明文密碼訪問服務,一個普通
的協議實現包括 LOGIN 服務存在偽造欺騙對 Key Distribution Center 的響應 。
) 怎么操作的呢 ?
他并不是很復雜 , 他先是建立一個 專門認證用戶的 服務 (SERVER) 這個服務只做一件事 , 負責驗證用戶的 ID 和 PASS 是否是正確 , 在正確的情況提供用戶一個名為 TGT 的票據 ,
相當你要去游樂場玩 , 首先你要在門口檢查你的身份 ( 即 CHECK 你的 ID 和 PASS), 如果你通過驗證 , 游樂場的門衛 (AS) 即提供給你一張門卡 (TGT).
這張卡片的用處就是告訴 游樂場的各個場所 , 你是通過正門進來 , 而不是后門偷爬進來的 , 并且也是獲取進入場所一把鑰匙 .
好的 , 現在你有張卡 , 但是這對你來不重要 , 因為你來游樂場不是為了拿這張卡的 , 好的 , 我們向你的目的出發 , 恩 , 你來到一個摩天樓 , 你想進入玩玩 ,
這時摩天輪的服務員 (client) 攔下你 , 向你要求摩天輪的 (ST) 票據 , 你說你只有一個門卡 (TGT), 好的 , 那你只要把 TGT 放在一旁的票據授權機 (TGS) 上刷一下 ,
票據授權機 (TGS) 就根據你現在所在的摩天輪 , 給你一張摩天輪的票據 (ST), 哈 , 你有摩天輪的票據 , 現在你可以暢通無阻的進入摩天輪里游玩了 .
當然如果你玩完摩天輪后 , 想去游樂園的咖啡廳休息下 , 那你一樣只要帶著那張門卡 (TGT). 到相應的咖啡廳的票據授權機 (TGS) 刷一下 , 得到咖啡廳的票據 (ST) 就可以進入咖啡廳
當你離開游樂場后 , 想用這張 TGT 去刷打的回家的費用 , 呵呵 , 對不起 , 你的 TGT 已經過期了 , 在你離開游樂場那刻開始 , 你的 TGT 就已經銷毀了 ~
Yale CAS Server 的配置過程
CAS (Central Authentication Service) 是 Yale 大學的 ITS 開發的一套 JAVA 實現的開源
的 SSO(single sign-on) 的服務。該服務是以一個 java web app(eg:cas.war) 來進行服務的,
使用時需要將 cas.war 發布到一個 servlet2.3 兼容的服務器上,并且服務器需要支持 SSL ,
在需要使用該服務的其他服務器(客戶),只要進行簡單的配置就可以實現 SSO 了。
CAS 的客戶端可以有很多種,因為驗證的結果是以 XML 的格式返回的, CAS 的客戶端已
打包進去的有 java,perl,python,asp,apache module 等好幾種客戶端示例,你還可以根據
需要實現一個自己的客戶端,非常簡單 !~
下面我們以 tomcat 5.0 作為 CAS Server(server1) ,另外一臺 tomcat5.0 為 client(client1)
為例進行說明。
1. 下載 cas-server 和 cas-client( 可選,建議使用)
http://www.ja-sig.org/downloads/cas/cas-server-3.0.5.zip
http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.zip
2. 將 cas-server-3.0.5.zip 解壓,并將 lib/cas.war 拷貝到 server1 的 webapps 下
3. 產生 SERVER 的證書
PS: 參數與各系統本身一致
%JAVA_HOME%\bin\keytool -delete -alias tomcat -keypass changeit
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keypass changeit -keyalg RSA
%JAVA_HOME%\bin\keytool -export -alias tomcat -keypass changeit? -file %FILE_NAME%
%JAVA_HOME%\bin\keytool -import -file server.crt -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts
%JAVA_HOME%\bin\keytool -import -file server.crt -keystore %JAVA_HOME%\jre\lib\security\cacerts
4. 在 server1 配置 tomcat 使用 HTTPS
$CATALINA_HOME/conf/server.xml 里
<Connector className="org.apache.coyote.tomcat5.CoyoteConnector"
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https"
secure="true">
<Factory className="org.apache.coyote.tomcat5.CoyoteServerSocketFactory"
keystoreFile="/path/to/your/keystore-file"
keystorePass="your-password" clientAuth="false" protocol="TLS" />
</Connector>
5. 在要使用 CAS 的客戶端 client1 里設置(以 servlets-examples 這個 APP 為例),我們使用
ServletFilter(CAS client 里提供的 ) 來實現 SSO 的檢查。
修改 servlets-examples/WEB-INF/web.xml
<filter>
<filter-name>CASFilter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
<param-value>https://your.cas.server.name(eg:server1):port/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://your.cas.server.name(eg:server1):port/cas/proxyValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serviceUrl</param-name>
<param-value>your.client.server.ip(eg:127.0.0.1):port</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CASFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
PS: 在 client 端配置 filter 時 , 需要將 CAS 的 filter 放在 web.xml 最上端 ,. 如果在你的 web.xml 有類似 encodingFilter 的 filter 也需要將這個 filter 放在 CAS filter 下面 , 否則你會發現每次訪問時都需要你進行驗證 .
6. 將 cas-client-java-2.1.1.zip 解壓,把 java/lib/casclient.jar 拷貝到 client1 服務器上的
webapps/servlets-examples/WEB-INF/lib 目錄下(如果沒有就建一個)
7. 導出 SERVER 的證書,用來給所有需要用到的客戶端導入
keytool -export -file server.crt -alias my-alias-name -keystore keystore-file
8. 在客戶端的 JVM 里導入信任的 SERVER 的證書 ( 根據情況有可能需要管理員權限 )
keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file server.crt -alias my-alias-name
9.test & done.
把 server1 和 client1 分別起來,檢查啟動的 LOG 是否正常,如果一切 OK ,就訪問
http://client1:8080/servlets-examples/servlet/HelloWorldExample
系統會自動跳轉到一個驗證頁面,隨便輸入一個相同的賬號 , 密碼,嚴正通過之后就會訪問
到真正的 HelloWorldExample 這個 servlet 了
實現自已的認證代碼 (java 代碼和相關注釋 , 需要 cas-server-3.0.5.jar 包 )
?
package
?com.mcm.sso;?

?

import
?org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;?

import
?org.jasig.cas.authentication.principal.UsernamePasswordCredentials;?

import
?org.springframework.util.StringUtils;?

?

public
?
class
?MyUsernamePasswordAuthenticationHandler?
extends
?


??????????????AbstractUsernamePasswordAuthenticationHandler?
{?

?

???????
public
?
boolean
?authenticateUsernamePasswordInternal(?


?????????????????????
final
?UsernamePasswordCredentials?credentials)?
{?

??????????????
final
?String?username?
=
?credentials.getUsername();?

??????????????
final
?String?password?
=
?credentials.getPassword();?

??????????????

??????????????
//
?此處實現你的登陸驗證代碼?
??????????????
if
?(StringUtils.hasText(username)?
&&
?StringUtils.hasText(password)?)?
{?

?????????????????????getLog().debug(?

???????????????????????????????????
"
User?[
"
?
+
?username?
+
?
"
]?was?successfully?authenticated?with?ucix.
"
);?

?????????????????????
return
?
true
;?

??????????????}
?

?

??????????????getLog().debug(
"
User?[
"
?
+
?username?
+
?
"
]?failed?authentication
"
);?

?

??????????????
return
?
false
;?

???????}
?

?


???????
protected
?
void
?afterPropertiesSetInternal()?
throws
?Exception?
{?

??????????????
super
.afterPropertiesSetInternal();?

???????}
?

}
?

?
然后將這個類配置到 deployerConfigContext.xml 文件里 , 替代 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
可能要用到數據庫連接之類的配置,具體可參照 spring framework 相關文檔
在 client 端取到登陸相關信息及登出系統
1. 取得用用戶 ID
以下兩種方式都可以
session.getAttribute(CASFilter.CAS_FILTER_USER);
session.getAttribute("edu.yale.its.tp.cas.client.filter.user");
也可以直接取得認證 java 對象
session.getAttribute(CASFilter.CAS_FILTER_RECEIPT);
session.getAttribute("edu.yale.its.tp.cas.client.filter.receipt");
JSP2.0 標準寫法
<c:out value="${sessionScope['edu.yale.its.tp.cas.client.filter.user']}"/>
在 jsp 中使用 CAS Tag Library 標簽
除實現以上功能完還可以實現登出之類的相關功能,具體參照 cas 官方文檔
http://www.ja-sig.org/products/cas/client/jsp/index.html
附錄
1 . SSL(Server Socket Layer) 簡介
在網絡上信息在源 - 宿的傳遞過程中會經過其它的計算機。一般情況下,中間的計算機不會監聽路過的信息。但在使用網上銀行或者進行信用卡交易的時候有可能被監視,從而導致個人隱私的泄露。由于 Internet 和 Intranet 體系結構的原因,總有某些人能夠讀取并替換用戶發出的信息。隨著網上支付的不斷發展,人們對信息安全的要求越來越高。因此 Netscape 公司提出了 SSL 協議,旨在達到在開放網絡 (Internet) 上安全保密地傳輸信息的目的,這種協議在 WEB 上獲得了廣泛的應用。 之后 IETF(ietf.org) 對 SSL 作了標準化,即 RFC2246 ,并將其稱為 TLS ( Transport Layer Security ),從技術上講, TLS1.0 與 SSL3.0 的差別非常微小。
2 . SSL 工作原理
SSL 協議使用不對稱加密技術實現會話雙方之間信息的安全傳遞。可以實現信息傳遞的保密性、完整性,并且會話雙方能鑒別對方身份。不同于常用的 http 協議,我們在與網站建立 SSL 安全連接時使用 https 協議,即采用 https://ip:port/ 的方式來訪問。當我們與一個網站建立 https 連接時,我們的瀏覽器與 Web Server 之間要經過一個握手的過程來完成身份鑒定與密鑰交換,從而建立安全連接。具體過程如下:
用戶瀏覽器將其 SSL 版本號、加密設置參數、與 session 有關的數據以及其它一些必要信息發送到服務器。
服務器將其 SSL 版本號、加密設置參數、與 session 有關的數據以及其它一些必要信息發送給瀏覽器,同時發給瀏覽器的還有服務器的證書。如果配置服務器的 SSL 需要驗證用戶身份,還要發出請求要求瀏覽器提供用戶證書。
客戶端檢查服務器證書,如果檢查失敗,提示不能建立 SSL 連接。如果成功,那么繼續。客戶端瀏覽器為本次會話生成 pre-master secret ,并將其用服務器公鑰加密后發送給服務器。如果服務器要求鑒別客戶身份,客戶端還要再對另外一些數據簽名后并將其與客戶端證書一起發送給服務器。
如果服務器要求鑒別客戶身份,則檢查簽署客戶證書的 CA 是否可信。如果不在信任列表中,結束本次會話。如果檢查通過,服務器用自己的私鑰解密收到的 pre-master secret ,并用它通過某些算法生成本次會話的 master secret 。
客戶端與服務器均使用此 master secret 生成本次會話的會話密鑰 ( 對稱密鑰 ) 。在雙方 SSL 握手結束后傳遞任何消息均使用此會話密鑰。這樣做的主要原因是對稱加密比非對稱加密的運算量低一個數量級以上,能夠顯著提高雙方會話時的運算速度。
客戶端通知服務器此后發送的消息都使用這個會話密鑰進行加密。并通知服務器客戶端已經完成本次 SSL 握手。
服務器通知客戶端此后發送的消息都使用這個會話密鑰進行加密。并通知客戶端服務器已經完成本次 SSL 握手。
本次握手過程結束,會話已經建立。雙方使用同一個會話密鑰分別對發送以及接受的信息進行加、解密。
?