企业的信息化过程是一个循序渐进的过程,在企业各个业务网站逐步建设的过程中,根据各种业务信息水平的需要构建了相应的应用系统,由于这些应用系统一般是在不同的时期开发完成的,各应用系统由于功能侧重、设计方法和开发技术都有所不同,也就形成了各自独立的用户库和用户认证体系。随着新的业务网站不断的增加,用户在每个应用系统中都有独立的账号,这样就造成在访问不同的应用系统时,需要记录对应的用户名和密码,多个用户名密码极易记混,如果忘记或记错了某一个业务网站的用户名或密码就无法进行登录,耽误工作,影响工作效率,随着局内信息化进程的推进还会有新的应用系统产生,如果不引入单一用户登录的解决方案,全公司工作人名特别是承担审批权限的各级领导很难记清各类应用系统的用户名和密码,严重影响由信息化带来快捷性和高效性。此外,多个应用平台就有多个用户管理,这也为系统管理员维护人员系统带来巨大的工作量,例如,一次变更10个人员,即使只有5个应用系统,也需要重复维护50个人员信息,而企业的每次人员调整远不至10人,这种几何增长的维护工作量,会浪费大量的精力和时间,减弱了信息化系统带来方便快捷,为此,需建立一套统一的、完善的、科学的单点登录系统,每个用户只需记录一个用户名密码,登录一个平台后即可实现各应用系统的透明跳转,而且实行统一的用户信息管理系统,系统管理员只需维护一套人员信息,更改信息通过平台接口同步更新至各个应用系统,实现人员系统单次维护全公司同步变更,大大提高工作效率。
环境:redhat5.0 enterprise
tomcat 5.5
mysql-5.0.22-2.1.0.1
单点登录系统简介,这是引用别人的原话,原文地址是http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html
|
|
CAS 介绍
CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:
- 开源的企业级单点登录解决方案。
- CAS Server 为需要独立部署的 Web 应用。
- CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
CAS 原理和协议
从 结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。图1 是 CAS 最基本的协议过程:
图 1. CAS 基础协议
<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" alt="CAS 基础协议" style='width:350.25pt;height:255.75pt'> <v:imagedata src="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg" o:href="http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/images/image001.jpg" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份合适,以确保 Service Ticket 的合法性。
在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保,ST 和 TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。
另外,CAS 协议中还提供了 Proxy (代理)模式,以适应更加高级、复杂的应用场景,具体介绍可以参考 CAS 官方网站上的相关文档。
首先下载CAS server和client
到 CAS 官方网站下载 CAS Server 和 Client,地址分别为:
http://www.jasig.org/cas/download
http://www.ja-sig.org/downloads/cas-clients
我下载的是cas-client-java-3.0.0.zip和cas-server-3.3.1-release.tar.gz这两个包。
由于CAS认证是基于SSL协议的,所以我们先安装SSL证书。(注,下面命令中黄色的字体代表用户自己设置的值)
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore "/usr/local/tomcat/server.keystore"
接下来会让你设置密码,然后注意填写姓名的时候填写localhost,这是考虑到后面连接数据库。然后后面随便写。
然后导出证书
$JAVA_HOME/bin/keytool -export -alias tomcat -file server.cert -keystore "/usr/local/tomcat/server.keystore"
然后导入到我们的授权证书中
$JAVA_HOME/bin/keytool -import -trustcacerts -file server.cert -keystore $JAVA_HOME/jre/lib/security/cacerts (注,这时输入默认的密码:changeit)
这时证书就安装完毕了。
下面修改配置文件,首先修改tomcat/conf/server.xml,找到下面这段关于SSL的语句
<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="/usr/local/tomcat/server.keystore" keystorePass="123456"这两句,这是定义你自己的设置的keystore路径和密钥的密码。如果你使用默认的,(keystore 放在tomcat下,keystorePass为changeit)那么不用加这两句话。
接下来解压下载的CAS-server文件包cas-server-3.3.1-release.tar.gz,把其中的moudules中的cas-server-webapp-3.3.1.war复制到tomcat/webapps目录下,并且改名为cas.war,这个文件会自动解压生成个cas的目录
,到这里,由于已经布置好了SSL协议,可以检验一下SSL是否成功了,重启tomcat,然后打开浏览器输入https://localhost:8443/cas
如果能出现正常的 CAS 登录页面,则说明 CAS Server 已经部署成功。
下面是关键的一步:扩展认证接口
CAS 提供扩展认证的核心是 AuthenticationHandler 接口,这里要看详细的介绍还是去http://www.ibm.com/developerworks/cn/opensource/os-cn-cas/index.html,或者CAS的官网www.jasig.org/cas。
我使用的是通过JDBC认证
这里要连接数据库,通过将用户输入的用户名和密码,和数据库中的数据对照,如果数据库中存在,那么通过,如果没有,那么认证失败,用户不能登录。
具体做法如下:
首先在数据库中添加一个用户casserver,密码是casserver。然后添加database cas,添加个一个tables app_user,并赋值给他。
mysql> create databases cas;
mysql> use cas;
mysql> create table app_user (username varchar(30) not null default'', password varchar(45) not null default'', primary key (username));
mysql> insert into app_user (username,password) values ('test01','psw01'),('test02','psw02');
找 到刚才解压到tomcat/webapps的那个cas包,修改在cas/WEB-INF/目录下的deployerConfigContext.xml 文件。找到这段话<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
由于我使用的是mysql数据库,因此在后面添加
<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://192.168.2.137:3306/cas</value></property>
<property name="username"><value>casserver</value></property>
<property name="password"><value>casserver</value></property>
</bean>
再找到这段话
<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>
接下来,要实现功能,还得要添加一些必要的模块驱动,如mysql.jar等,总共七个文件,我是全部放进去了:
spring-jdbc.jar commons-dbcp-1.2.2.jar
mysql.jar commons-collections-3.2.1.jar
mysql-connector-java-3.1.11-bin.jar cas-server-support-jdbc-3.3.1.jar
commons-pool-1.3.jar
将他们全都拷贝到tomcat/webapps/cas/WEB-INF/lib。
到这里就OK了,这时再重启tomcat,打开https://localhost:8443/cas
会发现如果输入的用户名和密码和数据库中的不一致,认证就不能通过。这表明数据库认证已经起作用了。
注:以上命令在写此文时均再次执行过,都顺利通过。
二、部署CAS客户端
<!-- 一、安装SSL
这里拿客户端机器B来做,首先客户端自己也要安装SSL协议。步骤和服务器版本的一样。在tomcat/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="/usr/local/tomcat/client.keystore" keystorePass="changeit",这个看你自己高兴设置密码了。
接下来,依次:
#$JAVA_HOME/bin/keytool -genkey -alias client -keyalg RSA -keystore /usr/local/tomcat/client.keystore
#$JAVA_HOME/bin/keytool -export -alias client -file client.cert -keystore /usr/local/tocmat/client.keystore
#$JAVA_HOME/bin/keytool -import -alias client -file client.cert -keystore $JAVA_HOME/jre/lib/security/cacerts
-->
今天又做了一次,上面的步骤是可以省略的。。。,部署客户端可以直接从下面开始。。。
二、安装服务器证书
现在我们要和服务器端取得信任关系:
下载http://blogs.sun.com/andreas/entry/no_more_unable_to_find 的 InstallCert.java,这个文件下来后是源代码,还需执行“javac InstallCert.java”,生成InsallCert.class,InstallCert$SavingTrustManager.class这两个文件,然后运行“ java InstallCert compA:8443 ”命令,并且在接下来出现的询问中输入 1。这样,就将 A服务器添加到了 B 的 trust store 中。如果多个客户端应用分别部署在不同机器上,那么每个机器都需要与 CAS Server 所在机器建立信任关系。
其实,可以这样,首先建立一个空文白件,名字叫做InstallCert.java,然后复制blogs.sun.com/andreas/resource/InstallCert.java里面的内容放进去,执行“javac InstallCert.java”,生成InsallCert.class,InstallCert$SavingTrustManager.class这两个文件,然后运行“ java InstallCert compA:8443 ”命令,并且在接下来出现的询问中输入 1。
那么进行上面这个步骤以后,会有一个jsscacerts的文件,记住:移动这个文件到$JAVA_HOME/jre/lib/security中,也就是和cacerts这个文件在同一个目录。不然会报错哦,我的另一篇文章就是记录这种错误的,里面有错误代码,有兴趣的可以对照一下。
三、编辑客户端配置文件
以tomcat/webapps/jsp-examples这个为例子吧,下载一个cas-client-2..11.zip包,解压后将cas-client-2.0.11/java/lib目录下的casclient.jar这个包复制到jsp-examples中WEB-INF/lib 下,并编辑jsp-examples/WEB-INF/web.xml文件,添加以下代码
<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://domainA:8443/cas/login</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>
<param-value>https://domainA:8443/cas/serviceValidate</param-value>
</init-param>
<init-param>
<param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>
<param-value>domainB:8080</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CAS Filter</filter-name>
<url-pattern>/protected-pattern/*</url-pattern>
</filter-mapping>
这里面domainA,domainB域名或者IP都可以,不过很多人建议域名,还没有测试这两者的差距,因为没时间再弄个域名服务器。
四、测试效果
现在打开http://domainB:8080/jsp-examples,浏览器会弹出安全提示,接受后即转到 CAS 的登录页面,填入前面你在数据库里面设定的用户名和密码,好了,页面就转到jsp-examples/index.html了。其实就是你访问这个页面中间去SERVER上验证了一下,又回头了。