CAS认证(1):流程详解

在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 ‘‘ &amp;&amp; externalContext.requestParameterMap[‘gateway‘] neqnull &amp;&amp; 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 ‘‘ &amp;&amp; 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的工作原理。另外,如果对于自定义登录流程如何处理,将会在特殊场景的解决方案中给出。

时间: 2024-09-30 10:39:46

CAS认证(1):流程详解的相关文章

ssl协议工作流程详解

SSL 协议 (HTTPS) 握手.工作流程详解 (双向 HTTPS 流程 )SSL 协议的工作流程:服务器认证阶段: 1)客户端向服务器发送一个开始信息"Hello"以便开始一个新的会话连接; 2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的"Hello"信息时将包含生成主密钥所需的信息; 3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器; 4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信

Linux启动流程详解【转载】

在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接管硬件以后,首先读入 /boot 目录下的内核文件. 我们查看一下,/boot 目录下面大概是这样一些文件: 第二步.启动初始化进程 内核文件加载以后,就开始运行第一个程序 /sbin/init,它的作用是初始化系统环境. 由于init是第一个运行的程序,它的进程编号(pid)就是1.其他所有进程都

IMS AKA鉴权及应用流程详解

IMS AKA鉴权及应用流程详解 @auth doubleRabbit @date 2017-03-14 目的 了解鉴权及通信类业务相关鉴权算法的概念原理 了解IMS注册流程 了解IMS鉴权流程应用 鉴权含义 鉴权是指用户访问系统的权利,是提升系统安全性的一种方式,传统鉴权方法就是用户名与密码. 鉴权与授权的区别联系.逻辑上授权过程发生在鉴权之后,而实际中有时鉴权与授权对于用户来说体现为同一过程.例如在EPC附着过程中,先发生AIA鉴权过程,再发生ULR位置更新过程(授权). 接下来讲的是针对通

XMPP 协议工作流程详解

XMPP 要点. 1. 客户端(C) 和服务器端(S) 通过TCP连接5222端口进行全双工通信. 2. XMPP 信息均包含在 XML streams中.一个XMPP会话, 开始于<stream> 标签, 并结束于</stream>标签.所有其他的信息都位于这俩标签之间. 3. 出于安全目的考虑, 开始<stream>之后, 后续的内容会被适度的使用 Transpor Layer Security (TLS) 协商传输 和强制性的 Simple Authenticat

域名注册、域名实名认证、域名解析流程详解

1.域名注册流程详解首先登陆阿里云网站 www.aliyun.com 点击产品,选择域名注册(左下角蓝色字体) 然后来到此页面 在输入框中填入你想要注册的域名产看是否已经被注册 如:[email protected]然后点击查询域名,如果此域名没有被注册会弹出如下页面然后再次输入想要注册的域名点击查询此时各种域名的价钱还有注册状态就会显示出来,选择你喜欢的域名点击加入清单然后点击右侧的立即结算到如下页面选择购买年限和所有者类型然后勾选我已阅读协议 点击立即购买选择付款方式,付款成功后会弹出一个付

Shiro 登录认证源码详解

Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加的简单. 本文主要介绍 Shiro 的登录认证(Authentication)功能,主要从 Shiro 设计的角度去看这个登录认证的过程. 一.Shiro 总览 首先,我们思考整个认证过程的业务逻辑: 获取用户输入的用户名,密码: 从服务器数据源中获取相应的用户名和密码: 判断密码是否匹配,决定是否

unity3d-配置Android环境,打包发布Apk流程详解

31:unity3d-配置Android环境,打包发布Apk流程详解 作者 阿西纳尼 关注 2016.08.28 22:52 字数 498 阅读 1806评论 0喜欢 5 Unity配置Android环境,打包发布安卓流程 一:SDK与JDK下载地址:http://pan.baidu.com/s/1mhVaXHe下载完成后,解压文件 SDK文件 二.安装 JDK 运行安装程序jdk-7u67-windows-x64 Java-JDK 分别点击下一步进行安装. 安装中 在安装过程中先后会出现两次选

CentOS 5,6 系统启动流程详解

一.linux 组成介绍 1.linux 组成: Linux: kernel+rootfs(根文件系统) kernel: 进程管理.内存管理.网络管理.驱动程序.文件系统.安全功能 rootfs: 程序和glibc 库:函数集合, function, 调用接口(头文件负责描述) 过程调用: procedure,无返回值 函数调用: function 程序:二进制执行文件 2.内核设计流派: 单内核(monolithic kernel): Linux 把所有功能集成于同一个程序 微内核(micro

Android4.0 input事件输入流程详解(中间层到应用层)

在Android系统中,类似于键盘按键.触摸屏等事件是由WindowManagerService服务来管理的,然后再以消息的形式来分发给应用程序进行处理.系统启动时,窗口管理服务也会启动,该服务启动过程中,会通过系统输入管理器InputManager来负责监控键盘消息.当某一个Activity激活时,会在该Service下注册一个接收消息的通道,表明可以处理具体的消息,然后当有消息时,InputManager就会分发给当前处于激活状态下的Activity进行处理. InputManager的启动

[nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)

:由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . 从GPIO电平变化到产生中断事件的流程详解  1.GPIOTE概览 nRF51上面有32个GPIO,由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) .GP