cas實現單點登錄,登出(java和php客戶端)

 

 iLife's 博客http://blog.csdn.net/fei1502816 


最近項目中需要做單點登錄,客戶端包含java和php,java有幾個應用程序,php是discuz+supesite+ucenter,需

 

要這幾個客戶端都要能單點登錄和登出,在網上找了許多相關資料,今天終於配置成功,步驟如下:

 

1、cas服務端:下載地址:http://downloads.jasig.org/cas/cas的服務端和客戶端有許多版本,最新版本和老版本

 

有很大的區別,目前服務端最新版本爲:cas-server-3.4.4-release.zip

 

解壓cas-server-3.4.4-release.zip將modules目錄下的cas-server-webapp-3.4.4.war改名稱爲cas.war複製到

 

tomcat的webapps下,啓動tomcat,訪問:http://localhost:8080/cas/login 就可以看到登錄界面了:

(如下:圖一)

cas服務端默認採用的是 用戶名=密碼的驗證,並且採用的是https驗證,需要給tomact配置證書,本系統沒有采用https驗證,若採用https驗證可參考:

 

http://blog.csdn.net/haydenwang8287/archive/2010/07/26/5765941.aspx

 

1.1、若不採用https驗證,服務器端需要配置

  1)、

cas\WEB-INF\deployerConfigContext.xml

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient"/>


 增加參數p:requireSecure="false",是否需要安全驗證,即HTTPS,false爲不採用,加上去之後如下:

<bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
 p:httpClient-ref="httpClient"  p:requireSecure="false"/>


 2)、

cas\WEB-INF\spring-configuration\

ticketGrantingTicketCookieGenerator.xml

<bean id="ticketGrantingTicketCookieGenerator" class="org.jasig.cas.web.support.CookieRetrievingCookieGenerator"

      p:cookieSecure="true"

      p:cookieMaxAge="-1"

      p:cookieName="CASTGC"

      p:cookiePath="/cas" />


 

參數p:cookieSecure="true",同理爲HTTPS驗證相關,TRUE爲採用HTTPS驗證,FALSE爲不採用https驗證。

參數p:cookieMaxAge="-1",簡單說是COOKIE的最大生命週期,-1爲無生命週期,即只在當前打開的IE窗口有效,IE關閉或重新打開其它窗口,仍會要求驗證。可以根據需要修改爲大於0的數字,比如3600等,意思是在3600秒內,打開任意IE窗口,都不需要驗證。

1.2、服務器端退出訪問:http://localhost:8080/cas/logout,

(如下圖二)

若希望退出後能返回則需要配置

服務端cas-servlet.xml配置

<bean id="logoutController" class="org.jasig.cas.web.LogoutController" ... .../>

增加屬性 p:followServiceRedirects="true"

 

退出鏈接爲:http://localhost:8080/cas/logout?service=http://localhost:8080/Casclient/index.jsp

1.3、更改服務器端驗證方式,採用數據庫驗證:

修改配置文件deployerConfigContext.xml,加dbcp連接池:(以oracle爲例)

<bean id="casDataSource" class="org.apache.commons.dbcp.BasicDataSource">
     <property name="driverClassName">
          <value>oracle.jdbc.driver.OracleDriver</value>
     </property>
     <property name="url">
          <value>jdbc:oracle:thin:@192.168.18.26:1521:orcl</value>
     </property>
     <property name="username">
          <value>test</value>
     </property>
     <property name="password">
          <value>test</value>
     </property>
   </bean>

需要的jar包有:(見附件:cas-server-support-jdbc-3.4.4.jar,commons-dbcp-1.2.1.jar,commons-pool-1.3.jar,ojdbc14_g.jar)

 

配置加密方式,cas內置的有MD5加密,也可以寫自己的加密類,實現org.jasig.cas.authentication.handler.PasswordEncoder接口即可:

<bean id="passwordEncoder"  
    class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder" autowire="byName">      
    <constructor-arg value="MD5"/>  
   </bean> 

註釋掉默認的驗證方式,採用數據庫查詢驗證:

<property name="authenticationHandlers">
     <list>
     <!----註釋掉這裏的默認驗證方式,採用以下驗證QueryDatabaseAuthenticationHandler-->
    <!--
    <bean
     class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /> -->

 

     <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
      <property name="dataSource" ref="casDataSource" />
      <property name="sql" 
         value="select password from userinfo where lower(username) = lower(?)" />
      <property  name="passwordEncoder"  ref="passwordEncoder"/>
     </bean>
   </list>
  </property>

---------------到這裏cas服務端的配置就完成了。

2、java客戶端配置,下載客戶端:http://downloads.jasig.org/cas-clients/,目前最新版本爲:cas-client-3.2.0

 

