1. 程式人生 > >4、《SSO CAS單點系列》之 實操!輕鬆玩轉SSO CAS就這麼簡單(相遇篇)

4、《SSO CAS單點系列》之 實操!輕鬆玩轉SSO CAS就這麼簡單(相遇篇)

CAS是中央認證服務Central Authentication Service的簡稱。最初由耶魯大學的Shawn Bayern 開發,後由Jasig社群維護,經過十多年發展,目前已成為影響最大、廣泛使用的、基於Java實現的、開源SSO解決方案。

2012年,Jasig和另一個有影響的組織Sakai Foundation合併,組成Apereo。Apereo是一個由高等學術教育機構發起組織的聯盟,旨在為學術教育機構提供高質量軟體,當然很多軟體也被大量應用於商業環境,譬如CAS。目前CAS由Apereo社群維護。

前面我們自己親自動手實現了一個SSO,包括Nebula Server和Nebula Client,對SSO的解決思路也已非常清楚了。那現在理解這個CAS原理就非常容易了,同理,CAS也提供了一個認證中心,叫CAS Server,參與登入的應用系統都會引導到CAS Server進行登入。與Nebula Client類似,各應用系統與CAS Server互動通訊的登入元件叫CAS Client。

可能有的讀者疑問了,既然我們按照相同原理自己都實現了SSO,為什麼還要學習瞭解CAS?

我們知道,網際網路應用及企業應用的SSO具體使用場景和要求往往千差萬別,如基於上篇的SSO實現,在具體實現上需要定製化很多場景,也就是說需要一定量的開發定製工作。而成熟開源的CAS,很多情況下,考慮了這些具體場景,直接在框架上面做應用開發比從零基礎底層技術開發要輕鬆的多。

如CAS Client,已經提供了包括Java、.net、php、ruby、perl等多種語言的實現,非常適合異構系統的單點登入使用場景。再比如認證方式,除了常見的基於資料庫認證,還提供LDAP使用場景,同時支援各種常見認證協議,如spnego、OpenId、X509等等。

對於全域性會話,CAS基於Cookie使用了自己的實現方式,而服務端的會話儲存,除了預設基於記憶體模式,還提供了基於ehcache、memcached等多種實現,同時提供了靈活介面便於自己定製擴充套件,這非常適合某些高可用性、高效能的應用場景。

因此,在一般場景下,我們不需要重新發明輪子,直接在成熟技術框架基礎上開發使用即可。這也是CAS在很多網際網路和企業應用中廣泛使用的原因。當然,對於某些場景,如安全性因素、更特殊更高效的應用場景,在技術實力許可的情況下,通常都自己實現SSO。

簡短地介紹完CAS之後,那我們就趕緊體驗一下吧:

1、到cas原始碼工程https://github.com/Jasig/cas,點選releases到釋出頁

2.我們看到目前的最新版本是v4.1.0,我們看到這個版本就在9月中旬釋出,說明CAS社群非常活躍。往下拉找到Downloads,下載cas-4.1.0.zip 原始碼包。

3.解壓到硬碟如e:\cas-4.1.0,cas原始碼提供的是maven工程,我們利用eclipse的maven import功能匯入工程。筆者使用的eclipse版本是Luna。注意,cas提供了眾多外掛子工程,為了工作介面整潔,筆者只匯入三個重要工程:父工程cas-server、核心包工程cas-server-core、執行web包工程cas-server-webapp。

4.此時pom.xml可能提示有錯誤,按eclipse提示更正資訊ignore即可。然後我們利用maven compile、package cas-server-webapp工程。正常情況下會生成cas.war 認證中心安裝包,說明下載的原始碼沒問題。 

5.找到WEB-INF\deployerConfigContext.xml,找到primaryAuthenticationHandler段落,修改登入使用者名稱為admin,密碼123123 做登入體驗用。(CAS預設使用的是配置檔案方式管理使用者名稱和密碼,實際應用中使用最多的是利用資料庫管理,CAS提供相應介面)

6.找到WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml檔案,將p:cookieSecure的值改為false。CAS預設要求使用https協議,我們將此改為false,使其在http協議下也能工作。

7.copy如下程式碼到pom.xml檔案的plugins段落中,配置tomcat7執行外掛。

<plugin>  
  <groupId>org.apache.tomcat.maven</groupId>  
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>2.2</version>
  <configuration>
    <uriEncoding>UTF-8</uriEncoding>  
    <path>/</path>
    <port>80</port>
    <contextReloadable>false</contextReloadable>
  </configuration>  
