sso cas4.0改造历程--spring-webflow篇

来源:互联网 发布:中文域名在线转码程序 编辑:程序博客网 时间:2024/05/17 19:16
前言:
如果想要对CAS做业务流程的添加(譬如:添加验证码,记录用户登陆信息,用户特征分析等等),势必不能回避spring-webflow的理解。尤其是想要摸清楚src\main\webapp\WEB-INF\下的login-webflow.xml以及logout-webflow.xml这两个文件,弄清楚单点登陆以及登出的流程。磨刀不误砍柴工,下面我们就来看看什么是spring-webflow。

什么时候使用:
“Spring Web Flow 是 Spring 的一个子项目,其最主要的目的是解决跨越多个请求的、用户与服务器之间的、有状态交互问题”——摘自百度的这句话可能不太好理解。什么叫“跨越多个请求”,什么叫“用户与服务器之间的、有状态交互”?

“跨越多个请求”。
我们看下图--上一篇文章《sso cas4.0改造历程--初识篇》里的流程图。可以发现,虽然对于用户来说只要输入用户名密码(流程:1-3-6)。已经登陆以后(流程:1-5),再打开其他应用,连登录页面都看到不。但是,在这整个流程中包含了“session的检查”、校验用户名密码、“TGC的检查”、“ST的生成,回传并校验”这一系列的过程(流程图中2、3、4、5虚线的流程)。对应的cas认证中心与需要校验登陆的应用服务器之间,其实,是经行了多次信息交换的。而我们在编写常见的接口时(如果你也是采用mvc框架的话),往往只需要接受请求中的信息,做一些“增删改查”的操作以后,返回信息即可。并不会多次的调用别人的接口,并以返回结果来作为下一步处理的依据。概括来说:一次显式请求处理,需要经历多次隐性重定向,接口调用。



“有状态交互”
什么叫有状态交互呢?当通过浏览器请求用户信息的时候,首先会检查有没有session,当进入cas服务端的时候,会先查看是否存在tgc。这些在做登陆处理的时候都被拿来作为判断的依据,也就是用户登陆流程的当前状态。而我们在做平时的接口时,往往只需要关心用户传给我们了哪些参数,然后做对应的处理就行了。很少需要判断用户在调用接口之前或者之后做了什么操作

规范:
1、开始
<on-start>    <evaluate expression="initialFlowSetupAction" /></on-start>
这是整个流程的开始,没啥好说的

2、普通流程
<action-state id="ticketGrantingTicketCheck">        <evaluate expression="ticketGrantingTicketCheckAction.checkValidity(flowRequestContext)"/>        <transition on="notExists" to="gatewayRequestCheck"/>        <transition on="invalid" to="terminateSession"/>        <transition on="valid" to="hasServiceCheck"/></action-state>
action-state代表一个流程,其中id可以理解为给这个流程起了一个名字。
然后<evaluate expression="ticketGrantingTicketCheckAction.checkValidity(flowRequestContext)"说明了哪个类的哪个方法通过传入了哪些参数做了操作。
这里就代表ticketGrantingTicketCheckAction中执行了checkValidity方法,传入参数为flowRequestContext。既然知道了这个,我们就可以查到ticketGrantingTicketCheckAction的具体实现。
不难找到它的定义:
<bean id="ticketGrantingTicketCheckAction" class="org.jasig.cas.web.flow.TicketGrantingTicketCheckAction" c:registry-ref="ticketRegistry" />
查看源码中的
 public Event checkValidity(final RequestContext requestContext) {        final String tgtId = WebUtils.getTicketGrantingTicketId(requestContext);        if (!StringUtils.hasText(tgtId)) {            return new Event(this, NOT_EXISTS);        }        final Ticket ticket = this.ticketRegistry.getTicket(tgtId);        return new Event(this, ticket != null && !ticket.isExpired() ? VALID : INVALID); }
我们就可以知道最终对应了三个不同返回结果,与上面的三个流程去向一一对应。
<transition on="notExists" to="gatewayRequestCheck"/>
<transition on="invalid" to="terminateSession"/>
<transition on="valid" to="hasServiceCheck"/>

3、判断语句
<decision-state id="hasServiceCheck">     <if test="flowScope.service != null" then="renewRequestCheck" else="viewGenericLoginSuccess" /></decision-state>
这里和普通流程一样取了个名字叫hasServiceCheck,当进入该流程是会判断flowScope.service != null,满足则进入renewRequestCheck,不然进入流程viewGenericLoginSuccess。

4、显示语句
<view-state id="viewLoginForm" view="casLoginView" model="credential">        <binder>            <binding property="username" />            <binding property="password" />        </binder>        <on-entry>            <set name="viewScope.commandName" value="'credential'" />        </on-entry>        <transition on="submit" bind="true" validate="true" to="validatorCaptcha">            <evaluate expression="authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)" />        </transition></view-state>
这里也类似的取名为viewLoginForm,对于jsp为casLoginView.jsp路径看其他的配置,与理解流程无关就不讲了。binder代表需要填写的参数,set是赋值操作。最后经过authenticationViaFormAction.doBind(flowRequestContext, flowScope.credential)操作以后进入validatorCaptcha流程。

5、结束语句
<end-state id="viewServiceSsoErrorView" view="viewServiceSsoErrorView" />
此处代表,进入viewServiceSsoErrorView流程时,整个流程结束并且返回viewServiceSsoErrorView.jsp页面

结束:
要明白cas的流程知道这几种流程写法,大体也就行了。如果有兴趣的,可以深入去研究一下spring-webflow。至此,可以尝试着去画cas的流程图了,也能根据login-webflow.xml去跟代码。不难发现cas采用spring-webflow对于理解整个流程来说还是很有帮助的。



0 0
原创粉丝点击