http://www.imooc.com/article/3720
主要原理:用户第一次访问一个CAS 服务的客户web 应用时(访问URL :http://192.168.1.90:8081/web1 ),部署在客户web 应用的cas AuthenticationFilter ,会截获此请求,生成service 参数,然后redirect 到CAS 服务的login 接口,url为https://cas:8443/cas/login?service=http%3A%2F%2F192.168.1.90%3A8081%2Fweb1%2F ,认证成功后,CAS 服务器会生成认证cookie ,写入浏览器,同时将cookie 缓存到服务器本地,CAS 服务器还会根据service 参数生成ticket,ticket 会保存到服务器,也会加在url 后面,然后将请求redirect 回客户web 应用,url 为http://192.168.1.90:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZuMwnbMvxpCBcNAIi6-20 。这时客户端的AuthenticationFilter 看到ticket 参数后,会跳过,由其后面的TicketValidationFilter 处理,TicketValidationFilter 会利用httpclient 工具访问cas 服务的/serviceValidate 接口, 将ticket 、service 都传到此接口,由此接口验证ticket 的有效性,TicketValidationFilter 如果得到验证成功的消息,就会把用户信息写入web 应用的session里。至此为止,SSO 会话就建立起来了,以后用户在同一浏览器里访问此web 应用时,AuthenticationFilter 会在session 里读取到用户信息,所以就不会去CAS 认证,如果在此浏览器里访问别的web 应用时,AuthenticationFilter 在session 里读取不到用户信息,会去CAS 的login 接口认证,但这时CAS 会读取到浏览器传来的cookie ,所以CAS 不会要求用户去登录页面登录,只是会根据service 参数生成一个ticket ,然后再和web 应用做一个验证ticket 的交互。 cas client 访问 cas server时 server会获取 cookie中的信息,如果cookie中有信息就不会出现登录页面。
上一篇《相遇篇》我们作为新手初步了解了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认证中心给用户的体验效果基本一致。
作者: 手插口袋_
链接:http://www.imooc.com/article/3720
来源:慕课网