CAS认证(1):流程详解
内部邀请码:C8E245J (不写邀请码,没有现金送)
国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为“中国PE第一股”,市值超1000亿元。
在CAS中MVC的控制主要是使用的spring MVC来实现的。但是,在登录过程中,因为有点类似于工作流的性质,所以,采用了一个轻量级的工作流框架,就是spring 的weflow。下面,我们就CAS如何采用webflow控制登录流程进行分析。
想深入理解webflow工作原理的读者需要参考官方的webflow2.21版本的reference。
好了,话不多说,开始CAS认证流程之旅。
用户请求如何进入认证流程的
用户一开始输入http://localhost:8080/CASServer 的时候,默认是回去访问 index.jsp的。我们看一下index.jsp,里面的内容非常简单。
final String queryString = request.getQueryString();
final String url = request.getContextPath() +"/login" + (queryString!= null ?"?" + queryString : "");
response.sendRedirect(response.encodeURL(url));
这里进行的处理就是将用户的请求重定向到CAS认证中心的 /login 路径下。在上一章中,我们已经知道,该路径我们是由 名为 CAS 的servlet,也就是org.jasig.cas.web.init.SafeDispatcherServlet 进行处理的。我们进入该servlet看一下他是如何进行处理的。
进入该servlet中,我们看到,他继承自 HttpServlet,也就是说他只是一个普通的servlet。该servlet持有一个DispatcherServlet 属性delegate。这同struts的处理方式如出一辙。都是通过一个代理类来进行处理请求的。
该类的初始化也仅仅是调用代理类delegate的初始化。Service函数很仅仅是调用delegate的service函数。
看来,DispatcherServlet类才是处理请求的关键类。我们看到DispatcherServlet类的完整路径是
org.springframework.web.servlet.DispatcherServlet
这里,也就是将请求交给了spring MVC处理了。(关于spring mvc,参考我其他的关于spring 的源码分析文章)。
Webflow与Spring MVC集成
Spring MVC核心配置文件是cas-servlet.xml。在该文件中,webflow将与springMVC进行集成。
这里有一个问题,就是spring何时开始加载cas-servlet.xml文件的呢?
原来,在初始化DispatcherServlet的时候,会自动加载 servlet-name+“-servlet.xml”文件。所以,cas-servlet.xml是自动加载的,不需要在配置文件进行配置。(参见关于springMVC的文章)
交给spring MVC之后,spring MVC又将请求交给了 webflow处理。下面是webflow同spring MVC的结合:
<!-- 根据工作流定义,生成一个执行器 -->
<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框架作为spring MVC的一个节点来进行配置。
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配置文件及源码分析
在WEB-INF文件夹下的login-webflow.xml是登陆流程的主要配置文件。在该文件中,定义了用户登录的整个处理流程。
首先,配置文件中的 on-start标签定义了用户第一次进入流程中的预处理动作。该标签对应spring中的id为initialFlowSetupAction的bean。查看该bean(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的工作原理。另外,如果对于自定义登录流程如何处理,将会在特殊场景的解决方案中给出。
CAS认证(1):流程详解的更多相关文章
- Linux启动流程详解【转载】
在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接 ...
- Shiro 登录认证源码详解
Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...
- C++的性能C#的产能?! - .Net Native 系列《二》:.NET Native开发流程详解
之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...
- [nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)
:由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . ...
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解
本文转自:http://www.topeetboard.com 视频下载地址: 驱动注册:http://pan.baidu.com/s/1i34HcDB 设备注册:http://pan.baidu.c ...
- iOS 组件化流程详解(git创建流程)
[链接]组件化流程详解(一)https://www.jianshu.com/p/2deca619ff7e
- git概念及工作流程详解
git概念及工作流程详解 既然我们已经把gitlab安装完毕[当然这是非必要条件],我们就可以使用git来管理自己的项目了,前文也多多少少提及到git的基本命令,本文就先简单对比下SVN与git的区别 ...
- Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)
一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...
- JPEG图像压缩算法流程详解
JPEG图像压缩算法流程详解 JPEG代表Joint Photographic Experts Group(联合图像专家小组).此团队创立于1986年,1992年发布了JPEG的标准而在1994年获得 ...
- unity3d-配置Android环境,打包发布Apk流程详解
31:unity3d-配置Android环境,打包发布Apk流程详解 作者 阿西纳尼 关注 2016.08.28 22:52 字数 498 阅读 1806评论 0喜欢 5 Unity配置Android ...
随机推荐
- PHP漏洞全解(一)-PHP网站的安全性问题
本文主要介绍针对PHP网站常见的攻击方式,包括常见的sql注入,跨站等攻击类型.同时介绍了PHP的几个重要参数设置.后面的系列文章将站在攻击者的角度,为你揭开PHP安全问题,同时提供相应应对方案. 针 ...
- 解读分库分表中间件Sharding-JDBC
[编者按]数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据 ...
- Android ImageButton | Button | TextView 点击和触摸效果
ImageButton------------------------------------------------> 一.Java 代码: 在drawable目录下添加新的xml文件 bu ...
- poj3140Contestants Division
链接 这叫树形DP吗..?断开某条边 求剩下两颗树数权值和的差最小 dfs一遍 枚举边 查了n久 wa n次 dp数组没初始化.. 在poj上1A感觉应该挺爽 #include <iostre ...
- VJP1456 最小总代价(状压)
链接 这题卡了一天 刚开始没考虑第一个传的和最后一个传的 感觉挺简单 啪啪的敲完 居然还过了17组数据.. 正解:dp数组一维保存状态 一维保存当前传到了谁 再枚举是由谁传过来的 这样可以保证正确性 ...
- bzoj2749
根绝欧拉函数的计算式,欧拉函数次方每次就是不断把2消掉,并把其他质因子不断变出2,最终弄成1显然我们先预处理每个数会被弄出多少个2出来,次方=弄出来的2的总数-[一开始是否有2](因为一开始没2的话是 ...
- 【转】Eclipse提示No java virtual machine(转载)
原文网址:http://blog.sina.com.cn/s/blog_6cd73dfb01013zkg.html 第一次运行Eclipse,经常会提示下面的问题:... No java virtua ...
- [liu yanling]黑盒测试用例设计方法
1. 概述 黑盒测试用例设计方法包括等价类划分法.边界值分析法.错误推测法.因果图法.判定表驱动法.正交试验设计法.功能图法等. 2. 等价类划分法 2.1. 概念 等价类划分法是把 ...
- java基础之开发环境搭建
我们这里后续的所有课程都使用eclipse 来开发java代码,下面我们来搭建开发环境: 1.首先去java.sun.com去下载jdk,可以下载1.6 的版本2.安装JDK,最好安装在某个盘的跟目录 ...
- c# 中Intern的作用
1. 函数如下 public static string Intern(string str) { if(str == null) { throw new ArgumentNullException( ...