1. 程式人生 > >配置CAS應用客戶端

配置CAS應用客戶端

本文介紹JavaEE,Django, Php的CAS客戶端配置方法。

CAS客戶端可以在這裡找到,其中有些是官方維護,有些是社群維護。你也可以根據CAS協議編寫一個客戶端。關於CAS登陸驗證流程請參閱: 這裡 。當然最好是採用別人已經封裝好的客戶端(元件),避免重複發明輪子。

JavaEE

先定義一些環境變數:

  • CATALINA_HOME: Tomcat安裝目錄(以tomcat 7.0.42為例)

  • CAS_CLIENT_HOME cas客戶端發行包解壓後的目錄(以cas-client-3.2.1為例)

我們以tomcat自帶的例子來進行說明。

開啟%CATALINA_HOME%/webapps/examples1/WEB-INF/web.xml,在所有過濾器之前新增如下的過濾器:

<!-- 修復亂碼的問題 -->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>edu.vt.middleware.servlet.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>requestCharsetName</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>responseCharsetName</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
    <filter-mapping>
   <filter-name>CharacterEncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

    <!-- 該過濾器用於實現單點登出功能,可選配置。 -->
<filter>
    <filter-name>CasSingleSignOutFilter</filter-name>
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
    <filter-mapping>
   <filter-name>CasSingleSignOutFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

    <!-- 該過濾器負責使用者的認證工作,必須啟用它 -->     
<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://localhost:8444/cas-server/login</param-value> <!-- CAS-SERVER的url-->
      </init-param>
      <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value> <!-- 本客戶端的IP和埠 --> 
      </init-param>
</filter>   
    <filter-mapping>
    <filter-name>CasAuthenticationFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

    <!-- 該過濾器負責對Ticket的校驗工作,必須啟用它 -->
<filter>
    <filter-name>CasValidationFilter</filter-name>
    <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
    <init-param>
        <param-name>casServerUrlPrefix</param-name>
        <param-value>https://localhost:8444/cas-server</param-value>
    </init-param>
    <init-param>
        <param-name>serverName</param-name>
        <param-value>http://localhost:8080</param-value>
    </init-param>
    <init-param>
        <param-name>redirectAfterValidation</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>   
    <filter-mapping>
    <filter-name>CasValidationFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>     

    <!--
       該過濾器負責實現HttpServletRequest請求的包裹,
        比如允許開發者通過HttpServletRequest的getRemoteUser()方法獲得SSO登入使用者的登入名
    -->
    <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>

    <!-- 將通過驗證後得到的Assertion 放入threadlocal  -->
    <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>

以及在所有監聽器之前新增:

<!-- 用於單點退出,該過濾器用於實現單點登出功能,通知其他應用單點登出-->
 <listener>
     <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>

其中casServerLoginUrl和casServerUrlPrefix要根據你的實際情況替換成合適的值,serverName是CAS客戶端的URL。另外,你應該根據業務的需要對受保護的資源實施登陸認證要求,這裡為了演示的方便,對所有資源的訪問請求都要求身份驗證.

$CAS_CLIENT_HOME/modules/cas-client-core-3.2.1.jar, $CAS_CLIENT_HOME/modules/cas-client-integration-atlassian-3.2.1.jar複製到$CATALINA_HOME/webapps/examples/WEB-INF/lib目錄中

把搭建CAS伺服器時產生的證書檔案(見這裡)匯入執行CAS客戶端的JVM證書庫

此外還要下載一個vt-servlet-filters-2.0.2.jar, common-logging-1.1.1.jar放到$CATALINA_HOME/webapps/examples/WEB-INF/lib

啟動tomcat, 訪問http://localhost:8080/examples。 第一次訪問時,瀏覽器會被重定向到CAS認證伺服器的登陸頁面,輸入使用者名稱和密碼並登陸成功後,瀏覽器會跳回http://localhost:8080/examples。後續訪問不需要重新登陸,直到CAS客戶端的session過期或使用者執行登出操作。

PHP

先定義一些環境變數

  • PHP_HOME: PHP安裝目錄(以php 5.5.1為例)

  • NGINX_HOME: nginx 安裝目錄(以nginx 1.4。1為例)

  • PHPCAS_HOME phpCAS客戶端安裝包解壓後的目錄(以phpCAS-1.3.2為例)。

注意: phpcas-1.3.2.tgz的目錄結構是這樣的:

·
|-- CAS-1.3.2/
|    |-- CAS
|    |-- docs
|    |-- CAS.php
|    |-- LICENSE
|    |-- NOTICE
|    `-- README.md
`-- package.xml

需要將CAS-1.3.2/目錄下的所有內容拷貝到上一層目錄,即

