到下载页面下载以下3个zip包:
第一个,CAS Server,这个是CAS的服务器端(当前最新版本是3.5.1)

服务端下载地址:http://www.jasig.org/cas/download

第二个,JA-SIGCAS Java Client,这个是官方开发的CAS的客户端,用于单点退出。特别注意事项:当前只有3.1.2及以上版本支持单点退出(当前最新版本是3.2.1)
客服端下载地址:http://downloads.jasig.org/cas-clients/

第三个,Yale CAS Client,这个是耶鲁大学开发的CAS的客户端,用于单点登录,不支持单点退出(当前最新版本是2.0.11)

1.下载cas-server和cas-client(可选,建议使用)
http://www.yale.edu/tp/cas/cas-server-2.0.12.zip
http://www.yale.edu/tp/cas/cas-client-2.0.11.zip     (下面我使用的是cas-client-2.0.11)


Tomcat 下配置CAS,首先要让Tomcat支持SSL,要产生证书之类的,命令简单介绍如下:
生成密匙:

keytool -genkey -alias tomcat -keystore ./mykeystore -keyalg RSA -validity 2000

-keyalg RSA 指的是采用的RSA算法 

输入密码:danding

姓名:据说要输入服务器域名,本机测就localhost吧

会在该目录下生成mykeystore文件

导出证书,命令

keytool -export -alias tomcat -keystore ./mykeystore -file server.crt

密码和上面一样

会在该目录下生成一个server.crt 文件

然后把该证书导入jdk下

以我自己的mac为例

keytool -import -file server.crt -keystore /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib/security/cacerts

导入到security目录下



配置tomcat   服务器端:

修改tomcat里的server.xml配置文件,讲一下一段去掉注释(正常情况下是注掉的),并加上keystoreFile="c:/resource/cas/mykeystore ",keystorePass="danding"

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"

       maxThreads="150" scheme="https" secure="true"

       clientAuth="false" sslProtocol="TLS"

           keystoreFile="mykeystore"

       keystorePass="danding"/>

最好把mykeystore文建移到tomcat目录下,在mac下总是在写的路径下自动加上tomcat的路径,例如.../tomcat/mykeystore



将我们下载的cas-server包解压modules目录下有个cas-server的打包文件,放到tomcat的webapps目录下

启动tomcat后,输入http://localhost:8080/cas/login和https://localhost:8443/cas/login都可以访问的



配置tomcat客户端:

端口改为8180就行了

新建一个grails项目 名字:testCase1

引入包:cas-client-2.0.11\cas-client-2.0.11\java\lib\casclient.jar(用于单点登陆)

引入包:cas-client-3.2.1-release\cas-client-3.2.1\modules目录下的cas-client-core-3.2.1.jar(用于单点退出)

引入包:cas-client-3.2.1-release\cas-client-3.2.1\modules目录下的commons-logging-1.1.jar(用于单点退出)

在testCase1的web.xml中增加如下代码:

grails项目下找不到web.xml,用grails install-templates命令生成就有了

然后在web.xml文件中写过滤器的配置就可以了!!!

<!-- 用于单点退出 -->
<listener>
   <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener<stener-class>
<stener>
<filter>
    <filter-name>CAS Single Sign Out Filter</filter-name>
    <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<!-- 用于单点登录 -->
<filter>
<filter-name>CAS Filter</filter-name>
<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>
    <init-param>
      <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>
       <param-value>https://localhost:8443/cas/login</param-value>
<!--这里的server是服务端的IP-->

    </init-param>
    <init-param>
       <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
       <param-value>https://localhost:8443cas/serviceValidate</param-value>
<!--这里的ServerName是服务端的主机名也就是CN-->

    </init-param>
    <init-param>
       <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
       <param-value>localhost:8180</param-value> 
<!--client:port就是需要cas需要拦截的地址和端口,一般就是这个tomcat所启动的ip和port-->

    </init-param>
</filter>
<filter-mapping>
    <filter-name>CAS Single Sign Out Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>CAS Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<!--下面的filter根据需要配置-->
<!--


        该过滤器负责实现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>
<!--
        该过滤器使得开发者可以通过org.jasig.cas.client.util.AssertionHolder
        来获取用户的登录名,      比如AssertionHolder.getAssertion().getPrincipal().getName()。
-->
<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>
<!-- 自动根据单点登录的结果设置本系统的用户信息 -->
<filter>
        <display-name>AutoSetUserAdapterFilter</display-name>
        <filter-name>AutoSetUserAdapterFilter</filter-name>
        <filter-class>
                com.cas.client.filter.AutoSetUserAdapterFilter
        </filter-class>
