在Acegi初体验及初解剖(http://rmn190.iteye.com/blog/332711)里, 通过对web.xml和applicationContext-acegi-security.xml的跟踪,我们得出被Acegi拦截下的请求最终交到 了filterInvocationDefinitionSource配置下的几个Filter的实现类来处理. 它们是怎么处理这个请求的呢? 在Acegi(三): Acegi? Who are you? ,我们听说江湖中有"七剑", 但这么久了"七剑"怎么还 没露面呢? 这篇博客中我们将看到下天山的"七剑".

首先我看下都有哪些Bean参于了Acegi的保卫工作, 如下图所示:

上面是静态的定义, 再看下图的动态调用图:

这里结合着上图,我们跟着浏览器发出的请求走一遍.
     Step1: 对上就上图中数字1,这里浏览器发出一个请求.
     Step2: Web服务器,我们这里的Tomcat接受到Step1发来的HTTP请求, 把里面的信息抽取出来,组装成一个Request 对象, 同时Tomcat也生成了一个Response对象,这样接下的Request穿过的Filter都有机会来修改这个Response对象了, 也正是Acegi抓住了这个机会利用Filter来改变Response里的值达到保护我们系统的作用.这里Request到达图中的"Filter chain proxy", 我们还记得web.xml中配置的" FilterToBeanProxy "及基配置参数 FilterChainProxy(targetClass的值), 再看Bean图中的 filterChainProxy,这里我们动态地感觉到这个 filterChainProxy的存在了.通过配置中的" /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor" 一句我们告诉 filterChainProxy 当Request来时,都有哪些Filter处理这个Request.
     Step3/Step4: filterChainProxy调用filterChain中的第一个Filter,也就是 httpSessionContextIntegrationFilter . 这个httpSessionContextIntegrationFilter 是 HttpSessionContextIntegrationFilter类的实例, 这个类正是"七剑"之一. 从它的名字上,我们也隐隐约约地感觉到了点什么: 把Context integrate 到HttpSession中? 对的, 在HttpSessionContextIntegrationFilter的 doFilter方法里Acegi从HttpSession中获得 SecurityContext 对象(或没有的话新建个), 随后再把这个 SecurityContext存放到 SecurityContextHolder中, 很自然嘛, SecurityContextHolder 就是用来放 SecurityContext的. 做了这些处理后, httpSessionContextIntegrationFilter通过 chain.doFilter方法将执行权交给下一filter.

我们例子中下一个filter就是 authenticationProcessingFilter,它是 AuthenticationProcessingFilter的实例,看它名字里有Authentication跟"七剑"中的 Authentication有关系? 不错, authenticationProcessingFilter类中有一个 requiresAuthentication方法, 顾名思义,它是看当前的Request是否是用来做验证的,也就是说是否是登录的. 这就用到了Bean配置 authenticationProcessingFilter里属性, 看Acegi的源码可以得到验证. 接下来, 在方法 attemptAuthentication中Acegi从Request中取出 username和 password组建一个 Authentication 对象, 再由配置中的 authenticationManager来加以验证,若"暗号"没对上的话, 就有一个 AuthenticationException异常抛出, authenticationProcessingFilter catch住这个 AuthenticationException,再通过 sendRedirect方法在浏览器中指向 authenticationFailureUrl的值" /login.jsp?login_error=1 ". 若"暗号"对上了,将通过方法 successfulAuthentication重定向到 defaultTargetUrl指定的页面, 同时Acegi把对上"暗号"的 Authentication对象通过方法 SecurityContextHolder.getContext().setAuthentication存放到 SecurityContext中,以备后用.

Step5/Step6: Acegi将Request(当然还有Response)交给下一个Fillter, 我们例子中是 filterInvocationInterceptor(实际上交给了 exceptionTranslationFilter,这里我们为了讨论的方便,假定交给了 filterInvocationInterceptor ),这个filter再从SecurityContextHolder中取出SecurityContext,再取出里面的已经对上"暗号"的Authentication对象(此对象在本例中实际上是封装了users.properties里这样的" james=tom@1231,ROLE_TECHNICIAN "键值对), 再把这个 Authentication对象交给当前bean中配置的 accessDecisionManager属性以决定 Authentication是否能访问它想访问的资源.经 accessDecisionManager"研究"后发现可以访问,此时Acegi即将Request/Response交给我们系统里配置的相应方法(如Struts里配置的某一method).若"研究"时发现没权限,则以异常的方式交给上面提到的 exceptionTranslationFilter,这个filter再重定向到 loginFormUrl指定的URL上.

到这步骤已走完了, 那怎么没看到"七剑"中的另三剑呢? 它们是 GrantedAuthority , UserDetails , Us erDetailsService . 实际上它们在filterInvocationInterceptor中用到了, 不过当时为了讨论的方便,并没有写出来. 是这样的, 在决定一个 Authentication是否可以访问它想要的资源时, accessDecisionManager会从 Authentication里 调用getAuthorities得到它的 GrantedAuthority [] , 再将它们与通过Us erDetailsService 得到的 UserDetails 对象里方法返回的GrantedAuthority[]一一比较, 若在比较过程中发现有个对应上了, 就表示有权访问,否则即无权. 这里所论述的过程正是上面 accessDecisionManager所做的"研究".

好了,至此, 我们通过跟踪请求的来龙去脉把 applicationContext-acegi-security.xml配置中的Filter走了一遍,更重要的是走filter时,我们与Acegi江湖里的鼎鼎大名的"七剑"有了短暂但美好的接触.

Acegi源码研究(五):七剑下天山相关推荐

  1. 基于C++6.0的Gh0st远控源码研究及在VS2019下的编译修正和测试

    最近闲着无聊,研究了一下Gh0st的源码,这个源码现在也很难白嫖到了,花了200多积分从CSDN下了好几个版本.在VC2019下都编译不了.看来只能自己修改了: 经过一天一夜的折腾(昨晚通宵到早上6点 ...

  2. Apache Tika源码研究(七)

    tika怎样加载Parser实现类的,怎样根据文档的mime类型调用相应的Parser实现类,本文接着分析 先熟悉一下tika的解析类的相关接口和类的UML模型: Parser接口的源码如下: /** ...

  3. Apache Jackrabbit源码研究(五)

    上文最后提到jackrabbit的检索默认实现类QueryImpl,先熟悉一下该类的继承层次 QueryImpl继承自抽象类AbstractQueryImpl,而抽象类实现了Query接口(JCR的接 ...

  4. Soul网关源码阅读(七)限流插件初探

    Soul网关源码阅读(七)限流插件初探 简介     前面的文章中对处理流程探索的差不多了,今天来探索下限流插件:resilience4j 示例运行 环境配置     启动下MySQL和redis d ...

  5. snabbdom源码解析(七) 事件处理

    事件处理 我们在使用 vue 的时候,相信你一定也会对事件的处理比较感兴趣. 我们通过 @click 的时候,到底是发生了什么呢! 虽然我们用 @click绑定在模板上,不过事件严格绑定在 vnode ...

  6. Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager)

    Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager) 本篇主要讲解iOS开发中的网络监控 前言 在开发中,有时候我们需要获取这些信息: 手机是否联网 ...

  7. WebRTC源码研究(4)web服务器工作原理和常用协议基础

    文章目录 WebRTC源码研究(4)web服务器工作原理和常用协议基础 前言 做WebRTC 开发为啥要懂服务器开发知识 1. Web 服务器简介 2. Web 服务器的类型 3. Web 服务器的工 ...

  8. 【vue-router源码】五、router.addRoute、router.removeRoute、router.hasRoute、router.getRoutes源码分析

    [vue-rouer源码]系列文章 [vue-router源码]一.router.install解析 [vue-router源码]二.createWebHistory.createWebHashHis ...

  9. WebRTC源码研究(4)web服务器工作原理和常用协议基础(转载)

    前言 前面3篇博客分别对WebRTC框架的介绍,WebRTC源码目录,WebRTC的运行机制进行了介绍,接下来讲解一点关于服务器原理的知识.后面博客会写关于WebRTC服务器相关的开发,目前git上面 ...

  10. 一起谈.NET技术,.NET Framework源码研究系列之---万法归宗Object

    经过前面三篇关于.NET Framework源码研究系列的随笔,相信大家都发现其实.NET Framework的实现其实并不复杂,也许跟我们自己做的项目开发差不多.本人也是这样的看法.不过,经过仔细深 ...

最新文章

  1. 10双屏鼠标过不去_升级到2.0版本的双屏工作桌!家中工作高效还需利器辅助
  2. F1 score,micro F1score,macro F1score 的定义
  3. JSP教程第1讲笔记
  4. 数学函数图像软件-Graph之小技巧
  5. 男神.png misc之图片lsb隐写
  6. 路由器搭建个人网站_PittMesh路由器归个人所有
  7. python抢课_python实现强智科技教务系统抢课(两种方法)
  8. eBay自养号测评需要准备哪些资料?
  9. 加盟代理小程序为创业者带来另一条出路
  10. 添加或修改Kindle图书封面
  11. Android studio软件编译生成APK
  12. 【js练习】for of循环与for in循环
  13. 文件资源管理器无法打开怎么办?
  14. MFC比较好的一篇文章
  15. 计算机中文速记四级多少字,计算机中文速记职业技能培训和鉴定标准
  16. i18n和i10n:国际化本地化--gettext
  17. 转载:table单元格内容自动换行
  18. 【Spark入门】2、Spark编写软件——IDEA的安装与长期使用
  19. SGAPI使用备忘录
  20. python中dump 和dumps load和loads的区别

热门文章

  1. linux之ls -l命令详解
  2. MP地面站二次开发教程(二)MP的框架与修改
  3. 摘抄整理:基于数据驱动的故障诊断方法综述
  4. 【Python基础知识整理】
  5. PMP知识点:工作绩效数据、信息和报告的区别
  6. Not annotated parameter overrides @NonNullApi parameter
  7. UEFI Shell编程和使用
  8. PRML读书会第五章 Neural Networks(神经网络、BP误差后向传播链式求导法则、正则化、卷积网络)...
  9. Linux的隐匿技巧【渗透测试】
  10. 【HDFS】常用API