·
|-- CAS
|-- docs
|-- CAS.php
|-- LICENSE
|-- NOTICE
|-- README.md
`-- package.xml

安裝phpCAS客戶端

安裝phpCAS客戶端前,請先確保php.ini中配置了curl, openssl和zlib三個擴充套件。

這裡需要用到php官方提供的go-pear安裝指令碼。對於Linux的PHP,該指令碼在編譯安裝完成後位於$PHP_HOME/bin目錄下;對於window的PHP,該指令碼可能沒在官方的發行包中,故需要先將 go-pear網頁的輸出另存為·go-pear.phar·檔案,然後在命令終端執行

php go-pear.phar

此時會顯示一些關於pear指令碼的安裝配置資訊,直接按回車完成。安裝完成後,會生成pear.bat指令碼,把pear.bat複製到%PHP_HOME%目錄下。

安裝phpCAS

$PHP_HOME/bin/pear.sh install $PHPCAS_HOME/package.xml

Windows中則是:

%PHP_HOME%pear.bat  install %PHPCAS_HOME%/package.xml

pear安裝指令碼會把phpCAS分成兩部分(執行庫和文件庫)進行安裝。在Linux中,預設會把phpCAS的執行庫安裝到$PHP_HOME/lib/php目錄中,把文件庫安裝到$PHP_HOME/lib/php/doc下;而Windows則把執行庫安裝到%PHP_HOME%/pear/下,把文件庫安裝到%PHP_HOME%/docs中.

配置phpCAS客戶端

phpcas自帶了一個演示例子(example_simple.php)下面我們以這個為例進行說明。

首先複製兩個樣板檔案到nginx的釋出目錄:

cp $PHPCAS_HOME/docs/examples/config.example.php $NGINX_HOME/html/config.php
cp $PHPCAS_HOME/docs/examples/example_simple.php $NGINX_HOME/html/example_simple.php

根據實際情況,需要修改config.php中的$phpcas_path, $cas_host, $cas_context, $cas_port, $cas_server_ca_cert_path這幾個變數,其中

  • $phpcas_path 指向phpcas執行庫的根目錄(Linux中填入 $PHP_HOME/lib/php , windows中填入%PHP_HOME%/pear, 注意要把PHP_HOME替換為實際的路徑, 並且Windows中的路徑分割符要用雙反斜槓“\“)

  • $cas_host CAS認證伺服器的域名

  • $cas_port CAS認證伺服器的https埠

  • $cas_context CAS認證伺服器的上下文路徑(假如CAS認證伺服器的頁面登陸地址是https://localhost:8444/cas-server/login,那麼$cas_context就是cas-server)

  • $cas_server_ca_cert_path 指向CAS認證伺服器的安全證書(如果nginx應用伺服器和CAS認證伺服器不是部署在同一臺機,那麼要把該證書拷貝到nginx應用伺服器的機器上)

example_simple.php給出phpCAS的基本使用方法,但example_simple.php沒有提供單點登出的配置方法。要支援單點登出,需要在phpCAS::setNoCasServerValidation();和phpCAS::forceAuthentication();這兩條語句之間加上:

phpCAS::handleLogoutRequests(false,true);

其中handleLogoutRequests的第一個引數表示當example_simple.php接收到CAS登出請求時,是否檢查該請求的客戶端。這主要是為了防止有其他人冒充CAS認證伺服器傳送登出請求。如果第一個引數為false,即表示example_simple.php不檢查客戶端,那麼第二個引數會被忽略。如果第一個引數為true,那麼第二個引數應該以陣列的形式列出哪些IP(或域名)的客戶端所傳送的登出請求會被處理。比如CAS的認證伺服器IP為192.168.121.130,那麼上述的程式碼可能改成:

phpCAS::handleLogoutRequest(true, ['192.168.121.130']);

測試

啟動nginx , 訪問http://localhost/example_simple.php。第一次訪問時,瀏覽器會被重定向到CAS認證伺服器的登陸頁面, 輸入使用者名稱和密碼併成功登陸後,瀏覽器跳回example_simple.php。後續訪問不需要重新登陸,直到CAS客戶端的session過期或使用者執行登出操作。

Django

環境

  • OS Windows 7(64位)

  • python 2.7.3(32位)

  • django 1.5.1

  • django_cas 2.1.1

假設上述環境已就緒,下面在一個臨時建立的django工程(E:\workspace\python_workspace\hello, 記為%PROJ_DIR%)中說明如何使用django_cas。

配置

在開始之前,先修改django_cas的一個檔案。進入%PYTHON_HOME%/lib/site-packages/django_cas-2.1.1-py2.7.egg/django_cas,開啟views.py,將from django.http import 後面的get_host刪去,並把檔案中所有的get_host(request)替換為request.get_host()

開啟%PROJ_DIR%的專案配置檔案settings.py.

在INSTALL_APPS配置項中追加'django_cas',,如下圖所示:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    'django.contrib.admindocs',
    'books',
    'django_cas',
)

在MIDDLEWARE_CLASSES配置項的'django.contrib.auth.middleware.AuthenticationMiddleware'後面新增'django_cas.middleware.CASMiddleware', ,如下面所示

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_cas.middleware.CASMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # Uncomment the next line for simple clickjacking protection:
    'django.middleware.clickjacking.XFrameOptionsMiddleware',    
)

在AUTHENTICATION_BACKENDS配置項的最後新增 'django_cas.backends.CASBackend', , 如下面所示

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django_cas.backends.CASBackend',
)

新增CAS_SERVER_URL配置項,該配置項的內容為CAS認證伺服器的預設地址,如下面所示

CAS_SERVER_URL='https://localhost:8443/cas-server/'

除此之外,還可以定義一些可選的配置項:

  • CAS_ADMIN_PREFIX: The URL prefix of the Django administration site. If undefined, the CAS middleware will check the view being rendered to see if it lives in django.contrib.admin.views`.

  • CAS_EXTRA_LOGIN_PARAMS: Extra URL parameters to add to the login URL when redirecting the user.

  • CAS_IGNORE_REFERER: If True, logging out of the application will always send the user to the URL specified by CAS_REDIRECT_URL.

  • CAS_LOGOUT_COMPLETELY: If False, logging out of the application won't log the user out of CAS as well.

  • CAS_REDIRECT_URL: Where to send a user after logging in or out if there is no referrer and no next page set. Default is /.

  • CAS_RETRY_LOGIN: If True and an unknown or invalid ticket is received, the user is redirected back to the login page.

  • CAS_VERSION: The CAS protocol version to use. '1' and '2' are supported, with '2' being the default.

