最早由Yale开发的CAS在目前开源SSO市场上占据了80%的份额。简单研究了一下,感觉CAS确实比较成熟,认证流程均可通过证书保证安全,也提供了对多种App服务器和开发环境的支持。比较感兴趣的是两个:Php和Jetty,前者较为常用;后者是Hadoop平台内置的Jetty服务器。
一、配置Php认证
这个相当简单,有人实现了一个PhpCAS库,只需将CAS.php和client.php等三个php文件放置到应用目录下即可。然后代码中加入4行代码即可实现SSO,如下。其中需要指出的是这个例子并没有使用服务器证书认证,而只是让Apache/Php服务器从CAS服务器经由SSL验证PT。这种方式的前提是服务器之间是互相信任的,否则就可以让恶意服务器获取用户的一些信息。如需证书认证,会相当麻烦,参见后面的讨论
// import phpCAS lib
include_once('CAS.php');
// initialize phpCAS
phpCAS::client(CAS_VERSION_2_0,'tomcat',8443,'cas-server-webapp-3.4.2');
//此处要注意版本,目前CAS协议已经到3.0,但是还兼容2.0
// no SSL validation for the CAS server
phpCAS::setNoCasServerValidation();
// force CAS authentication
phpCAS::forceAuthentication();
二、配置Jetty认证
Jetty是一个比Tomcat更为小巧的Java应用服务器,被包括Hadoop、GAE在内的系统使用,GAE的某人说的很有道理,一个Jetty节省1MB内存,则10000个服务器就可以节省10GB空间,能省干吗不省呢?
Hadoop平台中,Jetty被当做一个嵌入式服务器使用了,配置基本上和Tomcat类似,都是需要配置Filter,此类配置很多,就不详述了。在应用中需要写一个跳转页面就可以了,对于Hive稍微罗嗦一些,主要是Hive默认使用了一个war文件,因此为了配置简单就需要使用两个war文件,一个支持SSO,一个不支持
- 当然也可以不这么用。应用中需要写如下2行代码获取用户名称:
Object uo =
session.getAttribute("edu.yale.its.tp.cas.client.filter.user");
if (uo instanceof String) user =
(String)uo;
三、配置服务器证书
配置证书比写出来代码更为麻烦,基本的教程中都是使用keytool生成自签名的证书,这种证书对于Tomcat来说,是可以接受的,但是处于安全性,Jetty不支持自签名证书,这就带来了很多的问题,这里有2种方法解决:
1. 修改CAS
Client的代码,使用http来做服务器端验证。(注:CAS客户端默认是不支持这种方式的,极其不安全,其代码中多次判断是否验证URL是https)
2. 配置非自签名证书。步骤如下:
2.1
自己搭建CA,可以使用OpenSSL,生成一个root证书,用root证书为CAS服务器签署一个服务器证书,将root证书导出为JKS格式。
2.2 将CAS服务器所在的Tomcat服务器(或者其他服务器)的JVM
Keystore中导入CAS服务器证书,同时也可以复制一份放到Tomcat中
2.3 将root证书转换为浏览器认识的格式,比如pkcs12,导入浏览器
2.4 将root证书导入到Jetty服务器的JVM Keystore中,同时也可以复制一份到Jetty中
这样,浏览器就可以接受CAS服务器的证书,Jetty服务器也可以接受CAS服务器的证书,达到互相信任的效果,实现SSO。这个流程还是很复杂的,我在2.4遇到问题,Jetty不认识JVM中的证书,以后闲下来再研究吧。
四、关于用户注册的思考
由于用户信息在CAS服务器和应用服务器上实际上都有存放,一般来说CAS只保存最为基本的用户名和密码认证信息,而应用服务器需要保存授权信息。这样就带来了鸡生蛋还是蛋生鸡的问题,或者说信息如何同步的问题。我想这不是什么技术问题,而是一种管理问题。比如在企业应用中可以统一创建用户目录,比如LDAP,预先部署用户的认证信息,由于服务器之间互信,只需使用统一的用户名就可以实现SSO。
应用服务器是否保存用户认证信息其实并不重要,但是应用服务器提供注册用户的功能时,需要在CAS用户数据库和应用中同时保存用户信息,一旦不同步,则无法实现SSO。