一 CAS简介
1.1 CAS介绍
随着企业信息化的快速发展,企业内业务系统的建设也越来越完善,但信息化建设是个循循渐进的过程,在建设的过程中每个业务系统可能用到的技术、开发语言、功能侧重、设计架构及方法都不同,也就形成了每个系统独立的认证数据库及认证方式(用户名/密码、证书登录、短信认证、动态令牌)的不同。
对用户来说,用户在每个应用系统中都有独立的账号,这样就造成在访问不同的应用系统时,需要记录对应的用户名和密码,多个用户名密码极易记混,如果忘记或记错了某一个业务网站的用户名或密码就无法进行登录,耽误工作,影响工作效率,随着企业信息化进程的推进还会有新的应用系统产生,如果不引入单一用户登录的解决方案,全公司工作人名特别是承担审批权限的各级领导很难记清各类应用系统的用户名和密码,严重影响由信息化带来快捷性和高效性。
对管理员来说,多个应用系统就有多个用户管理,这也为系统管理员维护人员系统带来巨大的工作量,例如,一次变更10个人员,即使只有10个应用系统,也需要重复维护100个人员信息,而企业的每次人员调整远不至10人,企业的业务系统也是在不断地建设,这种几何增长的维护工作量,会浪费大量的精力和时间,减弱了信息化系统带来方便快捷。
从信息共享角度,现有的各个业务系统都使用各自的数据存储方式,不经过基础的用户名和密码认证后,相互之间无法传递有效信息。为避免信息孤岛的产生,因此需要建立一个连接各个业务系统的技术架构和标准,实现平台统一化整合;通过对业务处理和异常处理实现监管透明;通过将业务流程从应用中抽离,实现业务流程的灵活安排,这样就需要一套可以整合现有各个业务网站的信息共享平台。
为此,需建立一套统一的、完善的、科学的单点登录系统,每个用户只需记录一个用户名密码,登录一个平台后即可实现各应用系统的透明跳转,而且实行统一的用户信息管理系统,系统管理员只需维护一套人员信息,更改信息通过平台接口同步更新至各个应用系统,实现人员系统单次维护全公司同步变更,大大提高工作效率。
单点登录的英文名称为Single Sign-On,简写为SSO,它是一个用户认证的过程,允许用户一次性进行认证之后,就访问系统中不同的应用;而不需要访问每个应用时,都重新输入密码。IBM对SSO有一个形象的解释“单点登录、全网漫游”。
本文要说的Cas(全称Centeral Authentication Service)即是对单点登录SSO(Single Sign On)的一种实现。其由Cas Server和Cas Client两部分组成,Cas Server是核心,而Cas Client通常就对应于我们的应用。一个Cas Server可以对应于多个Cas Client。它允许我们在一个Client进行登录以后无需再让用户输入用户名和密码进行认证即可访问其它Client应用。
1.2 单点登录、统一用户、单一用户
谈起单点登录时,常常和统一用户、单一用户理解混淆,要么误认为单点登录自然实现了单一用户管理;要么误认为统一用户或者单一用户就是单点登录。实际上,这三个概念是有明确区别的,
统一用户值不同的系统,使用同一套用户处理的机制。
用户ID、用户登录名、登录密码全局唯一,并且统一存储在单一系统中(如:统一用户管理系统)。
用户的一些属性,如姓名、电话、地址、身份证号、邮件等统一存储在单一系统中,尽管各应用系统可以自行增加一些属性(如:学历、籍贯等),单是基本属性应该统一存储和管理。
应用系统不应该直接对用户信息进行增加、修改、和删除,但是可以进行查询。对用户信息的增删改操作应该由专门的系统(如:统一用户管理系统)进行统一的管理。
很显然,统一用户是单点登录的基础,即要建设单点登录,首先要实现统一用户的建设。但是,统一用户并不意味着实现了单点登录。
单一用户管理则指所有的用户管理工作都在唯一的地方进行处理,而每个应用系统不再保留自己的用户管理功能。单一用户管理和统一用户管理最大的区别在于,统一用户管理之后,每个应用系统仍然保留自己的用户管理,用户额外的属性设置,角色分配、权限管理;而单一用户管理时,每个应用系统都不再保留自己的用户管理功能。
二 CAS特性
2.1 CAS优点
SSO将一个企业内部所有域中的用户登录和用户帐号管理集中到一起,SSO的好处显而易见:
减少用户在不同系统中登录耗费的时间,减少用户登录出错的可能性
实现安全的同时避免了处理和保存多套系统用户的认证信息
减少了系统管理员增加、删除用户和修改用户权限的时间
增加了安全性:系统管理员有了更好的方法管理用户,包括可以通过直接禁止和删除用户来取消该用户对所有系统资源的访问权限
2.2 CAS缺点
对于CAS单点登录,也会经常提到的一些问题包括:
难以重构。对 SSO 解决方案进行重构来适应现有的应用程序很困难,个性化定制复杂、很耗费时间、服务端和客户端负载均衡不理想等。
无人看守的桌面。实现 SSO 会减少一些安全风险,但是也增加了其他安全风险。例如,如果用户登录之后离开了他的机器,恶意用户就可以访问他的资源。尽管这是一个普遍存在的安全问题,但是 SSO 会使这个问题更加严重,因为恶意用户可以访问所有获得授权的资源。在采用多次登录方式时,用户每次只能登录进一个系统,所以只有一个资源被泄露。
单点攻击。在使用单点登录时,所有应用程序使用一个集中的身份验证服务。对于希望实施拒绝服务攻击的黑客,这是一个有吸引力的目标。如果cas宕机,从逻辑上来说就是所有的系统全部宕机了很耗费时间而且昂贵,
所以,CAS 并非毫无缺点。但在用户、管理员和开发人员看来,它的优点要超过缺点。
三 CAS运行原理
SSO的实现机制不尽相同,大体分为Cookie机制和Session机制两大类,而CAS即是采用Cookie机制。
3.1 Cookie实现单点登录的原理
首先,单点登录分为“服务端”和“客户端”。服务端就是单点登录服务器,而客户端通常是“函数库”或者“插件”。需要使用单点登录的应用程序,需要把客户端插件(如:客户端jar包)安装到自己的系统中,或者将客户端函数库包括在代码中。单点登录的客户端通常替换了原来应用程序的认证部分的代码。
某个应用程序首先要发起第1次认证。大部分情况下,应用程序中嵌入的客户端会把应用程序原来的登录画面屏蔽掉,而直接转到单点登录服务器的登录页面。
用户在单点登录服务器的登录页面中,输入用户名和密码。
然后单点登录服务器会对用户名和密码进行认证。认证本身并不是单点登录服务器的功能(CAS默认认证是用户名=密码即认证成功),因此,通常会引入某种认证机制。认证机制可以有很多种,例如自己写一个认证程序,或者使用一些标准的认证方法,例如LDAP或者数据库等等。在大多数情况下,会使用LDAP进行认证。这是因为LDAP在处理用户登录方面,有很多独特的优势。
认证通过之后,单点登录服务器会和应用程序进行一个比较复杂的交互,这通常是某种授权机制。CAS使用的是所谓的Ticket。
授权完成后,CAS把页面重定向,回到Web应用。Web应用此时就完成了成功的登录(当然这也是单点登录的客户端,根据返回的Ticket信息进行判断成功的)。
然后单点登录服务器会在客户端创建一个Cookie。注意,是在用户的客户端,而不是服务端创建一个Cookie。这个Cookie是一个加密的Cookie,其中保存了用户登录的信息。
如果用户此时希望进入其他Web应用程序,则安装在这些应用程序中的单点登录客户端,首先仍然会重定向到CAS服务器。不过此时CAS服务器不再要求用户输入用户名和密码,而是首先自动寻找Cookie,根据Cookie中保存的信息,进行登录。登录之后,CAS重定向回到用户的应用程序。
这样,就不再需要用户继续输入用户名和密码,从而实现了单点登录。
注意,这种单点登录体系中,并没有通过http进行密码的传递(但是有用户名的传递),因此是十分安全的。
3.2 身份验证步骤
下图说明了在集成了 CAS 服务器的系统中身份验证是如何执行的
下面是这个身份验证协议中的主要步骤。
用户尝试使用应用程序的 URL 访问应用程序。用户被重定向到 CAS 登录 URL,采用的是 HTTPS 连接,他请求的服务的名称作为参数传递。这时向用户显示一个用户名/密码对话框。
用户输入 ID 和密码,CAS 对他进行身份验证。如果身份验证失败,目标应用程序根本不会知道这个用户曾经试图访问它 —— 用户在 CAS 服务器上就被拦住了。
如果身份验证成功,CAS 就将用户重定向回目标应用程序,并在 URL 中附加一个称为 ticket 的参数。然后,CAS 尝试创建一个称为 ticket-granting cookie 的内存 cookie。这是为了以后进行自动的重新验证;如果存在这个 cookie,就表示这个用户已经成功地登录了,用户就不需要再次输入他的用户名和密码。
然后,应用程序要检查这个 ticket 是否正确,以及是否代表一个有效用户;检查的方法是,打开一个 HTTPS 连接来调用 CASserviceValidateURL,并作为参数传递 ticket 和服务名称。CAS 检查这个 ticket 是否有效,以及是否与请求的服务相关联。如果检查成功,CAS 就将用户名返回给应用程序。
3.3 CAS架构和运行原理
Cas Server的主要作用是通过发行和验证Ticket(piao据)来对用户进行认证和授权访问Client应用,用于认证的凭证信息都是由Cas Server管理的。而Cas Client就对应于我们真正的应用,当然其中会使用到Cas相关的类,用于与Cas Server进行交互。官网有两张图也能体现Cas的架构和原理。
四 CAS安装
4.1 CAS下载
可以从 CAS 官网:http://www.jasig.org/cas 下载,也可以访问这个地址:http://downloads.jasig.org/cas/,同样可以下载,或者直接在开源中国搜索cas框架也可以下载。
下载CAS服务器cas-server-3.5.2-release.zip
解压程序包cas-server-3.5.2\modules\cas-server-webapp-3.4.2.war到tomcat\webapps下,并重新命名cas.war
到了这一步,不体验一把是不会死心的,那就启动tomcat,看看运行效果吧,如果输入http://localhost:8080/cas出现如下界面:
看这里说明:
Non-secure Connection:You are currently accessing CAS over a non-secure connection. Single Sign On WILL NOT WORK. In order to have single sign on work, you MUST log in over HTTPS.
提示:不安全的连接:你现在通过不安全的连接访问cas,单点登录不能工作,为了使单点登录正常工作,你必须使用https协议访问。
由上可知,cas服务器默认是支持的是https协议,所有为了使cas服务器正常运行起来我们还需要:
创建cas证书库
使web容器(此处使用的tomcat)支持https
4.2 创建证书
证书是单点登录认证系统中很重要的一把钥匙,客户端于服务器的交互安全靠的就是证书;本教程由于是演示所以就自己用JDK自带的keytool工具生成证书;如果以后真正在产品环境中使用肯定要去证书提供商去购买,证书认证一般都是由VeriSign认证,中文官方网站:http://www.verisign.com/cn/
4.2.1 生成秘钥库keystore
用JDK自带的keytool工具生成,生成语句:
keytool -genkey -alias wangzhen -keyalg RSA -storepass changeit -keystore d:/keys/.keystore
1)以上输入项唯一需要注意的是您的名称与姓氏?该输入项即为cas服务的访问地址;由于https协议访问cas只能域名访问,故该提示项只能输入域名,不能输入ip。
开发测试时,如果没有域名服务器可以修改本机C:\Windows\System32\drivers\etc\hosts文件做下映射。
127.0.0.1 wangzhen.cas
2)参数-keystore d:/keys/.keystore表示生成的keystore的文件路径,如果不加该参数,生成的keystore文件默认在系统用户目录下,其中包含一个keypair。
3)为了简化操作,建议 keystore 与 keypair 的密码相同,且均为 changeit;命令中-storepass changeit即为设置keystor密码为changeit。
4)还有几条常用的 keytool 命令:
查看 keypair:keytool -list -storepass changeit -keystore d:/keys/.keystore
删除 keypair:keytool -delete -alias <别名> -storepass changeit -keystore d:/keys/.keystore
创建时有keystore 参数,后续的keytool中都要有keystore ,创建时使用默认目录,则后续相关keytool也不需要keystore 参数。
5)命令中参数的具体含义见下参数说明。
4.2.2 从keystore中导出证书
使用一下命令导出证书:
keytool -export -file d:/keys/wangzhen.crt -alias wangzhen -storepass changeit -keystore d:/keys/.keystore
1)执行完该命令即生成了我们需要的证书了,证书位置位于d:/keys/wangzhen.crt ;如下图所示:
2)如果4.2.1中keystore生成在默认路径(系统用户目录),则导出证书时也不需要指定crt证书绝对路径,只需要指定名称即可如:-file wangzhen.crt。此时生成的证书文件也在系统用户目录下。
3)从图中可以看出密码可以在命令中直接指定-storepass changeit,也可以在属性输入项中输入,此处密码需和生成的4.2.1中创建密码保持一致。
至此,导出证书完成,可以分发给应用的JDK使用了,接下来讲解客户端的JVM怎么导入证书。
注:在实际项目中,如果客户已经购买了认证机构提供的证书,则前创建keystore和导出证书步骤可以省略。
4.2.3 为客户端JVM导入证书
获取到证书后,我们需要给需要集成的应用系统jvm中导入证书,具体导入命令为:
keytool -import -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file D:/keys/wangzhen.crt -alias wangzhen -storepass changeit
1)在执行以上命令前,必须需要保证 cacerts 文件对当前用户有写权限。
2)JDK 的 keystore 的密码最好也为 changeit。
3)这里的jre地址和tomcat使用的jre要保持一致。
至此证书的创建、导出、导入到客户端JVM都已完成。
注意:以上创建证书的无论是默认了证书的生成地址({user}/.keystore)还是自己制定的地址,建议将最终生成的.keystore文件都放在当前用户目录下,因为tomcat配置ssl时默认读取的秘钥库地址即为{user}/.keystore,这样在后续配置tomcat下https访问时,只需要将https的8443端口注释打开即可,不用再做指定.keystore地址等多余配置。
4.2.4 keytool参数说明
-genkey 在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书
-alias 产生别名
-keystore 指定密钥库的名称,产生的各类信息将不在.keystore文件中
-keyalg 指定密钥的算法
-validity 指定创建的证书有效期多少天
-keysize 指定密钥长度
-storepass 指定密钥库的密码
-keypass 指定别名条目的密码
-dname 指定证书拥有者信息例如: "CN=firstName,OU=org,O=bj,L=bj,ST=gd,C=cn"
-list 显示密钥库中的证书信息 keytool -list -v -keystore 别名 -storepass ....
-v 显示密钥库中的证书详细信息
-export 将别名指定的证书导出到文件 keytool -export -alias 别名 -file 文件名.crt
-file 参数指定导出到文件的文件名
-delete 删除密钥库中某条目 keytool -delete -alias 别名 -keystore sage
-keypasswd 修改密钥库中指定条目口令 keytool -keypasswd -alias 别名 -keypass .... -new .... -storepass ... -keystore 别名
-import 将已签名数字证书导入密钥库 keytool -import -alias 别名 -keystore 证书名-file 文件名(可以加.crt 后缀)
4.3 运行cas服务器
4.3.1 使WEB容器支持https
上面为使用https协议的访问做了那么多工作,那么我们的web容器在这里也需要设置能够支持http协议。此处以tomcat为例,如需用到其他如:jboos、was、weblogic等web容器可以自行上网搜索。
打开tomcat/conf/server.xml文件:
<!-- cas https -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
<!-- keystorefile="D:/keys/.keystore" keystorepass="changeit" -->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
1)若htts端口设置为443则可以在访问https时不用加端口号,就像http对应80端口不需要加端口一样。
2)如果生成的.keystore文件放在当前用户目录下,则不需要做额外配置,如果是在自己指定目录,则需要在这里指定下目录和创建时的密码如:keystorefile="D:/keys/.keystore" keystorepass="changeit"
4.3.2 启动cas服务器
到此Tomcat的SSL启用完成,现在可以再次启动tomcat试一下了,启动后输入https://localhost:8443/cas会出现如下界面:
此处可以看出我们创建的证书,只对我们设置的域名wangzhen.cas有效,其余的访问地址不被信息,此时我们不应该再使用localhost来进行访问了,应该使用在hosts文件中映射的域名wangzhen.cas来访问。我们再次访问cas:https://wangzhen.cas:8443/cas,如果出现以下界面,则说明安装成功了:
说明:由于CAS默认的认证机制是只要用户名和密码相同即为认证成功,所有此处我们输入两个相同的用户名密码点击登陆,出现如下界面则说明认证成功:
至此,一个原生的cas单点登录服务器就被搭建起来了,当然我们实际运用中这点功能是不能够满足的,如何定制化登录界面?如何修改认证方式?客户端应用如何集成到cas上?等等一些列问题还需要我们去发掘,会在后面章节一一说明。
五 构建CAS应用
由于字数限制,该章节请前往构建CAS源码应用查看。
六 支持http协议
由于字数限制,该章节请前往CAS支持http协议查看。
七 自定义认证方式
由前文我们可以指导,cas默认的认证方式是只要用户名与密码相同即为认证成功,这显然不能满足我们正常的使用,此处说明下如何修改cas的认证方式。
CAS的认证接口为org.jasig.cas.authentication.handler.AuthenticationHandler其中,CAS内置了一些AuthenticationHandler 实现类,如jdbc认证等。我们也可以编写自己的认证类,同样只要实现AuthenticationHandler 接口即可。
打开WEB-INF/deployerConfigContext.xml注释掉用户名等于密码的即成功的认证类,增加自己的认证类
<!-- cas本身带的验证类 只是判断用户名和密码相同即可通过 此处舍弃掉
<bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />
-->
<!-- 配置自己写的验证类 -->
<bean class="slt.nic.cas.authentication.handler.QueryDatabaseHandler" />
当然,我们自定义的认证类也必须要实现AuthenticationHandler 接口。QueryDatabaseHandler类代码如下:
package slt.nic.cas.authentication.handler;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import slt.nic.cas.dao.IUserDao;
import slt.nic.cas.dao.impl.UserDao;
import slt.nic.cas.util.Common;
/**
* 该方法是配置的登录cas服务器的凭证,此处可以根据传入的用户名密码到数据库初步验证
* authenticateUsernamePasswordInternal验证方法名不能修改
* @date 2013-08-11
* @author wangZhen
*
*/
public class QueryDatabaseHandler extends AbstractUsernamePasswordAuthenticationHandler
{
@Override
protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials) throws AuthenticationException
{
//操作用户接口
IUserDao dao = (UserDao) Common.getBean("userDao");
//检查用户是否有登陆cas服务器凭证
return dao.authenticateUserByCredentials(credentials);
}
}
验证成功与否,只要在此方法返回true/false即可,此处我们配置了数据源并且写了用户操作接口,在该接口中实现了对用户输入的用户名密码进行检验的代码,此处就不贴一一出了,每个人实现的方法均不相同。
8 客户端配置及集成
9 拦截过滤特定url
参见:CAS拦截器过滤指定URL构建CAS应用