环境
cas-server-4.1.8,cas-client-3.4.0,Java-8,Maven-3,Tomcat-7.0.72
CAS Server 安装
点此进入 CAS 下载列表,选择下载 cas-4.1.8.zip。
解压缩 cas-4.1.8.zip 并进入 cas-server-webapp 目录,在当前目录打开 cmd 并执行安装命令
1 
  | mvn -e -ff clean install -Dmaven.test.skip=true 
  | 
 
经亲身测试(自己拉的电信12M网络),该安装过程非常漫长,主要因为镜像原因导致依赖包下载非常慢,此过程需静心等待。或直接下载我已经打好包的 cas.war 文件(注:该文件的依赖包版本有稍做修改,此不影响正常使用)。
安装完成后,在 cas-server-webapp/target 目录下可以看到 cas.war 文件,该文件便是 cas server 应用服务的 war 包。
cas server 安全认证是基于 https 的,这里使用 JDK 自带的 keytool 工具生成数字证书,生产环境系统的应用需要到证书提供商处购买证书。证书的生成及 Tomcat 的配置可参考文章:keytool 生成数字证书 - tomcat https 配置 。
首先确保 tomcat 的 https 可以正常访问,将 cas.war 文件拷贝到 apache-tomcat-7.0.72/webapps 下进行发布,启动 tomcat,访问 https://www.fanlychie.com:8443/cas

上图是用火狐浏览器打开的链接,选择高级 -> 添加例外 -> 确认安全例外

用户名和密码在 apache-tomcat-7.0.72/webapps/cas/WEB-INF/deployerConfigContext.xml 配置文件中,找到并打开该文件,大概在 105 行
1 2 3 4 5 6 7 8 
  | <bean id="primaryAuthenticationHandler" 	class="org.jasig.cas.authentication.AcceptUsersAuthenticationHandler"> 	<property name="users"> 		<map> 			<entry key="casuser" value="Mellon" /> 		</map> 	</property> </bean> 
  | 
 
可以看到默认的用户名是 casuser,密码是 Mellon。

看到上图的页面,表明 cas server 已经部署成功。
CAS Server 配置基于数据库用户认证
回到 cas-4.1.8.zip 解压缩的目录,并进入 cas-server-support-jdbc 目录,在当前目录打开 cmd 并执行安装命令
1 
  | mvn -e -ff clean install -Dmaven.test.skip=true 
  | 
 
安装完成后在 target 目录得到 cas-server-support-jdbc-4.1.8.jar 文件。
将该文件拷贝到 apache-tomcat-7.0.72/webapps/cas/WEB-INF/lib 目录下,并向此目录添加 c3p0-0.9.1.2.jar,mysql-connector-java-5.1.17.jar 两个文件。嫌麻烦的话,点此下载这三个 jar 包的压缩包文件。
再次打开 apache-tomcat-7.0.72/webapps/cas/WEB-INF/deployerConfigContext.xml 文件,大概在第 54 行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 
  | <bean id="authenticationManager" class="org.jasig.cas.authentication.PolicyBasedAuthenticationManager">     <constructor-arg>         <map>                             | IMPORTANT                | Every handler requires a unique name.                | If more than one instance of the same handler class is configured, you must explicitly                | set its name to something other than its default name (typically the simple class name).                -->             <entry key-ref="proxyAuthenticationHandler" value-ref="proxyPrincipalResolver" />                          <entry key-ref="primaryAuthenticationHandler" value-ref="primaryPrincipalResolver" />             -->                          <entry key-ref="myAuthenticationHandler" value-ref="primaryPrincipalResolver" />         </map>     </constructor-arg>          <property name="authenticationMetaDataPopulators">        <util:list>            <bean class="org.jasig.cas.authentication.CacheCredentialsMetaDataPopulator"/>        </util:list>     </property>     -->             | Defines the security policy around authentication. Some alternative policies that ship with CAS:        |        | * NotPreventedAuthenticationPolicy - all credential must either pass or fail authentication        | * AllAuthenticationPolicy - all presented credential must be authenticated successfully        | * RequiredHandlerAuthenticationPolicy - specifies a handler that must authenticate its credential to pass        -->     <property name="authenticationPolicy">         <bean class="org.jasig.cas.authentication.AnyAuthenticationPolicy" />     </property> </bean> 
  | 
 
