CAS简介
CAS架构图
CAS server 和CAS client 是构成CAS系统架构的两个物理组件,他们之间通过多种协议来通信
CAS server
CAS server 的主要作用是通过分发ticket并使之生效来对用户进行认证并授权用户访问CAS认可的服务,通常这些服务就是指CAS client,当用户成功登录 server发放一个已授权的ticket 给用户(TGT),此时一个sso session就被创建了。
CAS client
通常CAS client有两层含义,一,CAS client 可以是任何被CAS认可的应用,二 ,CAS client也可以是能与各种软件平台或者应用集成的软件包
准备工作
到官网下载CAS源码 https://www.apereo.org/projects/cas/download-cas
本文使用v4.2.1版本 现在比较新的版本需要自己用gradle打包
下载tomcat 本文使用tomcat8版本
jdk使用1.8版本
部署 CAS Server
配置Tomcat使用Https协议
创建证书
证书是单点登录认证系统中很重要的一把钥匙,客户端于服务器的交互安全靠的就是证书;本文使用jdk自带的keytool生成,真正在产品环境中使用肯定要去证书提供商去购买,证书认证一般都是由VeriSign认证,中文官方网站:http://www.verisign.com/cn/
$ keytool -genkey -alias jason -keyalg RSA -keystore /Users/lilixin/programming/jasonssokey
添加hosts
在/etc/hosts(linux系统)中加入127.0.0.1 sso.jason-li.cn
导出证书
keytool -export -file /Users/lilixin/programming/jasonssokey.crt -alias jason -keystore /Users/lilixin/programming/jasonssokey
至此导出证书完成,可以分发给应用的JDK使用了,接下来讲解客户端的JVM怎么导入证书
为客户端JVM导入证书
keytool -import -keystore /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/jre/lib/security/cacerts -file /Users/lilixin/programming/jasonssokey -alias jason
过程中可能遇到如下错误,请重命名/…./security/cacerts
keytool 错误: java.io.IOException: Keystore was tampered with, or password was incorrect
应用证书到Web服务器
启用Web服务器(Tomcat)的SSL,也就是HTTPS加密协议
打开tomcat目录的conf/server.xml文件,开启83和87行的注释代码,并设置keystoreFile、keystorePass,修改后结果如下,请注意属性值区分大小写
|
|
测试
浏览器打开 https://sso.jason-li.cn:8443/ 可访问到tomcat页面既成功
启动CAS server
把下栽来的CAS源码中 modules目录中的cas-server-webapp-3.5.2.war 重命名后放入tomcat的webapps目录中 启动tomcat
访问https://sso.jason-li.cn:8443/cas 如果出现正常CAS登录页面则部署成功
扩展认证接口
由于缺省的实现仅能用于测试,我们还需要自己扩展认证接口
扩展 AuthenticationHandler
|
|
通过源码可以看到AuthenticationHandler主要有两个方法 supports ()方法用于检查所给的包含认证信息的Credentials 是否受当前 AuthenticationHandler 支持;而 authenticate() 方法则担当验证认证信息的任务,这也是需要扩展的主要方法,根据情况与存储合法认证信息的介质进行交互,返回 boolean 类型的值,true 表示验证通过,false 表示验证失败。
JDBC 认证方法
通常我们会将用户信息保存在数据库中,所以采用jdbc认证方式
配置DataStore
打开 /webapps/cas/WEB-INF/deployerConfigContext.xml添加一个新的 bean 标签
|
|
记得添加名称空间 xmlns:p=”http://www.springframework.org/schema/p“
配置 AuthenticationHandler
在 cas-server-support-jdbc-3.1.1.jar 包中,提供了 3 个基于 JDBC 的 AuthenticationHandler,分别为 BindModeSearchDatabaseAuthenticationHandler, QueryDatabaseAuthenticationHandler, SearchModeSearchDatabaseAuthenticationHandler。其中 BindModeSearchDatabaseAuthenticationHandler 是用所给的用户名和密码去建立数据库连接,根据连接建立是否成功来判断验证成功与否;QueryDatabaseAuthenticationHandler 通过配置一个 SQL 语句查出密码,与所给密码匹配;SearchModeSearchDatabaseAuthenticationHandler 通过配置存放用户验证信息的表、用户名字段和密码字段,构造查询语句来验证。
我们这里选用QueryDatabaseAuthenticationHandler
CAS4.2.1默认使用的是一个简单的acceptUsersAuthenticationHandler,找到他然后注释掉他
使用我们自己定义的AuthenticationHandler
|
|
这里我们采用MD5加密 MD5PasswordEncoder是对具体实现的引用
|
|
定制返回属性
注释掉原来的attributeRepository和attrRepoBackingMap
|
|
添加相应jar包
- cas-server-support-jdbc.4.2.1.jar
- mchange-commons-java-0.2.10.jar
- c3p0-0.9.5.1.jar
- commons-collections-3.2.jar
- commons-dbcp-1.2.1.jar
- commons-pool-1.3.jar
把相应jar包放入/webapps/cas/WEB-INF/lib下面
最后的配置文件
|
|
替换CAS Server 界面
页面在目录 cas/WEB-INF/view/jsp/default下
有4个页面是必须的:
- casConfirmView.jsp: 当用户选择了“ warn ”时会看到的确认界面
- casGenericSuccess.jsp: 在用户成功通过认证而没有目的Service时会看到的界面
- casLoginView.jsp: 当需要用户提供认证信息时会出现的界面
- casLogoutView.jsp: 当用户结束 CAS 单点登录系统会话时出现的界面
重新启动tomcat 浏览器打开http://sso.jason-li.cn:8080/cas/login 从数据库中找到一个账号 登录 OK 成功 进行下一步
部署客户端应用
与CAS Server建立信任关系
- 略
引入CAS client jar包
我们这里使用shiro做权限控制并与CAS集成
|
|
shiro.properties
|
|
applicationContext-shiro.xml
|
|
UserRealm
|
|
filterChainDefinitions过滤器配置
Shiro内置有FilterChain ,Shiro验证URL时,URL匹配成功便不再继续匹配查找,详细见官网 ,通常可将这些过滤器分为两组
认证过滤器
anon,authc,authcBasic,user
授权过滤器
perms,port,rest,roles,ssl
注意user和authc不同:当应用开启了rememberMe时,用户下次访问时可以是一个user,但绝不会是authc,因为authc是需要重新认证的,user表示用户不一定已通过认证,只要曾被Shiro记住过登录状态的用户就可以正常发起请求,比如rememberMe,说白了,以前的一个用户登录时开启了rememberMe,然后他关闭浏览器,下次再访问时他就是一个user,而不会authc
举几个例子
/admin=authc,roles[admin] 表示用户必需已通过认证,并拥有admin角色才可以正常发起’/admin’请求
/home=user 表示用户不一定需要已经通过认证,只需要曾经被Shiro记住过登录状态就可以正常发起’/home’请求
Web.xml中配置filter
|
|
注意到 DelegatingFilterProxy 它会自动的把filter请求交给相应名称的bean处理,也就是我们在shiro-xml中配置的shiroFilter
web.xml单点登录相关配置
|
|
多系统单点退出功能改造
以上实现不能实现多个系统退出状态的同步,所以需要改造一下,因为session是由各个client端的shiro来维护的,CAS退出的时候并不会清理掉session
重写CasFilter
主要是把CasFilter和logoutFilter合并 这样就可以在logout的时候拿到shiro中的subject,并进行注销
|
|
重写SingleSignOutHttpSessionListener
|
|
web.xml更改
- 删除掉web.xml中单点登录过滤器配置
- listener改成我们自己的
shiro.xml更改
- 把casFilter 配置成我们自己写的MyCasFilter
需要每个客户端都进行这样的改造才能保证多系统单点退出时是真正的退出,单点退出改造部份内容参考 http://edolphin.site/2016/07/01/cas-single-sign-out/