jasig CAS实现单点登录(数据库认证)

之前转载了一篇IBM的CAS单点登录实现,不过瘾,于是到官网弄下最新版本来再战一把:

这个CAS(Central Authentication Service)是耶鲁大学的开源项目,旨在实现企业应用单点登录,还是很不错的,牛b的大学确实不一样,不是我们这些2b学校式的教育。其官网http://www.jasig.org/cas,很不幸,应该翻了墙才能进去,建议就GoAgent足已。

  • 实验环境:
?
1
2
3
4
5
6
1.jdk7_45
2.tomcat7_45
3.三台虚拟机:
    1.tomcat1(部署cas验证服务器)
    2.tomcat2(其中部署了两个web应用cas-web-client, cas-web-client2)
    3.mysql server一台(直接到数据库种验证)
  • 原理图:


  • 资源下载地址:

       http://downloads.jasig.org/

       解压之,jar会再modules目录下,其他都为源代码项目

       已经打包的server:

       client:

------------------------------------------------------

开始搭建:

  • CAS服务器配置:

1.在tomcat1所在机器生成证书:

这时会在用户主目录下生成.keystore文件,这个文件也可在上述命令种指定,其中生成过程会填入一些信息,注意输入第一个时(名字与姓氏)就输入你本机器的域名(不能时IP), 这里我的是www.tomcat1.com:

2.导出证书(后面将其导入客户端的jre环境中):

于是在用户主目录下就有了ssotest.crt证书文件(保留着,待会客户端配置要用),

3.配置Tomcat SSL: ${TOMCAT_HOME}/conf/server.xml中83-93行修改为:

?
1
2
3
4
5
6
7
8
9
10
<!-- Define a SSL HTTP/1.1 Connector on port 8443
    This connector uses the JSSE configuration, when using APR, the
    connector should be using the OpenSSL style configuration
    described in the APR documentation -->
<!-- configure ssl -->
< Connector port = "8443" protocol = "HTTP/1.1" SSLEnabled = "true"
          maxThreads = "150" scheme = "https" secure = "true"
          clientAuth = "false" sslProtocol = "TLS"
          keystoreFile = "/home/tomcatadmin/.keystore"
          keystorePass = "ssotest" />

4.将上面下载资源中的cas-server-webapp-3.5.2.war改名为cas.war, 复制到${TOMCAT_HOME}/webapps/下,启动tomcat,这时进入https://www.tomcat1.com:8443/cas/, 见下图,则服务端已经配置ok:

这时输入用户名及密码(保持一样就可以,默认CAS验证方式只要用户名密码一样就行), 可见其默认验证实现类SimpleTestUsernamePasswordAuthenticationHandler:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final class SimpleTestUsernamePasswordAuthenticationHandler extends
     AbstractUsernamePasswordAuthenticationHandler {
 
     public boolean authenticateUsernamePasswordInternal( final UsernamePasswordCredentials credentials) {
         final String username = credentials.getUsername();
         final String password = credentials.getPassword();
 
         if (StringUtils.hasText(username) && StringUtils.hasText(password)
             && username.equals(getPasswordEncoder().encode(password))) { //用户名及密码相同就成功
             return true ;
         }
         return false ;
     }
}

这样CAS服务端就默认配置完毕了,待会儿我们还要配置数据库验证。

  • 配置web客户端:

      1.生成.keystore(同上);

      2.将CAS服务端的导出ssotest.crt证书拷贝到某目录,并且导入到客户端机器的jre运行环境中:      

?
1
2
keytool - import -keystore $JAVA_HOME /jre/lib/security/cacerts - file ~ /ssotest .crt - alias ssotest
# NOTE: 有可能会有异常:java.io.IOException: Keystore was tampered with, or password was incorrect. 那就先删除本机上述的cacerts文件。

       3.配置客户端Tomcat SSL(同上);

       4.新建WEB项目cas-web-client, 并加入依赖包:cas-client-core-3.2.1.jar,commons-logging-1.1.jar

       5.配置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
