cas單點登錄系統:客戶端(client)詳細配置


最近一直在研究cas登錄中心這一塊的應用,分享一下記錄的一些筆記和心得。后面會把cas-server端的配置和重構,另外還有這幾天再搞nginx+cas的https反向代理配置,以及cas的證書相關的知識分享出來。

Cas由兩部分組成,Cas Server和Cas Client。Cas Server是Cas自己的服務端,而Cas Client是Cas客戶端,往往客戶端需要和我們具體的業務系統進行集成,這里我們主要詳述cas 客戶端的配置以及實例

第一步:

我們得有一個現成的web項目,然后我們要加入cas-client-core-xxx.jar到classpath;

maven項目用這個:

<dependency>
	<groupId>org.jasig.cas.client</groupId>
	<artifactId>cas-client-core</artifactId>
	<version>3.3.3</version>
</dependency>

這里我使用 cas-client-core-3.3.3.jar,順便推薦一個用來搜索和下載引用包的網站,我一般從這里下載引用包:http://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core/3.3.3


第二步:配置Filter

 我們需要在應用的web.xml文件中配置四個Filter,這四個Filter必須按照固定的順序來進行配置,而且它們必須配置在應用的其它Filter之前。它們的先后順序要求如下:
1、AuthenticationFilter
2、TicketValidationFilter
3、HttpServletRequestWrapperFilter
4、AssertionThreadLocalFilter

1.1、 配置AuthenticationFilter

 1.1.1、AuthenticationFilter有兩個必須指定的參數:

casServerLoginUrl用來指定Cas Server登錄地址serverName或service用來指定認證成功后需要跳轉地址。

補充:

service和serverName一般只需要指定一個,如果都指定了,參數service將具有更高的優先級,即以service指定的參數值為准。

service和serverName的區別:

service指定的是一個確定的URL,認證成功后就會確切的跳轉到service指定的URL;

serverName用來指定主機名,格式為{http/https}:{主機名}:{端口號}

如:https://localhost:8335,當指定的是serverName時,AuthenticationFilter將會把它附加上當前請求的URI,以及對應的查詢參數來構造一個確定的URL,如指定serverName為“http://localhost”,而當前請求的URI為“/login”,查詢參數為“user=123&pwd=123”,則對應認證成功后的跳轉地址將為“http://localhost/login?user=123&pwd=123”。)

 AuthenticationFilter可以指定如下可選參數:
renew:當指定renew為true時,在請Cas Server時將帶上參數“renew=true”,默認為false。
gateway:指定gateway為true時,在請求Cas Server時將帶上參數“gateway=true”,默認為false。
artifactParameterName:指定ticket對應的請求參數名稱,默認為ticket。
serviceParameterName:指定service對應的請求參數名稱,默認為service。


例如,我是這樣配置的:

<filter>
      <filter-name>casAuthenticationFilter</filter-name>
   <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
      <init-param>
         <param-name>casServerLoginUrl</param-name>
         <param-value>https://cas.eguid.cn:8335/cas-server/</param-value>
      </init-param>
      <init-param>
         <param-name>serverName</param-name>
         <param-value>http://sso.eguid.cn:8080/</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>casAuthenticationFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>


1.2、配置TicketValidationFilter

請求通過AuthenticationFilter的認證之后,如果請求中攜帶了參數ticket則將會由TicketValidationFilter來對攜帶的ticket進行校驗。

TicketValidationFilter只是對驗證ticket的這一類Filter的統稱,其並不對應Cas Client中的一個具體類型。

Cas Client中有多種驗證ticket的Filter,都繼承自AbstractTicketValidationFilter,它們的驗證邏輯都是一致的,都有AbstractTicketValidationFilter實現,不同的是使用的TicketValidator不一樣。這里我們使用Cas10TicketValidationFilter,也可以使用Cas20ProxyReceivingTicketValidationFilter或者Saml11TicketValidationFilter。