定義登陸URL和登出URL所對應的檢視函式,比如

(r'^accounts/login/$', 'django_cas.views.login'),
 (r'^accounts/logout/$', 'django_cas.views.logout'),

Play 1.2.x

Play 1.2.x提供了CAS客戶端模組支援. 首先開啟Play工程的依賴配置檔案conf/dependencies.yml, 新增模組引用宣告:

- play -> cas 1.3

在conf/routes中新增:

*    /    module:cas

然後執行play dependencies,Play會把該模組下載並解壓到 /modules/cas-1.3. cas-1.3在conf/application.conf預設提供了一組配置示例,我們只需按照實際需要進行修改即可。下面是一個簡單配置的例子:

#############################################################
#   CAS CONFIGURATION
#############################################################
cas.validateUrl=https://localhost:8443/cas/serviceValidate
cas.loginUrl=https://localhost:8443/cas/login
cas.logoutUrl=https://localhost:8443/cas/logout
# 如果不使用代理模式,需要設定為空白
cas.proxyUrl=
cas.gateway=false
 # play-cas模組可以為CAS伺服器提供mock支援. mock支援特性只能工作在DEV模式下
cas.mockserver=false
# 如果使用mock支援,需要修改處理http請求的執行緒數
# play.pool=2
application.url.ssl=https://localhost:443
# 登陸成功後跳轉的首頁
application.url=http://localhost:9000

然後對需要身份認證的操作新增@With(controllers.modules.cas.SecureCAS.class)註解,比如

@With(controllers.modules.cas.SecureCAS.class)
public class Application extends Controller {

    public static void index() {
        render();
    }

        public static void test(){
            render();
        }

}

這樣所有Application內的action請求都要先經過身份認證。

如果需要登陸後做進一步的許可權控制,可以在Controller或Action上新增@play.modules.cas.annotation.Check註解,同時繼承controllers.modules.cas.Security類並提供public static boolean check(String profile)的實現,比如

@With(controllers.modules.cas.SecureCAS.class)        
public class Application extends Controller {

        @play.modules.cas.annotation.Check("role1")
    public static void index() {
        render();
    }

        public static void test(){
            render();
        }

}

    public class MySecurity extends Security{
        public static boolean check(String profile){
            if ("role1".equals(profile)){    
                 return isPermit();   // do whatever you want
            }else{
                return false;
            }
        }
    }

對於通過身份驗證但沒有通過Security.check的請求,play-cas模組預設返回403響應,當然你也可以在Security子類提供自定義的onCheckFailed方法,返回一段描述性的文字。

更多高階用法,請參考這裡或play-cas的原始碼