<? xml version = "1.0" encoding = "UTF-8" ?>
< web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns = "http://java.sun.com/xml/ns/javaee" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id = "WebApp_ID" version = "2.5" >
     < display-name >cas-web-client2</ display-name >
     < listener >
         < listener-class >
             org.jasig.cas.client.session.SingleSignOutHttpSessionListener
         </ listener-class >
     </ listener >
     < 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 >CASFilter</ filter-name >
        < filter-class >org.jasig.cas.client.authentication.AuthenticationFilter</ filter-class >
         < init-param >
             < param-name >casServerLoginUrl</ param-name > <!-- Cas Server登录url-->
             < param-value >https://www.tomcat1.com:8443/cas/login</ param-value >
         </ init-param >
         < init-param > <!-- 配置当前web应用所在的web服务器域名url -->
             < param-name >serverName</ param-name >
             < param-value >http://www.tomcat2.com:8080</ param-value >
         </ init-param >
     </ filter >
     < filter-mapping >
         < filter-name >CASFilter</ filter-name >
         < url-pattern >/*</ url-pattern >
     </ filter-mapping >
     < filter >
         < filter-name >CasTicketFilter</ filter-name >
         < filter-class >
             org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</ filter-class >
         < init-param >
             < param-name >casServerUrlPrefix</ param-name >
             < param-value >https://www.tomcat1.com:8443/cas</ param-value >
         </ init-param >
         < init-param >
             < param-name >serverName</ param-name >
             < param-value >http://www.tomcat2.com:8080</ param-value >
         </ init-param >
     </ filter >
     < filter-mapping >
         < filter-name >CasTicketFilter</ filter-name >
         < url-pattern >/*</ url-pattern >
     </ filter-mapping >
     < filter >
         < filter-name >CasRequestWrapFilter</ filter-name >
         < filter-class >
             org.jasig.cas.client.util.HttpServletRequestWrapperFilter</ filter-class >
     </ filter >
     < filter-mapping >
         < filter-name >CasRequestWrapFilter</ filter-name >
         < url-pattern >/*</ url-pattern >
     </ filter-mapping >
     < filter >
         < filter-name >AssertionThreadLocalFilter</ filter-name >
         < filter-class >org.jasig.cas.client.util.AssertionThreadLocalFilter</ filter-class >
     </ filter >
     < filter-mapping >
         < filter-name >AssertionThreadLocalFilter</ filter-name >
         < url-pattern >/*</ url-pattern >
     </ filter-mapping >
     < welcome-file-list >
         < welcome-file >index.jsp</ welcome-file >
     </ welcome-file-list >
</ web-app >

这样cas-web-client就完成了,拷贝一份为另一个web客户端cas-web-client2:


启动Cas Server所在tomcat(Tomcat1),再启动web客户端所在tomcat(Tomcat2),此时我们访问两个web客户端:

http://www.tomcat2.com:8080/cas-web-client/index.jsp

http://www.tomcat2.com:8080/cas-web-client2/index.jsp

都会被重定想到CAS Server登录界面,登录成功其中之一(将看到对应的index.jsp),再刷新另一个(也能看到对应的index.jsp了,因为已经登录过了), 这就算服务端和客户端都配置OK了。

------------------------------------------------------

  • 现在就是要定制我们自己的验证方式(基于数据库验证):

      1.新建WEB项目cas-auth-server,你需要将cas-server-webapp-3.5.2.war中的资源对应拷贝到项目中,再把下载包中cas-server-webapp的源码考到项目中,由于基于数据库验证,还得将cas-server-support-jdbc-3.5.2.jar和mysql-connector驱动包拷贝到WEB-INF/lib目录下,这样就构成了纯净的cas server项目,当然你也可以通过maven去构建,官网也有说明,如图:

      2.我们要做的是修改一些配置,就是WEB-INF/deployerConfigContext.xml文件,先配置mysql数据源:

?
1
2
3
4
5
6
7
<!-- DataSource,根据你的环境来定 -->
< bean id = "mysqlDataSource" class = "org.apache.commons.dbcp.BasicDataSource" >
      < property name = "driverClassName" value = "com.mysql.jdbc.Driver" />
      < property name = "url" value = "jdbc:mysql://192.168.141.129:3306/blog?useUnicode=true&amp;characterEncoding=utf-8" />
      < property name = "username" value = "mysqladmin" />
      < property name = "password" value = "mysqladmin" />
</ bean >

      3.修改 authenticationManager bean的属性 authenticationHandlers:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
< property name = "authenticationHandlers" >
     < list >               
         < bean class = "org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref = "httpClient" />
         <!--注释掉默认的的认证实现<bean
         class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />-->
         <!-- 数据库查询认证处理器 -->
         < bean class = "org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler" >
             < property name = "dataSource" ref = "mysqlDataSource" />
             < property name = "sql"
                 value = "select password from t_user where username = ?" />
             < property name = "passwordEncoder" ref = "myPasswordEncoder" ></ property >
     </ bean >          
     </ list >
</ property >
?
1
2
<!-- 自己定义的密码转译器,你可以自己定义,也可以用CAS提供的 -->
< bean id = "myPasswordEncoder" class = "org.jasig.cas.custom.encoder.MyPasswordEncoder" />


这样就配置完成了,将项目导出war包,并部署到tomcat1所在机器上运行起来,效果会之前一样。

收工。

猜你喜欢

转载自tkggft.iteye.com/blog/2219997