<filter>
      <filter-name>casTicketValidationFilter</filter-name>
   <filter-class>org.jasig.cas.client.validation.Cas10TicketValidationFilter</filter-class>
      <init-param>
         <param-name>casServerUrlPrefix</param-name>
         <param-value>https://cas.eguid.cn:8335/cas-server/</param-value>
      </init-param>
        <init-param>
         <param-name>serverName</param-name>
         <param-value>http://sso.eguid.cn:8080/</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>casTicketValidationFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

必須指定的參數:

casServerUrlPrefix 用來指定Cas Server對應URL地址的前綴,如上面示例的“https://cas.eguid.cn:8335/cas-server
serverName或service:與前面的用法相同。

  

可選參數:
redirectAfterValidation :表示是否驗證通過后重新跳轉到該URL,但是不帶參數ticket,默認為true。
useSession :                在驗證ticket成功后會生成一個Assertion對象,如果useSession為true,則會將該對象存放到Session中。如果為false,則要求每次請求都需要攜帶ticket進行驗證,顯然useSession為false跟redirectAfterValidation為true是沖突的。默認為true。
exceptionOnValidationFailure :表示ticket驗證失敗后是否需要拋出異常,默認為true。
renew:                         當值為true時將發送“renew=true”到Cas Server,默認為false。
 
1.3、配置HttpServletRequestWrapperFilter

 HttpServletRequestWrapperFilter用於將每一個請求對應的HttpServletRequest封裝為其內部定義的CasHttpServletRequestWrapper,該封裝類將利用之前保存在Session或request中的Assertion對象重寫HttpServletRequest的getUserPrincipal()、getRemoteUser()和isUserInRole()方法。這樣在我們的應用中就可以非常方便的從HttpServletRequest中獲取到用戶的相關信息。

 <filter>
      <filter-name>casHttpServletRequestWrapperFilter</filter-name>
   <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>casHttpServletRequestWrapperFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

1.4、配置AssertionThreadLocalFilter

 AssertionThreadLocalFilter可以在應用的其它地方獲取Assertion對象,找個過濾器會把Assertion對象存放到當前的線程變量中,我們在程序的任何地方都可以從線程變量中獲取當前Assertion,就不需要再從Session或request中進行解析了。這個線程變量是由AssertionHolder持有的,我們在獲取當前的Assertion時也只需要通過AssertionHolder的getAssertion()方法獲取即可,如:
   Assertion assertion = AssertionHolder.getAssertion();

我是這樣配置的:

<filter>
      <filter-name>casAssertionThreadLocalFilter</filter-name>
     <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>casAssertionThreadLocalFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

cient端到這里就配置完成了,隨便寫個頁面,把這個應用部署到tomcat容器測試一下,嘗試打開頁面,你會發現跳轉進入了cas-server(cas服務端)的登錄頁面。

當你真的登錄成功后,你會發現,你回不到原來頁面了!怎么辦?其實我們只要在前端給他一個參數就行了,可以這樣簡單實現這個功能:

//登錄中心url
var loginCenter = "https://cas.eguid.cn:8335/cas-server";
function getUrl() {
	var hostname = location.href;
	return hostname;
}
//登陸
function login() {
	location.href = loginCenter + "/login?service=" + getUrl();
}
//登錄中心執行登出操作
function logoutServ()
{
	alert("開始登出");
	var loginUrl = loginCenter + "/login?service=" + getUrl();
	location.href = loginCenter + "/logout?service=" + loginUrl;
}
在頁面上的你得有登錄和退出兩個按鈕,分別調用login()和logoutServ()方法。

其實這里還有個小問題,就是雖然你在cas-server端注銷了,你會發現它依然會認為你現在是登錄狀態,所以沒有攔截你的請求。

這是因為它時基於session驗證的,你的server端session已經注銷了,但是客戶端應用這里的session還沒有注銷

一般我們會使用共享session的方法解決這個問題,另外有個簡單的方法就是你可以在后台寫個用來注銷當前用戶session的接口。





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM