環(huán)境篇
一、所需軟件Jdk:jdk1.6.0_13 Apache:httpd-2.2.15-win32-x86-openssl-0.9.8m-r2 Tomcat:apache-tomcat-6.0.10 jks2pfx:證書導(dǎo)出工具http://www./download/jks2pfx.zip memcache:memcached-1.2.1-win32(需要memcache集群環(huán)境)
二、安全證書生成1、keytool Apache、tomcat、jdk需要使用安全證書,進windows command窗口生成證書,命令如下: --生成證書庫 keytool -genkey -alias 800jit -keyalg RSA -keystore d:/cert/800jitkey --從證書庫中到處證書 keytool -export -file d:/cert/800jit.crt -alias 800jit -keystore d:/cert/800jitkey --把證書導(dǎo)入jdk的證書庫 keytool -import -keystore d: /jdk1.6.0_13/jre/lib/security/cacerts -file d:/cert/800jit.crt -alias 800jit --生成Apache服務(wù)器的SSL連接需要配置私鑰文件和證書文件 D:\casex\jks2pfx>JKS2PFX.bat .keystore 800jitkey tomcat server_dev00 生成的server_dev00.crt,server_dev00.key放到D:/work/Apache2.2/conf/
2、openssl openssl req -config ..\conf\openssl.cnf -new -out olymtech.csr openssl rsa -in privkey.pem -out olymtech.key openssl x509 -in olymtech.csr -out olymtech.cert -req -signkey olymtech.key -days 3650 openssl x509 -in olymtech.cert -out olymtech.der.crt -outform DER keytool -import -keystore d:/work/jdk1.6.0_13/jre/lib/security/cacerts -file d:/casex/ssl/olymtech.crt -alias olymtech keytool -import -keystore D:/casex/800jitkey -file D:/casex/cas-doc/ssl/olymtech.crt -alias olymtech
三、Apache配置Apache+ssl+虛擬機 --修改http.conf文件 取消注釋 LoadModule ssl_module modules/mod_ssl.so 取消注釋 Include conf/extra/httpd-ssl.conf 取消注釋 Include conf/extra/httpd-vhosts.conf
ProxyPass /cas balancer://cas lbmethod=bytraffic stickysession=jsessionid <proxy balancer://cas/> BalancerMember ajp://192.168.1.190:10009/cas loadfactor=1 route=jvm1 BalancerMember ajp://192.168.1.190:8009/cas loadfactor=1 route=jvm2 </proxy>
--修改httpd-ssl.conf 在<VirtualHost _default_:443>下增加 ProxyPass /cas balancer://cas/ lbmethod=bytraffic stickysession=jsessionid ProxyPassReverse /cas balancer://cas/ SSLProxyEngine On
修改 SSLCertificateFile "D:/work/Apache2.2/conf/server_dev00.crt" SSLCertificateKeyFile "D:/work/Apache2.2/conf/server_dev00.key"
--修改httpd-vhosts.conf 在<VirtualHost *:80>下增加 ProxyPass /cas balancer://cas/ lbmethod=bytraffic stickysession=jsessionid ProxyPassReverse /cas balancer://cas/
四、Tomcat配置修改server.xml --配置ssl <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="d:/work/apache-tomcat-6.0.10/conf/800jitkey" keystorePass="111111" />
五、session共享(Tomcat)六、memcache集群
CAS SERVER篇一、CAS 原理介紹 訪問流程圖
主要原理:用戶第一次訪問一個CAS 服務(wù)的客戶web 應(yīng)用時(訪問URL :http://192.168.1.90:8081/web1 ),部署在客戶web 應(yīng)用的cas AuthenticationFilter ,會截獲此請求,生成service 參數(shù),然后redirect 到CAS 服務(wù)的login 接口,url為https://cas:8443/cas/login?service=http%3A%2F%2F192.168.1.90%3A8081%2Fweb1%2F ,認證成功后,CAS 服務(wù)器會生成認證cookie ,寫入瀏覽器,同時將cookie 緩存到服務(wù)器本地,CAS 服務(wù)器還會根據(jù)service 參數(shù)生成ticket,ticket 會保存到服務(wù)器,也會加在url 后面,然后將請求redirect 回客戶web 應(yīng)用,url 為http://192.168.1.90:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZuMwnbMvxpCBcNAIi6-20 。這時客戶端的AuthenticationFilter 看到ticket 參數(shù)后,會跳過,由其后面的TicketValidationFilter 處理,TicketValidationFilter 會利用httpclient 工具訪問cas 服務(wù)的/serviceValidate 接口, 將ticket 、service 都傳到此接口,由此接口驗證ticket 的有效性,TicketValidationFilter 如果得到驗證成功的消息,就會把用戶信息寫入web 應(yīng)用的session里。至此為止,SSO 會話就建立起來了,以后用戶在同一瀏覽器里訪問此web 應(yīng)用時,AuthenticationFilter 會在session 里讀取到用戶信息,所以就不會去CAS 認證,如果在此瀏覽器里訪問別的web 應(yīng)用時,AuthenticationFilter 在session 里讀取不到用戶信息,會去CAS 的login 接口認證,但這時CAS 會讀取到瀏覽器傳來的cookie ,所以CAS 不會要求用戶去登錄頁面登錄,只是會根據(jù)service 參數(shù)生成一個ticket ,然后再和web 應(yīng)用做一個驗證ticket 的交互。
二、CAS 服務(wù)端的處理邏輯CAS 服務(wù)端總共對外定義了9 個接口,客戶端通過訪問這9 個接口與服務(wù)端交互,這9個接口為:
詳細說明: /login: 登錄流程這部分要考慮到不同種類用戶憑證的獲取方案,以及客戶應(yīng)用傳來的service 、gateway 、renew 參數(shù)的不同取值組合,CAS 為了實現(xiàn)流程的高度可配置性,采用了Spring Web Flow 技術(shù)。通過CAS 發(fā)布包里的login-webflow.xml 、cas-servlet.xml 、applicationContext.xml 這3 個文件,找出 了登錄有關(guān)的所有組件,畫出處理流程圖。 CAS 默認的登錄處理流程 第一次訪問Web 應(yīng)用的流程走向 已經(jīng)登錄web1 后,訪問web1 的資源(web1 沒有啟動session ),或訪問web2 的資源
注: 1 : InitialFlowSetupAction: 是流程的入口。用 request.getContextPath() 的值來設(shè)置 cookie 的 Path 值, Cookie 的 path 值是在配置文件里定義的,但這個 Action 負責將 request.getContextPath() 的值設(shè)置為 Cookie 的 path 值,這是在 cas 部署環(huán)境改變的情況下,靈活地設(shè)置 cookie path 的方式;把 cookie 的值以及 service 參數(shù)的值放入 requestContext 的 flowscope 里。 2 : GenerateServiceTicketAction 此 Action 負責根據(jù) service 、 GTC cookie 值生成 ServiceTicket 對象, ServiceTicket 的 ID 就是返回給客戶應(yīng)用的 ticket 參數(shù),如果成功創(chuàng)建 ServiceTicket ,則轉(zhuǎn)發(fā)到 WarnAction ,如果創(chuàng)建失敗,且 gateway 參數(shù)為 true ,則直接redirect 到客戶應(yīng)用, 否則則需要重新認證。 3 : viewLoginForm 這是登錄頁面, CAS 在此收集用戶憑證。 CAS 提供的默認實現(xiàn)是 /WEB-INF/view/jsp/simple/ui/casLoginView.jsp 。 4 : bindAndValidate 對應(yīng) AuthenticationViaFormAction 的 doBind 方法,該方法負責搜集登錄頁面上用戶錄入的憑證信息(用戶名、密碼等),然后把這些信息封裝到 CAS 內(nèi)部的 Credentials 對象中。用戶在 casLoginView.jsp 頁面上點擊提交后,會觸發(fā)此方法。 5:submit 對應(yīng) AuthenticationViaFormAction 的 submit 方法 , 如果 doBind 方法成功執(zhí)行完, 則觸發(fā) submit 方法,此方法負責調(diào)用centralAuthenticationService 的 grantServiceTicket 方法,完成認證工作,如果認證成功,則生成 TicketGrantingTicket 對象,放在緩存里, TicketGrantingTicket 的 ID 就是 TGC Cookie 的 value 值。 6 : warn CAS 提供了一個功能:用戶在一個 web 應(yīng)用中跳到另一個 web 應(yīng)用時, CAS 可以跳轉(zhuǎn)到一個提示頁面,該頁面提示用戶要離開一個應(yīng)用進入另一個應(yīng)用,可以讓用戶自己選擇。用戶在登錄頁面 viewLoginForm 上選中了 id=”warn” 的復(fù)選框,才能開啟這個功能。 WarnAction 就檢查用戶有沒有開啟這個功能,如果開啟了,則轉(zhuǎn)發(fā)到showWarnView, 如果沒開啟,則直接redirect 到客戶應(yīng)用。 7 :SendTicketGrantingTicketAction 此Action 負責為response 生成TGC Cookie ,cookie 的值就是 AuthenticationViaFormAction 的submit 方法生成的 TicketGrantingTicket 對象的 ID 。 8 : viewGenerateLoginSuccess 這是 CAS 的認證成功頁面。
/logout: ( 對應(yīng)實現(xiàn)類 org.jasig.cas.web.LogoutController ) 處理邏輯: 1) removeCookie 2) 在服務(wù)端刪除TicketGrantingTicket 對象(此對象封裝了cookie 的value 值) 3 )redirect 到退出頁面,有2 種選擇: if(LogoutController 的followServiceRedirects 屬性為true 值,且url 里的service 參數(shù)非空){ redirect 到 sevice 參數(shù)標識的url } else{ redirect 到內(nèi)置的casLogoutView (cas/WEB-INF/view/jsp/default/ui/casLogoutView.jsp ),如果url 里有url 參數(shù),則此url 參數(shù)標識的鏈接會顯示在casLogoutView 頁面上。 }
/serviceValidate: (對應(yīng)實現(xiàn)類 org.jasig.cas.web.ServiceValidateController ) 處理邏輯: 如果service 參數(shù)為空或ticket 參數(shù)為空,則轉(zhuǎn)發(fā)到failureView (/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationFailure.jsp ) 驗證ticket 。以ticket 為參數(shù),去緩存里找ServiceTicketImpl 對象,如果能找到,且沒有過期,且ServiceTicketImpl 對象對應(yīng)的service 屬性和service 參數(shù)對應(yīng),則驗證通過,驗證通過后,請求轉(zhuǎn)發(fā)至casServiceSuccessView (cas/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationSuccess.jsp ),驗證不通過,則轉(zhuǎn)發(fā)到failureView 。
三、認證相關(guān)的概念及流程概念
序列圖
類圖
四、Ticket介紹CAS的核心就是其Ticket,及其在Ticket之上的一系列處理操作。CAS的主要票據(jù)有TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0協(xié)議中就有的票據(jù),PGT、PGTIOU、PT是CAS2.0協(xié)議中有的票據(jù)。
一 名詞解釋
TGT是CAS為用戶簽發(fā)的登錄票據(jù),擁有了TGT,用戶就可以證明自己在CAS成功登錄過。TGT封裝了Cookie值以及此Cookie值對應(yīng)的用戶信息。用戶在CAS認證成功后,CAS生成cookie,寫入瀏覽器,同時生成一個TGT對象,放入自己的緩存,TGT對象的ID就是cookie的值。當HTTP再次請求到來時,如果傳過來的有CAS生成的cookie,則CAS以此cookie值為key查詢緩存中有無TGT ,如果有的話,則說明用戶之前登錄過,如果沒有,則用戶需要重新登錄。
ST是CAS為用戶簽發(fā)的訪問某一service的票據(jù)。用戶訪問service時,service發(fā)現(xiàn)用戶沒有ST,則要求用戶去CAS獲取ST。用戶向CAS發(fā)出獲取ST的請求,如果用戶的請求中包含cookie,則CAS會以此cookie值為key查詢緩存中有無TGT,如果存在TGT,則用此TGT簽發(fā)一個ST,返回給用戶。用戶憑借ST去訪問service,service拿ST去CAS驗證,驗證通過后,允許用戶訪問資源。
Proxy Service的代理憑據(jù)。用戶通過CAS成功登錄某一Proxy Service后,CAS生成一個PGT對象,緩存在CAS本地,同時將PGT的值(一個UUID字符串)回傳給Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以為Target Service(back-end service)做代理,為其申請PT。
PGTIOU是CAS協(xié)議中定義的一種附加票據(jù),它增強了傳輸、獲取PGT的安全性。
PT是用戶訪問Target Service(back-end service)的票據(jù)。如果用戶訪問的是一個Web應(yīng)用,則Web應(yīng)用會要求瀏覽器提供ST,瀏覽器就會用cookie去CAS獲取一個ST,然后就可以訪問這個Web應(yīng)用了。如果用戶訪問的不是一個Web應(yīng)用,而是一個C/S結(jié)構(gòu)的應(yīng)用,因為C/S結(jié)構(gòu)的應(yīng)用得不到cookie,所以用戶不能自己去CAS獲取ST,而是通過訪問proxy service的接口,憑借proxy service的PGT去獲取一個PT,然后才能訪問到此應(yīng)用。
二 代碼解析 CAS Ticket類圖
方法聲明:public synchronized ServiceTicket grantServiceTicket(final String id,final Service service, final ExpirationPolicy expirationPolicy, final boolean credentialsProvided) 方法描述: 1:生成SerivceTicketImpl 2:更新屬性: this.previousLastTimeUsed = this.lastTimeUsed; this.lastTimeUsed = System.currentTimeMillis(); this.countOfUses++; 3:給service對象的principal屬性賦值 4:將service對象放入map services
方法聲明: public TicketGrantingTicket grantTicketGrantingTicket(final String id, final Authentication authentication,final ExpirationPolicy expirationPolicy) 方法描述:在CAS3.3對CAS2.0協(xié)議的實現(xiàn)中,PGT是由ST簽發(fā)的,調(diào)用的就是ServiceTicket的grantTicketGrantingTicket方法。方法返回的TicketGrantingTicket對象,表征的是一個PGT對象,其中的ticketGrantingTicket屬性的值是簽發(fā)ST的TGT對象。
方法聲明:void expire() 方法描述: 在CAS的logout接口實現(xiàn)中,要調(diào)用TGT對象的expire方法,然后會在緩存中清除此TGT對象。 expire方法的內(nèi)容:循環(huán)遍歷 services 中的Service對象,調(diào)用其logoutOfService方法。具體Service實現(xiàn)類中的logoutOfService方法的實現(xiàn),要通知具體的應(yīng)用,客戶要退出。
三、TGT、ST、PGT、PT關(guān)系1:ST是TGT簽發(fā)的。用戶在CAS上認證成功后,CAS生成TGT,用TGT簽發(fā)一個ST,ST的ticketGrantingTicket屬性值是TGT對象,然后把ST的值redirect到客戶應(yīng)用。
2:PGT是ST簽發(fā)的。用戶憑借ST去訪問Proxy service,Proxy service去CAS驗證ST(同時傳遞PgtUrl參數(shù)給CAS),如果ST驗證成功,則CAS用ST簽發(fā)一個PGT,PGT對象里的ticketGrantingTicket是簽發(fā)ST的TGT對象。
3:PT是PGT簽發(fā)的。Proxy service代理back-end service去CAS獲取PT的時候,CAS根據(jù)傳來的pgt參數(shù),獲取到PGT對象,然后調(diào)用其grantServiceTicket方法,生成一個PT對象。 TGT、ST、PGT、PT之間的關(guān)聯(lián)關(guān)系
CAS CLIENT篇CASFilter 參數(shù)說明:
應(yīng)用整合篇一、JAVA程序整合1、 應(yīng)用配置說明(結(jié)合cas client) 導(dǎo)入key到本地jdk(tomcat使用的jdk必須) keytool -import -keystore d:/work/jdk1.6.0_13/jre/lib/security/cacerts -file d:/casex/800jit.crt -alias 800jit 在ie中導(dǎo)入證書800jit.crt 修改web程序的web.xml添加 <!-- 用于單點退出 --> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener>
<filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter>
<!-- 用于單點登錄 -->
<filter> <filter-name>CAS Filter</filter-name> <filter-class>com.olymtech.cas.client.filter.CASFilter</filter-class> <init-param> <param-name>com.olymtech.cas.client.filter.loginUrl</param-name> <param-value>https://cas./cas/login</param-value> </init-param> <init-param> <param-name>com.olymtech.cas.client.filter.validateUrl</param-name> <param-value>https://cas./cas/serviceValidate</param-value> </init-param> <init-param> <param-name>com.olymtech.cas.client.filter.serverName</param-name> <param-value>saas.</param-value> </init-param> <init-param> <param-name>com.olymtech.cas.client.filter.wrapRequest</param-name> <param-value>true</param-value> </init-param> </filter>
<filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
<filter-mapping> <filter-name>CAS Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在jsp/servlet中得到登陸數(shù)據(jù): <%@ page language="java" import="com.olymtech.cas.client.filter.CASFilterRequestWrapper"%> <% CASFilterRequestWrapper reqWrapper=new CASFilterRequestWrapper(request); String username = reqWrapper.getRemoteUser(); %> |
|
|