作者: 常明,Java架构师
[请尊重原创,盗版必究,转载请指明出处]
上一篇《相遇篇》我们作为新手初步了解了CAS,安装并进行了简单体验。这篇我们进一步深入认识CAS。
CAS原理和我们前面自己开发的Nebula基本一致,所有的系统应用都会引导到CAS Server认证中心去登录。登录成功后,认证中心会产生一个票据叫TGT(Ticket Granting Ticket),TGT即代表了用户与认证中心直接的全局会话。TGT存在,表明该用户处于登录状态。
TGT并没有放在Session中,也就是说,CAS全局会话的实现并没有直接使用Session机制,而是利用了Cookie自己实现的,这个Cookie叫做TGC(Ticket Granting Cookie),它存放了TGT的id,认证中心服务端实现了TGT。
我们利用上篇安装的CAS,在认证中心登录下,看下登录前后cookie的变化。显然,在登录后,多出一个叫CASTGC的Cookie,它来维持全局会话。
登录前:
登录后:
如果是应用系统登录,同理,会引导到认证中心进行登录,登录成功后再重定向回应用系统,这时会带上一个登录令牌,告知系统应用登录成功。
这个令牌,在CAS中叫做ST(Service Ticket)服务票据,它的作用和Nebula的token类似。当然,和Nebula一样,应用系统收到ST后,会直接向CAS Server去验证,验证通过后,应用系统即可建立本地会话,返回用户访问的受限资源。
下面我们利用前面搭建的环境,看下从应用系统首次登录时的情况。首先访问www.ssoclient.com:81/index.do,系统重定向到www.cas.com认证中心,输入用户名密码后,携带ST重定向回www.ssoclient.com:81/index.do 下面是重要的三个HTTP走向。
其中第一个,我们看到,登录成功后,系统会设置CASTGC Cookie,同时重定向回应用时带上了一个ticket变量,这个就是ST。
CAS官网给出了详细的用户登录时序图,非常详细,这里就不重新画轮子了,直接引用如下:
从流程图可以看出,和Nebula的时序流程图几乎一模一样。当然,作为成熟开源的CAS,考虑的应用场景更加丰富些。到目前为止,其CAS认证协议已经持续发展了三个版本,v1实现了单点登录,此版本跟Nebula实现的功能差不多。
v2版则重点增加了proxy模式,代理模式是一种更复杂形式的认证,即认证的Web应用(CAS Client)可以作为代理直接访问需要认证的后端服务(如邮件服务器),浏览器用户无需再和后端服务直接进行认证交互。这个比较复杂,在门户中可能会用到,我们这里不做讨论。
v3版本则更加丰富了协议,认证中心验证票据后不仅可以返回身份ID,还可携带用户昵称、性别等其他用户基本信息。
CAS不仅提供专有的CAS协议,还同时支持SAML 1.1、OpenID、OAuth等标准开放协议,具有更广泛的可用性。
CAS工程采用模块化插件化设计思想,其核心子工程是cas-server-core,提供CAS最核心的功能。其它功能以插件形式提供,放在不同子工程中。
CAS虽然以Web应用的形式提供服务,但从理论上讲,CAS提供的核心功能是基于票据令牌方式的认证,这种认证,和是否是Web应用方式运行无关。故实际上,cas-server-core提供的核心模块只有两部分,一是票据Ticket,包括票据的产生、查询、删除、存储等各种操作。另一个是认证,提供多种认证方式。
当然,CAS是支持Web应用的单点登录,确切说是Web SSO解决方案。故cas-server-core还提供了web层的一些最基本逻辑框架,如登录请求接收。
作为独立运行的Web应用,CAS还需提供与浏览器用户的交互,与需要认证的应用系统交互,这些逻辑,绝大部分放在cas-server-webapp和cas-server-webapp-support两个子工程中。CAS认证中心采用Spring MVC + WebFlow实现,cas-server-webapp提供了相关交互页面和web工程配置,而cas-server-webapp-support提供了基于WebFlow的相关认证流程逻辑代码,它将调用后端cas-server-core提供的票据和认证功能。
CAS应用的整体架构官方提供了一个比较清晰的架构图,如下所示:
对CAS工程内部有个大致认识后,我们开始动手实践,我们一步步实践如何在工程中实际应用CAS。
首先,我们来看下如何修改登录登出流程及相关页面,满足实际应用需求。我们让CAS完成和我们前面Nebula Server一致的登录登出流程并提供一致的交互页面。
CAS页面采用主题模板方式,我们的需求其实就是相当于定制一套自己的主题模板。
在WEB-INF/cas.properties 文件中找到:
cas.themeResolver.defaultThemeName=cas-theme-default
cas.viewResolver.basename=default_views
这两个参数指定了样式定义文件和模板定义文件,他们在WEB-INF/cas-servlet.xml 中引用到。修改这两个值,使用自己定义的文件:
cas.themeResolver.defaultThemeName=nebula-theme
cas.viewResolver.basename=nebula_views
仿照resources/cas-theme-default.properties 创建nebula-theme.properties文件,其内容是定义了css文件和js文件的位置。由于我们没用到js,只定义如下内容:
standard.custom.css.file=/css/nebula.css
创建/css/nebula.css文件,将nebula中的css文件内容copy过来。
同理仿照resources/default_views.properties 创建nebula_views.properties,CAS缺省定义了很多页面模板,代表不同流程节点需要给用户的接口页面。
按照我们前面开发Nebula所使用的登录登出流程,只提供两个页面,一个是登录页面,用以处理用户登录问题,一个是首页,登录前和登录后给用户的接口页面。因此,在nebula_views中,只定义两个模板即可。
nebulaLoginView.(class)=org.springframework.web.servlet.view.JstlView
nebulaLoginView.url=/WEB-INF/view/jsp/nebula/ui/login.jsp
nebulaIndexView.(class)=org.springframework.web.servlet.view.JstlView
nebulaIndexView.url=/WEB-INF/view/jsp/nebula/ui/index.jsp
同时,我们将nebula中两个页面,copy到/WEB-INF/view/jsp/nebula/ui 下并做相应调整。
按照CAS登录逻辑,对login.jsp,除了username、password两个登录参数外,form中还需要增加三个隐藏参数,lt、execution、_eventId,lt主要是为了增加页面登录安全性,防止重复提交,其它两个确保正确走webflow登录流程。
CAS的登录登出过程由webflow定义,这样可以更好地实现登录登出过程的定制化。登录的定义流程说明是login-webflow.xml,登出时logout-webflow.xml。我们分别copy这两个文件为nebula-login-webflow.xml和nebula-logout-webflow.xml作为流程定义的基础,并在cas-servlet.xml中修改登录登出流程定义文件为上述文件。
这里特别提到cas-servlet.xml文件,cas-servlet.xml是CAS的spring mvc配置文件,文件中定义了服务接口和定义处理的Controller:
我们看到上面为啥没有/login 和 /logout 接口呢?其实他们已经配置成webflow流程入口,分别走nebula-login-webflow.xml和nebula-logout-webflow.xml流程。
id即对应的path /login,logout同理,在文件下面能够找到。
根据要求,我们修改nebula-login-webflow.xml和nebula-logout-webflow.xml中内容。对于nebula-login-webflow.xml,去掉不必要的流程节点,如warn和proxy等,同时将错误响应直接指向登录页面,故登录流程中只提供两个响应页面即nebulaLoginView和nebulaIndexView。
对于nebula-logout-webflow.xml,登出正常结束后直接再走登录流程。这样和Nebula的登录登出处理流程基本一致。
OK,我们看下修改后的效果。先看下直接在认证中心登录登出的情况:
输入www.cas.com即显示登录页面:
登录成功后显示首页:
点击登出,又显示登录页面,从应用系统登录同理。至此,我们改造了CAS认证中心登录登出流程和相关界面模板,和Nebula认证中心给用户的体验效果基本一致。
本文出自慕课网,转载请注明出处,侵权必究。
热门评论
太喜欢这个系列了~!赞赞赞
太喜欢这个系列了~!赞赞赞
真心不错,正好用到cas 了,理解下