</filter>
<filter-mapping>
        <filter-name>AutoSetUserAdapterFilter</filter-name>
        <url-pattern>/*</url-pattern> </filter-mapping>



AutoSetUserAdapterFilter类设置登录用户session信息代码如下:
public class AutoSetUserAdapterFilter implements Filter{
        public void destroy() {
        }
        /**
         * 过滤逻辑:首先判断单点登录的账户是否已经存在本系统中,       
         * 如果不存在使用用户查询接口查询出用户对象并设置在Session中  
         */
        public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain) throws IOException, ServletException {
                   HttpServletRequest httpRequest = (HttpServletRequest) request;  
               // _const_cas_assertion_是CAS中存放登录用户名的session标志          
          Object object = httpRequest.getSession().getAttribute("_const_cas_assertion_"); 
          if (object != null) {                    
                  Assertion assertion = (Assertion) object;  
                  String loginName = assertion.getPrincipal().getName();  
                  System.out.println("登录名为:"+loginName);
                  // 接下来在本业务系统中根据用户名获取用户对象,判断session中是否存在,
                  // 如果不存在,则获取用户对象保存到session中,否则直接获取用户对象。                
          }
          chain.doFilter(request, response);
        }
        public void init(FilterConfig filterConfig) throws ServletException {
        } }




测试:同时将testCase1和cas发布一下,访问http://localhost:8180/testCase1,将自动跳转到服务端的登录页面,填写相同的用户名和密码,则成功登录并跳转回客户端的。

测试单点登录和退出:

再创建grails工程,名字:testCase2

同时部署server,testCase1,testCase2

测试1:访问testCase1,登录后可以直接访问testCase2

测试2:访问testCase2,登录后可以直接访问testCase1

测试3:登录testCase1,退出后可以不可访问testCase1和testCase2

如何退出?访问https://localhost:8443/cas/logout就退出了。

注意事项:访问形如http:// localhost:8080/cas_server/logout,这种通过http方式访问退出是不行的!!因为你不通过https来注销,CAS Server怎么"杀"掉它通过https发给你的TGC Cookie?

至此,基本完成单点登录和退出功能。



如果跳转的时候出现了unable to find valid certification path to requested target错误怎搞?

该错误是机子有多个jdk版本,运行多个项目时使用的可能不是同一个版本,解决方法是,把证书导入到使用的jdk版本里。



通过直接访问数据库定制密码验证

1.新建数据库cas,在建一个user表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `username` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
 

INSERT INTO `user` VALUES ('1', '1');



2.加入包到webapps\cas\WEB-INF\lib:
mysql-connector-java-5.1.5-bin.jar
cas-server-support-jdbc-3.3.1.jar(来自于cas-server-3.3.1.zip)
   spring-jdbc-2.5.5.jar



3. 在webapps\cas\WEB-INF\deployerConfigContext.xml文件中加入dateSource的Bean
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">

          <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>

          <property name="url"><value>jdbc:mysql://localhost:3306/cas</value></property>

          <property name="username"><value>root</value></property>

          <property name="password"><value></value></property>

</bean>

4. 在deployerConfigContext.xml文件中
注释掉:
       <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePassword

AuthenticationHandler" />

换成:
       <bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
       <property name="dataSource" ref="casDataSource" />
       <property name="sql" value="select password from user where username=?" />
    <property name="passwordEncoder" ref=" passwordEncoder "/>

       </bean>



安全证书到期了怎么办?
只要重新向jdk中导入证书就行了
inmatoMacBook-Pro:sso root# keytool -import -file server.crt -keystore /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home/lib/security/cacerts输入密钥库口令:
所有者: CN=localhost, OU=nala, O=nala, L=杭州市, ST=浙江省, C=cn
发布者: CN=localhost, OU=nala, O=nala, L=杭州市, ST=浙江省, C=cn
序列号: 60e4240a
有效期开始日期: Wed Nov 07 16:54:06 CST 2012, 截止日期: Mon Apr 30 16:54:06 CST 2018
证书指纹:
      MD5: 94:73:8A:06:7B:4C:DF:09:5C:D4:F0:CE:9D:2C:DC:9E
      SHA1: E5:F1:73:9F:FD:04:33:85:7F:AD:7F:2E:51:12:63:60:CC:8E:4C:C4
      SHA256: B5:70:1C:04:97:99:CA:2B:9D:C6:B7:BF:04:29:7D:CB:E9:3E:87:00:7B:C9:0E:4F:2B:93:3D:88:4D:81:85:E8
      签名算法名称: SHA256withRSA
      版本: 3


扩展:


#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F8 B5 EE B4 7F 5E 01 53   06 D2 79 01 10 43 51 AE  .....^.S..y..CQ.
0010: D8 23 E7 0A                                        .#..
]
]


是否信任此证书? [否]:  y
证书已添加到密钥库中



mac下亲测,可行