转: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
有一定的了解。
一.准备工作
- 下载并安装Tomcat(http://tomcat.apache.org/),本文使用的版本是5.5.15;
- 下载并安装MySQL(http://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);
- 下载Acegi(http://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-TO:http://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