將modules下的jar複製到java客戶端Casclient1的lib下,在web.xml中配置過濾器,配置如下(詳情見附件):

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
 xmlns="http://java.sun.com/xml/ns/j2ee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
 
 <!-- 用於單點退出,該過濾器用於實現單點登出功能,通知其他應用單點登出-->

 <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>
         <filter-name>CASFilter</filter-name>
         <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
         <init-param>
                 <param-name>casServerLoginUrl</param-name>
                 <param-value>http://192.168.18.8:8080/cas/login</param-value>
                 <!--這裏的server是服務端的IP-->
         </init-param>
         <init-param>
                 <param-name>serverName</param-name>
                 <param-value>http://192.168.18.8:8989</param-value>
         </init-param>
 </filter>
 <filter-mapping>
         <filter-name>CASFilter</filter-name>
         <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <!-- 該過濾器負責對Ticket的校驗工作,必須啓用它 -->
 <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://192.168.18.8:8080/cas</param-value>
         </init-param>
         <init-param>
                 <param-name>serverName</param-name>
                 <param-value>http://192.168.18.8:8989</param-value>
         </init-param>
 </filter>
 <filter-mapping>
         <filter-name>CAS Validation Filter</filter-name>
         <url-pattern>/*</url-pattern>
 </filter-mapping>
 
 <!--
         該過濾器負責實現HttpServletRequest請求的包裹,
         比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登錄用戶的登錄名,可選配置。
 -->
 <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>

<filter>
        <filter-name>CAS Assertion Thread Local Filter</filter-name>
        <filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>CAS Assertion Thread Local Filter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
 
 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>


 

頁面爲:

<%
AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal();    
String username = principal.getName(); 
%>
<br/>----------------------------------------------------------<br/>
<h1>登錄成功,這是客戶端1啊</h1><br/>
用戶名:<%=username %><br/>
<a href="http://localhost:8989/Casclient2/index.jsp">進入客戶端2</a><br/>

<a href="http://localhost:8080/cas/logout?service=http://localhost:8989/Casclient1/index.jsp">退出</a><br/>


 

-----------到這裏java客戶端配置成功,發佈到tomcat,複製Casclient1改名爲Casclient2,啓動tomcat,

 

訪問Casclient1,跳轉到登錄頁面,登錄成功後成功轉向登錄成功頁面,這時訪問Casclient2發現不需要登錄即顯示登錄成功頁面,java單點登錄成功。

 

 

3、配置php客戶端,下載php客戶端:http://downloads.jasig.org/cas-clients/php/ ,目前最新版本爲:CAS-1.2.0RC2

 

新建php工程:Phpcasclient1,將CAS文件夾和CAS.php複製到工程中,修改CAS/client.php,將其中的https改爲http,將docs/examples/example_simple.php

 

複製到工程中,修改如下:

<?php
//
// phpCAS simple client
//
// import phpCAS lib
include_once('CAS.php');
phpCAS::setDebug();
// initialize phpCAS
phpCAS::client(CAS_VERSION_2_0,'192.168.18.8',8080,'cas');
// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation();
// force CAS authentication
phpCAS::forceAuthentication();
// at this step, the user has been authenticated by the CAS server
// and the user's login name can be read with phpCAS::getUser().
// logout if desired
if (isset($_REQUEST['logout'])) {
 
 $param=array("service"=>"http://localhost/Phpcasclient1/example_simple.php");//退出登錄後返回
 phpCAS::logout($param);

}
// for this test, simply print that the authentication was successfull
?>

<html>
  <head>
    <title>phpCAS simple client</title>
  </head>
  <body>
    <h1>Successfull Authentication!這是客戶端1</h1>
    <p>the user's login is <b><?php echo phpCAS::getUser(); ?></b>.</p>
    <p>phpCAS version is <b><?php echo phpCAS::getVersion(); ?></b>.</p>
     <p><a href="http://192.168.18.8:8989/Casclient1/index.jsp">去java客戶端1</a></p>
     <p><a href="?logout=">退出</a></p>
  </body>
</html>

php配置需要開啓php_curl,可以複製Phpcasclient1爲Phpcasclient2

 

訪問:http://localhost/Phpcasclient1/example_simple.php,跳轉到登錄頁面,登錄成功後訪問Phpcasclient2,不需要登錄,

 

php單點登錄成功,這時再訪問java客戶端發現也不需要登錄,php和java應用之間單點登錄成功。

 

注:php的phpCAS::client(CAS_VERSION_2_0,'192.168.18.8',8080,'cas');地址需要和java的web.xml中的cas服務器地址一致,我開始一個寫的ip:192.168.18.8,一個寫的localhost,

php和java總是不能同步登錄,鬱悶了好久

 

----------------到這裏java和php的客戶端已經配置完成,現在你會發現php和java之間不能單點登出,php端退出java客戶端也退出,反之java退出但是php卻沒有同步退出

 

這裏需要做一個配置,在

phpCAS::setNoCasServerValidation();

// force CAS authentication
phpCAS::forceAuthentication();

這裏加上

 

phpCAS::setNoCasServerValidation();

// force CAS authentication

phpCAS::handleLogoutRequests();  這裏會檢測服務器端java退出的通知,就能實現php和java間同步登出了。

phpCAS::forceAuthentication();


至於discuz+supesite的單點登錄,再瞭解了php單點登錄的原理後就需要改造discuz+supesite的登錄代碼了,discuz的爲logging.php

 

supersite的爲batch.login.php,俺是做java開發的,對php不是很熟悉,所以改造的覺得不是很靠譜,大致是先讓discuz單點登錄,獲取用戶名,根據用戶

 

獲取數據庫中的密碼再交給discuz系統自己的登錄系統登錄。discuz是採用cookie驗證的,所以在java端退出後,discuz不會退出。

 

若誰有改造很成功的可以交流下。

 

參考網址:

http://blog.csdn.net/DL88250/archive/2008/08/20/2799522.aspx

http://www.wsria.com/archives/1349

http://tonrenyuye.blog.163.com/blog/static/30012576200922925820471/

http://www.discuz.net/thread-1416206-1-1.html


http://zxs19861202.iteye.com/blog/855856 JavaEye

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章