按以上配置注销掉第二个 entry 并添加一个 entry。接着在后面添加两个 bean 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
  | <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">     <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/cas_test_db?autoReconnect=true&useUnicode=true&characterEncoding=utf-8" />     <property name="user" value="root" />     <property name="password" value="root" />     <property name="driverClass" value="com.mysql.jdbc.Driver" />     <property name="initialPoolSize" value="10" />     <property name="maxIdleTime" value="1800" />     <property name="maxPoolSize" value="60" />     <property name="acquireIncrement" value="5" />     <property name="acquireRetryAttempts" value="60" />     <property name="acquireRetryDelay" value="2000" />     <property name="breakAfterAcquireFailure" value="false" />     <property name="autoCommitOnClose" value="false" />     <property name="checkoutTimeout" value="30000" />     <property name="idleConnectionTestPeriod" value="900" /> </bean> <bean id="myAuthenticationHandler" class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"      p:dataSource-ref="dataSource"      p:sql="SELECT passwd FROM user WHERE name = ?" /> 
  | 
 
其中 cas_test_db 数据库中的 user 建表语句为
1 2 3 4 5 6 
  | CREATE TABLE `user` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `name` varchar(255) NOT NULL,   `passwd` varchar(255) NOT NULL,   PRIMARY KEY (`id`) ) 
  | 
 
重启 tomcat,访问 https://www.fanlychie.com:8443/cas,用数据库中的 name/passwd 作为用户名和密码登录系统,若登录成功,表明配置已成功。
CAS Client 客户端使用和配置
使用 maven 创建两个 web 项目 cas-client1,cas-client2。点此下载 demo 文件。
cas-client1 项目 pom.xml 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 
  | <dependencies> 	<dependency> 		<groupId>org.jasig.cas.client</groupId> 		<artifactId>cas-client-core</artifactId> 		<version>3.4.0</version> 	</dependency> 	<dependency> 		<groupId>org.slf4j</groupId> 		<artifactId>slf4j-log4j12</artifactId> 		<version>1.7.12</version> 	</dependency> </dependencies> <build> 	<plugins> 		<plugin> 			<groupId>org.apache.tomcat.maven</groupId> 			<artifactId>tomcat7-maven-plugin</artifactId> 			<version>2.2</version> 			<configuration> 				<path>/</path> 				<port>8881</port> 				<httpsPort>8081</httpsPort> 				<uriEncoding>UTF-8</uriEncoding> 				<protocol>org.apache.coyote.http11.Http11NioProtocol</protocol> 				<clientAuth>false</clientAuth> 				<keystoreFile>C:\Users\fanlychie\.keystore\selfissue.jks</keystoreFile> 				<keystorePass>123654</keystorePass> 				<keystoreType>JKS</keystoreType> 				<url>http://localhost:8081/manager/html</url> 			</configuration> 		</plugin> 	</plugins> </build> 
  | 
 
首先必须确保项目 https 协议可以正常访问,否则 cas server 无法认证。
选中项目 -> Run As -> Maven build… -> tomcat7:run
访问 https://www.fanlychie.com:8081,若能访问到,表明 tomcat 已准备好。
cas-client1 项目 web.xml 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 
  | <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.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> 		<init-param> 			<param-name>casServerUrlPrefix</param-name> 			 			<param-value>https://www.fanlychie.com:8443/cas</param-value> 		</init-param> 	</filter> 	<filter-mapping> 		<filter-name>CAS Single Sign Out Filter</filter-name> 		<url-pattern>/*</url-pattern> 	</filter-mapping> 	 	<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>https://www.fanlychie.com:8443/cas/login</param-value> 		</init-param> 		<init-param> 			<param-name>serverName</param-name> 			 			<param-value>https://www.fanlychie.com:8081</param-value> 		</init-param> 	</filter> 	<filter-mapping> 		<filter-name>CAS Authentication Filter</filter-name> 		<url-pattern>/*</url-pattern> 	</filter-mapping> 	<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>https://www.fanlychie.com:8443/cas</param-value> 		</init-param> 		<init-param> 			<param-name>serverName</param-name> 			 			<param-value>https://www.fanlychie.com:8081</param-value> 		</init-param> 	</filter> 	<filter-mapping> 		<filter-name>CAS Validation Filter</filter-name> 		<url-pattern>/*</url-pattern> 	</filter-mapping> 	<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> 
  | 
 
以上是 cas client 标准配置,具体信息可参考 https://github.com/apereo/java-cas-client
cas-client2 配置基本与 cas-client1 配置相同,详情可见 demo,同时启动这两个项目
cas-client1 - https://www.fanlychie.com:8081
cas-client2 - https://www.fanlychie.com:8082
访问其中的一个项目 https://www.fanlychie.com:8081,会自动跳到 
https://www.fanlychie.com:8443/cas/login?service=https%3A%2F%2Fwww.fanlychie.com%3A8081%2F

由于还没有登录过 CAS 认证系统,CAS 认证系统拦截到你的访问,进入到认证系统登录界面,当登录成功后,CAS 服务会跳转向到你刚刚访问的地址。

当你访问 https://www.fanlychie.com:8082,此时是不需要登录了的

至此,CAS 实现 SSO 单点登录系统搭建结束。