配置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的源码

原文出处:http://m.oschina.net/blog/160930

你可能感兴趣的:(phpCAS)