转:CAS及客户端Acegi的安装配置指南

转:CAS及客户端Acegi的安装配置指南
  CAS及客户端Acegi的安装配置指南
作者:龙智  (Dragon)
时间: 2006-07-09
         CAS Central Authentication Service )是耶鲁大学开发的一个开源的 SSO single sign on ,单点登录)系统。它提供了丰富的客户端库,如 Java, .NET, PHP, Perl 等版本,使用这些库用户可以方便地给自己的应用程序加上 CAS 支持。 Acegi security system for Spring Spring 的一个子项目,它为 Java EE 开发者提供了一个易于使用的提供认证和授权服务的安全框架。 Acegi 支持 CAS ,也可看作是 CAS 的一个 Java 版的 Client
    以下详细介绍如何配置 CAS 以及应用程序,使其利用 Acegi CAS 进行用户的登录和认证。我将以 acegi-security-1.0.1 发布包中附带的 acegi-security-sample-tutorial 应用为例,它使用 DaoAuthenticationProvider 对用户进行认证,用户帐号和权限信息保存在一个 properties 文件中,我将对其进行改造,改造之后, acegi-security-sample-tutorial 使用 CAS 进行用户认证,授权信息仍从该 properties 文件读取,因为 CAS 只负责认证,不负责授权,所以授权工作交由客户端 Acegi 来完成, CAS 的用户源配置为数据库,利用 JDBC 进行读取。本文需要读者对 SSO Acegi 有一定的了解。

       一.准备工作

  • 下载并安装Tomcathttp://tomcat.apache.org/),本文使用的版本是5.5.15
  • 下载并安装MySQLhttp://www.mysql.com/),本文使用的版本是5.0.16
  • 下载CAS服务端(http://www.ja-sig.org/products/cas/),本文使用最新的3.0.5RC2
  • 下载CAS-JDBC Adapter http://developer.ja-sig.org/maven/cas/jars/cas-server-jdbc-3.0.5-rc2.jar);
  • 下载Acegihttp://acegisecurity.org/,本文使用的版本是1.0.1 

   二.安装CAS

   解压缩 cas-server-3.0.5-rc2.zip ,拷贝 target 目录中的 cas.war %CATALINA_HOME%/webapps 下即可。运行 Tomcat ,访问 http://localhost:8080/cas 应可看到 CAS 登录界面。
        

       三.配置Tomcat支持SSL

       由于 CAS 要求使用 https 和客户端进行通信,所以需要配置 Tomcat 支持 SSL ,首先介绍如何制作自签名证书以及将其导入到证书库。
1. keytool -keystore keystore -alias acegisecurity -genkey -keyalg RSA -validity 9999 -storepass password -keypass password
What is your first and last name?
  [Unknown]:  localhost
其他随便填写即可。
2. keytool -export -v -rfc -alias acegisecurity -file acegisecurity.txt -keystore keystore -storepass password
3. copy acegisecurity.txt %JAVA_HOME%\jre\lib\security  
4. copy keystore %CATALINA_HOME %
5. cd %JAVA_HOME%\jre\lib\security
6. keytool -import -v -file acegisecurity.txt -keypass password -keystore cacerts -storepass changeit -alias acegisecurity
       接下来,用编辑器打开 %CATALINA_HOME%/conf/server.xml ,找到
    <Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
       这一行默认是被注释掉的,取消注释,并加入 keystoreFile="keystore" keystorePass="password" 这两个属性,注意 keystoreFile 属性可以使用 keystore 文件的绝对路径,也可使用基于 %CATALINA_HOME% 环境变量的相对路径, keystorePass 是访问 keystore 的密码,应和上面制作证书时设定的密码保持一致。
       访问 https://localhost:8443 ,应弹出一个对话框,告知用户正要访问的站点的证书不安全,是否接受,确认接受,应可看到那只熟悉可爱的小猫。

   四.改造acegi-security-sample-tutorial

       解压缩 acegi-security-1.0.1.zip ,拷贝 acegi-security-sample-tutorial.war %CATALINA_HOME%/webapps 目录下,重启 tomcat acegi-security-sample-tutorial 即已发布。现在我们将其改造为使用 CAS 进行用户的登录和认证。
    用编辑器打开 WEB-INF/applicationContext-acegi-security.xml ,找到
       <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
                  <property name="authenticationManager" ref="authenticationManager"/>
                  <property name="authenticationFailureUrl" value="/acegilogin.jsp?login_error=1"/>
              <property name="defaultTargetUrl" value="/"/>
              <property name="filterProcessesUrl" value="/j_acegi_security_check"/>
              <property name="rememberMeServices" ref="rememberMeServices"/>
       </bean>
将其替换为:
       <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.cas.CasProcessingFilter">
              <property name="authenticationManager" ref="authenticationManager"/>
              <property name="authenticationFailureUrl" value="/acegilogin.jsp?login_error=1"/>
              <property name="defaultTargetUrl" value="/"/>
              <property name="filterProcessesUrl" value="/j_acegi_cas_security_check"/>
              <property name="rememberMeServices" ref="rememberMeServices"/>
       </bean>
其中, authenticationFailureUrl 是认证失败时显示的页面, acegi-security-sample-tutorial 登录失败时会在登录页 (acegilogin.jsp) 显示失败原因,现改为使用 CAS 之后, acegi-security-sample-tutorial 使用 CAS 的登录页面,故 acegilogin.jsp 可去掉。接下来,找到
              <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                     <property name="loginFormUrl" value="/acegilogin.jsp"/>
                     <property name="forceHttps" value="false"/>
              </bean>
替换为:
              <bean class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
                     <property name="loginUrl">
                            <value>https://localhost:8443/cas/login</value>
                     </property>
                     <property name="serviceProperties">
                            <ref bean="serviceProperties"/>
                     </property>
              </bean>
再接下来,找到
       <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
              <property name="providers">
                     <list>
                            <ref local="daoAuthenticationProvider"/>
                            <bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
                                   <property name="key" value="changeThis"/>
                            </bean>
                            <bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
                                   <property name="key" value="changeThis"/>
                            </bean>
                     </list>
              </property>
       </bean>
<ref local="daoAuthenticationProvider"/> 修改为 <ref local="casAuthenticationProvider"/> ,并添加以下 bean
       <bean id="casAuthenticationProvider" class="org.acegisecurity.providers.cas.CasAuthenticationProvider">
              <property name="ticketValidator">
                     <ref bean="ticketValidator"/>
              </property>
              <property name="casProxyDecider">
                     <ref bean="casProxyDecider"/>
              </property>
              <property name="statelessTicketCache">
                     <ref bean="statelessTicketCache"/>
              </property>
              <property name="casAuthoritiesPopulator">
                     <ref bean="casAuthritiesPopulator"/>
              </property>
              <property name="key">
                     <value>some_unique_key</value>
              </property>
       </bean>
    
       <bean id="ticketValidator" class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">
              <property name="casValidate">
                     <value>https://localhost:8443/cas/proxyValidate</value>
              </property>
              <property name="serviceProperties">
                     <ref bean="serviceProperties"/>
              </property>
       </bean>
    
       <bean id="serviceProperties" class="org.acegisecurity.ui.cas.ServiceProperties">
              <property name="service">
                     <value>https://localhost:8443/acegi-security-sample-tutorial/j_acegi_cas_security_check</value>
              </property>  
       </bean>
    
       <bean id="casProxyDecider" class="org.acegisecurity.providers.cas.proxy.RejectProxyTickets"/>
    
       <bean id="statelessTicketCache" class="org.acegisecurity.providers.cas.cache.EhCacheBasedTicketCache">
              <property name="cache">
                     <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
                            <property name="cacheManager">
                                   <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
                            </property>
                            <property name="cacheName" value="userCache"/>
                     </bean>
              </property>
       </bean>
    
       <bean id="casAuthritiesPopulator" class="org.acegisecurity.providers.cas.populator.DaoCasAuthoritiesPopulator">
              <property name="userDetailsService">
                     <ref bean="userDetailsService"/>
              </property>
       </bean>
改造完毕!
 

    五.配置CAS使用JDBC数据源进行用户认证

       CAS 默认设置为只要用户名和密码相同,即可进行登录,这在现实使用中是不允许的。我们修改为使用 MySQL test 数据库中的 app_user 表作为用户数据源。首先,我们在 test 库中创建一个表:
CREATE TABLE `app_user` (
  `username` varchar(30) NOT NULL default '',
  `password` varchar(45) NOT NULL default '',
  PRIMARY KEY  (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
并添加如下用户:
INSERT INTO `app_user` (`username`,`password`) VALUES
 ('dianne','emu'),
 ('marissa','koala'),
 ('peter','opal'),
 ('scott','wombat');
用编辑器打开 %CATALINA_HOME%/webapps/cas/WEB-INF/deployerConfigContext.xml ,找到
    <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
注释掉该行,在其下加入:
<bean class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler">
                            <property name="sql" value="select password from app_user where username=?" />
                            <property name="dataSource" ref="dataSource" />
                     </bean>
并添加一个 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/test</value></property>
       <property name="username"><value>test</value></property>
       <property name="password"><value>test</value></property>
    </bean>
拷贝 cas-server-jdbc-3.0.5-rc2.jar mysql-connector-java-3.1.12-bin.jar %CATALINA_HOME%/webapps/cas/WEB-INF/lib 下。
 
    重新启动 tomcat ,在浏览器中输入 http://localhost:8080/acegi-security-sample-tutorial ,你会发现,一旦你访问了受保护的页面,请求就会被重定向到 CAS 的登录页面,登录成功之后请求会被再被定向到最初访问的页面,如果有多个系统,在这些系统之间进行切换将不会要求用户重新登录,这就达到了单点登录的目的.

 

参考文献:

  • Acegi security官方网站及文档:http://acegisecurity.org
  • CAS官方网站及文档:http://www.ja-sig.org/products/cas
  • SSL Configuration HOW-TOhttp://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html
  • 利用CAS实现SSO技术:http://kb.csdn.net/java/Articles/200606/2e082aae-775d-48be-b2fb-c2e218af9ba9.html

你可能感兴趣的:(转:CAS及客户端Acegi的安装配置指南)