</plugin>

tomcat7:run 執行cas認證中心

在本機的host檔案中配置一個域名,如www.cas.com,瀏覽器輸入該網址,即可出現cas登入頁:

10.此時輸入我們定義的使用者名稱密碼 admin/123123 系統顯示成功登入了。我們可以輸入網址http://www.cas.com/logout 讓其登出,同時有意輸入錯誤使用者名稱密碼看看頁面的反應。

上面我們體驗的實際是在認證中心直接登入登出的情況,接下來我們體驗應用系統利用cas進行的登入登出。

1.我們在host檔案中再配置一個域名,www.ssoclient.com用於表示此應用系統登入網址。

2.建立一個java web maven工程,埠號設定為81,將CAS Client包配置到pom.xml中。(本例中整個工程採用spring mvc + spring,jsp為模板,同上,採用tomcat7 maven外掛啟動)

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

3.在web.xml中新增如下配置:首先配置登出listener和filter

<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-mapping>
    <filter-name>CAS Single Sign Out Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

接著配置認證filter,即受限資源需要先經過此fiter.注意這裡面要配置認證中心登入網址,以及標識此係統應用的服務名稱。

<filter>
 <filter-name>CAS Authentication Filter</filter-name>     
 <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
 <init-param>
  <param-name>casServerLoginUrl</param-name>
  <param-value>**http://www.cas.com/login**</param-value>
 </init-param>
 <init-param>
  <param-name>serverName</param-name>
  <param-value>**http://www.ssoclient.com:81**</param-value>
 </init-param>
</filter>
<filter-mapping>
 <filter-name>CAS Authentication Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

接下來配置驗證票據ticket的filter,此作用類似於我們開發Nebula中的驗證令牌token:

<filter>
 <filter-name>CAS Validation Filter</filter-name> 
 <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
 <init-param>
  <param-name>casServerUrlPrefix</param-name>
  <param-value>**http://www.cas.com**</param-value>
 </init-param>
 <init-param>
  <param-name>serverName</param-name>
  <param-value>**http://www.ssoclient.com:81**</param-value>
 </init-param>
</filter>

<filter-mapping>
 <filter-name>CAS Validation Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

最後我們配置一個Filter封裝標準的HttpRequest,使得request.getRemoteUser()和request.getUserPrincipal()這兩個方法可用。

<filter>
 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
 <filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

在這樣配置下,整個應用系統都是受限資源,我們定義一個一句話的首頁JSP:

${user}, 你好啊! <a href="http://www.cas.com/logout">登出</a>

對應的controller也很簡單:

@RequestMapping("/index.do")
public String showIndex(HttpServletRequest request, HttpServletResponse response) {
  Principal principal = request.getUserPrincipal();
  request.getSession().setAttribute("user", principal.getName());
  return "/index";  
}

準備就緒,啟動執行。然後在瀏覽器打入網址www.ssoclient.com:81/index.do,由於整個系統資源受限需要登入,這時會立即跳入到認證中心進行登入(注意瀏覽器網址是不是帶了一個service引數?跟我們自己開發SSO使用的returnURL有異曲同工之妙)。

輸入正確的使用者名稱密碼後,又重新返回到系統應用,並顯示登入後的系統首頁。這個過程和我們自己開發Nebula時的系統體驗是一樣的。

大家是不是還注意到在認證中心登入頁使用者名稱密碼輸入框下面還有一個“轉向其他站點前提示我”checkbox選擇框,選中這個意味著什麼呢?下面我們來演示一下:

首先,將配置檔案WEB-INF\spring-configuration\warnCookieGenerator.xml中的p:cookieSecure變數改成false,使其在http下起作用。

然後www.cas.com進入認證中心登入頁,輸入賬戶資訊admin/123123 並選中“轉向其他站點前提示我”進行登入。

接著http://www.ssoclient.com:81/index.do 訪問系統應用,這時和前面直接顯示登入後首頁不同,這裡顯示轉向目標系統提示頁。只要登入使用者跳轉到一個和現在不同的系統,即出現此提示頁。點選“這裡”即進入目標系統。

至此,我們算是和CAS相遇了,後面我們將更深入CAS,使其能勝任實際應用。

作者: 手插口袋_ 
連結:http://www.imooc.com/article/3576
來源:慕課網