CAS流程源码分析。
2015-07-27 16:47
405 查看
参考:http://www.cnblogs.com/AloneSword/p/3360106.html
首先是web.xml中的
Spring listener:
然后是springmvc的servlet
listener的核心配置文件在spring-configuration下的所有xml中。后面要用到先别管。
servlet SafeDispatcherServlet是普通的servlet,执行init方法,init方法中执行了DispatcherServlet的init方法,就跟springmvc一样。
默认配置文件为
servlet-name+“-servlet.xml”文件。,也就是cas-servlet.xml。
交给springmvc之后,cas-servlet.xml中又交给spring web flow处理:
webflow:flow-registry节点就是注册了一个webflow流程,该流程的入口,也就是ID=“login”。这样,交给springMVC的请求路径如果是login的,则有springMVC交给webflow处理。
在webflow中,会定义一些视图,这些视图都是以view=”XXX”的形式存在的。那么XXX又是如何找到对应的页面呢??看flow-builder-services节点,我们会发现有个view-factory-creator属性,该属性就定义了视图解析工厂。
该视图解析工厂是由视图解析器组成的。这里只定义了一个视图解析器,就是viewResolvers。该视图解析器是springFramework中的ResourceBundleViewResolver的一个实例,该类可以通过basenames属性,找到value值对应的properties属性文件,该文件中式类似ke=values类型的内容,正是该文件将jsp文件映射成视图名称。
至此,springMVC与webflow已经集成完毕。
由
首先该配置文件中的on-start定义了流程开始的操作
该bean在cas-servlet.xml可以找到。该类为org.jasig.cas.web.flow.InitialFlowSetupAction继承自AbstractAction,AbstractAction方法是org.springframework.webflow.action包中的类。是webflow中的基础类。该类中的doExecute方法是对应处理业务的方法。就犹如servlet中的service方法一样。该方法的参数是RequestContext对象,该参数是一个流程的容器。该方法从request中获取TGT,并且构建一个临时的service对象(不同域注册的service,详情见接入系统管理)。并且,将TGT和service放在FlowScope作用域中。
流程的初始化完毕之后,就开始一系列的判断了。也就是进入decision-state节点。这些节点是依次执行的。
对应的dicision-state走完之后,如果不存在TGT,其实就会进入voiwLoginForm节点。该节点是一个view-state类型的,这也就是说明该节点是一个页面,view=“casLoginView”属性定义了该view对应的页面是“casLoginView”。这个视图会被spring的视图解析器解析成/WEB-INF/view/jsp/default/ui/casLoginView.jsp页面。用户这时候就能看到一个登陆界面了。
需要注意的是,用户看到的登录界面中,会有hidden类型的一个lt参数:
<inputtype="hidden" name="lt"value="${flowExecutionKey}" />
该参数可以理解成每个需要登录的用户都有一个流水号。只有有了webflow发放的有效的流水号,用户才可以说明是已经进入了webflow流程。否则,没有流水号的情况下,webflow会认为用户还没有进入webflow流程,从而会重新进入一次webflow流程,从而会重新出现登录界面。
用户点击登录之后,提交到realSubmit节点。该节点执行的是authenticationViaFormAction.submit方法,在该方法中,将会验证用户的认证信息是否正确。验证成功之后,跳转到sendTicketGrantingTicket,在这里,将生成TGT,然后,进入serviceCheck,在serviceCheck中,将会验证flowScope作用域中是否存在service,如果存在,则进入generateServiceTicket,否则进入登录成功页面。在generateServiceTicket中,也将生成ST,同时检查是否有警告信息,然后进行重定向到用户最开始请求的地址。
至此,springMVC与webflow整合以及登录整个流程已经讲解完毕。
这里讲解的比较粗略。后续可能会较详细的写一下webflow的工作原理。另外,如果对于自定义登录流程如何处理,将会在特殊场景的解决方案中给出。
首先是web.xml中的
Spring listener:
<listener> <listener-class> org.jasig.cas.web.init.SafeContextLoaderListener </listener-class> </listener>
然后是springmvc的servlet
<servlet> <servlet-name>cas</servlet-name> <servlet-class> org.jasig.cas.web.init.SafeDispatcherServlet </servlet-class> <init-param> <param-name>publishContext</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
listener的核心配置文件在spring-configuration下的所有xml中。后面要用到先别管。
servlet SafeDispatcherServlet是普通的servlet,执行init方法,init方法中执行了DispatcherServlet的init方法,就跟springmvc一样。
默认配置文件为
servlet-name+“-servlet.xml”文件。,也就是cas-servlet.xml。
交给springmvc之后,cas-servlet.xml中又交给spring web flow处理:
<!-- 根据工作流定义,生成一个执行器 --> <webflow:flow-executorid="flowExecutor"flow-registry="flowRegistry"> <webflow:flow-execution-attributes> <webflow:always-redirect-on-pausevalue="false"/> </webflow:flow-execution-attributes> </webflow:flow-executor> <!-- 注册一个工作流 id是子路径 为flow入口对login的请求交由login-webflow.xml定义的处理器进行处理--> <webflow:flow-registryid="flowRegistry"flow-builder-services="builder"> <webflow:flow-locationpath="/WEB-INF/login-webflow.xml"id="login"/> </webflow:flow-registry> <webflow:flow-builder-servicesid="builder"view-factory-creator="viewFactoryCreator"expression-parser="expressionParser"/>
webflow:flow-registry节点就是注册了一个webflow流程,该流程的入口,也就是ID=“login”。这样,交给springMVC的请求路径如果是login的,则有springMVC交给webflow处理。
在webflow中,会定义一些视图,这些视图都是以view=”XXX”的形式存在的。那么XXX又是如何找到对应的页面呢??看flow-builder-services节点,我们会发现有个view-factory-creator属性,该属性就定义了视图解析工厂。
该视图解析工厂是由视图解析器组成的。这里只定义了一个视图解析器,就是viewResolvers。该视图解析器是springFramework中的ResourceBundleViewResolver的一个实例,该类可以通过basenames属性,找到value值对应的properties属性文件,该文件中式类似ke=values类型的内容,正是该文件将jsp文件映射成视图名称。
至此,springMVC与webflow已经集成完毕。
由
<webflow:flow-locationpath="/WEB-INF/login-webflow.xml"id="login"/>可知,流程的配置文件是login-webflow.xml这个。
首先该配置文件中的on-start定义了流程开始的操作
<on-start> <evaluate expression="initialFlowSetupAction" /> </on-start>该标签对应spring中的id为initialFlowSetupAction的bean。
该bean在cas-servlet.xml可以找到。该类为org.jasig.cas.web.flow.InitialFlowSetupAction继承自AbstractAction,AbstractAction方法是org.springframework.webflow.action包中的类。是webflow中的基础类。该类中的doExecute方法是对应处理业务的方法。就犹如servlet中的service方法一样。该方法的参数是RequestContext对象,该参数是一个流程的容器。该方法从request中获取TGT,并且构建一个临时的service对象(不同域注册的service,详情见接入系统管理)。并且,将TGT和service放在FlowScope作用域中。
流程的初始化完毕之后,就开始一系列的判断了。也就是进入decision-state节点。这些节点是依次执行的。
<!--检查flow中是否存在TGT如果存在,存在进入hasServiceCheck,为空进入gatewayRequestCheck--> <decision-stateid="ticketGrantingTicketExistsCheck"> <if test="flowScope.ticketGrantingTicketIdneq null"then="hasServiceCheck"else="gatewayRequestCheck"/> </decision-state> <!-- 主要是CS结构使用gatewat,暂时不研究--> <decision-stateid="gatewayRequestCheck"> <if test="externalContext.requestParameterMap['gateway']neq '' && externalContext.requestParameterMap['gateway'] neqnull && flowScope.service neq null" then="gatewayServicesManagementCheck"else="viewLoginForm"/> </decision-state> <!-- 存在TGT,说明用户已经登陆,测试flow中service是否为空,不为空,进入renewRequestCheck,为空,进入viewGenericLoginSuccess--> <decision-stateid="hasServiceCheck"> <if test="flowScope.service!= null"then="renewRequestCheck"else="viewGenericLoginSuccess"/> </decision-state> <!-- 用户已经登陆,且请求参数中存在service判断请求中是否存在'renew'参数,如果renew参数为空或者没有内容,那么,进入viewLoginForm,否则进入generateServiceTicket renew参数和gateway参数不兼容。renew参数将绕过单点登录。也就是说即使用户登录了,还将要求用户登录。(等你妹啊,人家都登录了,凭什么还要让人家再登录一次) --> <decision-stateid="renewRequestCheck"> <if test="externalContext.requestParameterMap['renew']neq '' && externalContext.requestParameterMap['renew'] neqnull"then="viewLoginForm"else="generateServiceTicket"/> </decision-state> <decision-stateid="warn"> <if test="flowScope.warnCookieValue"then="showWarningView"else="redirect"/> </decision-state>
对应的dicision-state走完之后,如果不存在TGT,其实就会进入voiwLoginForm节点。该节点是一个view-state类型的,这也就是说明该节点是一个页面,view=“casLoginView”属性定义了该view对应的页面是“casLoginView”。这个视图会被spring的视图解析器解析成/WEB-INF/view/jsp/default/ui/casLoginView.jsp页面。用户这时候就能看到一个登陆界面了。
需要注意的是,用户看到的登录界面中,会有hidden类型的一个lt参数:
<inputtype="hidden" name="lt"value="${flowExecutionKey}" />
该参数可以理解成每个需要登录的用户都有一个流水号。只有有了webflow发放的有效的流水号,用户才可以说明是已经进入了webflow流程。否则,没有流水号的情况下,webflow会认为用户还没有进入webflow流程,从而会重新进入一次webflow流程,从而会重新出现登录界面。
用户点击登录之后,提交到realSubmit节点。该节点执行的是authenticationViaFormAction.submit方法,在该方法中,将会验证用户的认证信息是否正确。验证成功之后,跳转到sendTicketGrantingTicket,在这里,将生成TGT,然后,进入serviceCheck,在serviceCheck中,将会验证flowScope作用域中是否存在service,如果存在,则进入generateServiceTicket,否则进入登录成功页面。在generateServiceTicket中,也将生成ST,同时检查是否有警告信息,然后进行重定向到用户最开始请求的地址。
至此,springMVC与webflow整合以及登录整个流程已经讲解完毕。
这里讲解的比较粗略。后续可能会较详细的写一下webflow的工作原理。另外,如果对于自定义登录流程如何处理,将会在特殊场景的解决方案中给出。
相关文章推荐
- Android View.onMeasure方法的理解
- SVN与其他工具整合
- maven常见命令
- 图结构练习——判断给定图是否存在合法拓扑序列
- Android API Guides 阅读笔记(4)----Fragment
- Jetty和Tomcat的选择
- 设置滚动效果
- Document.getElementById 与 $('#id')的区别
- 重拾Excel之为什么
- 几个不常用但是很好用的PHP数组函数
- 《Java Concurrency in Practice》之线程封闭(Thread Confinement)
- VIM常用方法记录
- GTK常用控件之窗口( GtkWindow )
- Android Fragment+ViewPager实现循环滑动
- BZOJ1011
- [Android]ToolBar使用详解(一)——项目配置
- JSON数据的生成
- easyUI的datagrid 分页保存选中状态
- 浅谈程序员接私单那点事及接私单需要注意的问题
- IIC 概述之1