CAS源码追踪系列一:Filter的初始化

目录

  • 代码跟踪

    • Spring-web:DelegatingFilterProxy
    • CAS:AuthenticationFilter
  • 总结

最近研究了一下SSO(Single Sign On:单点登录)原理。

于是想借助CAS(基于SSO原理的实现框架)加深一下理解同时参考一下具体代码实现,因此有了此系列文章。

先从CAS-CLIENT说起。

假设你已经掌握了如何在你的web项目中引入CAS。我们以AuthenticationFilter为例,说一说它是如何从初始化的。

代码跟踪

Spring-web:DelegatingFilterProxy

在web项目中的web.xml文件中我们通常通过如下方式进行spring和cas的整合:

<bean id="authenticationFilter" class="org.jasig.cas.client.authentication.AuthenticationFilter">
  <property name="casServlerLoginUrl">xxx</property>
  <property name="serverName">xxx</property>
</bean>
<filter>
  <filter-name>casAuthenticationFilter</filter-name>
  <filter-class>
  org.springframework.web.filter.DelegatingFilterProxy
  </filter-class>
  <init-param>
    <param-name>targetBeanName</param-name>
    <param-value>authenticationFilter</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>casAuthenticationFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

可以看到引入了一个名为DelegatingFilterProxy的Filter。那我们来看一下该类的源码:

public class DelegatingFilterProxy extends GenericFilterBean {
    private String contextAttribute;//上下文属性,寻找WebApplicationContext
    private WebApplicationContext webApplicationContext;//web上下文
    private String targetBeanName;//被委托的Filter的名字,如果没有指定,则使用DelegatingFilterProxy对应的Filter的name,即上面的<filter-name>标签的内容。
    private boolean targetFilterLifecycle;//是否是目标Filter的生命周期,默认为false,即由Spring来管理Filter的生命周期,否则由Servlet来管理。
    private Filter delegate;//被委托的过滤器
    private final Object delegateMonitor;//监视器
    ...

该类是实现了Filter接口并交由spring管理的servlet过滤器的代理类。

因为这个类也是实现了Filter接口,所以在tomcat容器初始化是会执行init(FilterConfig)方法。该方法来自其父类GenericFilterBean,来看代码:

public final void init(FilterConfig filterConfig) throws ServletException {
        ...
        this.filterConfig = filterConfig;
        ...
        this.initFilterBean();
    }

注意到this.initFilterBean(),该方法来自DelegatingFilterProxy,看源码:

protected void initFilterBean() throws ServletException {
                ...
                WebApplicationContext wac = this.findWebApplicationContext();//获取应用上下文
                if (wac != null) {
                    this.delegate = this.initDelegate(wac);//初始化委托
               ...
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        Filter delegate = (Filter)wac.getBean(this.getTargetBeanName(), Filter.class);//从应用上下文中获取名为targetBeanName的bean,也就是被委托的Filter
        if (this.isTargetFilterLifecycle()) {
            delegate.init(this.getFilterConfig());//调用Filter的初始化方法
        }

        return delegate;
    }

CAS:AuthenticationFilter

AuthenticationFilter继承了AbstractCasFilter。

上面说到调用Filter自己的初始化方法。对于AuthenticationFilter,因为自己没有重写init(FilterConfig),则会调用从其父类AbstractCasFilter继承来的init(FilterConfig)方法:

public final void init(FilterConfig filterConfig) throws ServletException {
        if (!this.isIgnoreInitConfiguration()) {
            ...
            this.initInternal(filterConfig);//内部初始化
        }

        this.init();//自定义初始化逻辑
    }

注意:你会发现AuthenticationFilter和其父类都有initInternal(filterConfig)和init()方法,这里进入的是AuthenticationFilter,所以回去调用AuthenticationFilter中对应的方法:

protected void initInternal(FilterConfig filterConfig) throws ServletException {//将filterConfig设置到WebXmlConfigurationStrategyImpl以及设置一些自己的属性值
            ...
            super.initInternal(filterConfig);//此时才去调用其父类的initInternal(filterConfig)
            ...
    }

public void init() {
        super.init();//此时才去调用其父类的init()
        ...
    }

直观的图示(非专业,手动滑稽~):

总结

本文从web项目和spring的整合入手,以cas中的AuthenticationFilter为例(其他类型的Filter类似)跟踪代码分析如何走到他自己的初始化逻辑。后续会有初始化之后对请求的拦截、cas服务端的处理等分析。

码字整理不易,如何你觉得写的还能看的话请赏一个赞或者推荐吧,如果写的不对请直接评论纠正,毕竟我还是一个在路上的小鲁班呢~

欢迎关注我的公众号,不定期更新学习笔记和视频文档学习资料哦~

原文地址:https://www.cnblogs.com/xuxiaojian/p/9822414.html

时间: 2024-08-30 06:22:49

CAS源码追踪系列一:Filter的初始化的相关文章

CAS源码追踪系列二:AuthenticationFilter对于请求的处理

上一篇我们说了在web项目中了和spring整合之后,如何进行对应Filter的初始化,如果你还没看过,请点击 <CAS源码追踪系列一:Filter的初始化>. 本篇我们来看看在初始化完成以后,cas-client是如何处理请求的. 源码地址:https://github.com/apereo/java-cas-client 如何你还不太清楚sso的原理,你可以看看这篇文章<单点登录原理与简单实现>. 当访问系统受保护的资源时,cas的过滤器AuthenticationFilter

CAS源码追踪系列三:cas-server端对请求的处理

目录 InitialFlowSetupAction ServiceAuthorizationCheck AuthenticationViaFormAction SendTicketGrantingTicketAction GenerateServiceTicketAction 第一次访问接入cas的另一个应用系统 总结 系列: CAS源码追踪系列一:Filter的初始化 CAS源码追踪系列二:AuthenticationFilter对于请求的处理 上一篇,我们了解了AuthenticationF

springMVC 源码解读系列(一)初始化

先看看DispatcherServlet的类机构: 初始化时序图: servlet初始化会调用 init 方法,换句话说就是springMVC进行初始化的时候首先会去执行HttpServletBean的init方法, 下面看看HttpServletBean的源码: 上面这段代码主要是在获取你在web.xml中配置在<init-param>中的属性(例如: namespace, contextConfigLocation). 其中有一点值得注意,那就是 initServletBean() 这个方

spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

回顾Bean与BeanDefinition的关系. BeanFactory容器. ApplicationContext上下文. 首先总结下: 开发人员定义Bean信息:分为XML形式定义:注解式定义 ApplicationContext搜集Bean的定义:存储到BeabFactory容器的中. BeanFactory根据这些BeanDefinition创建Bean.缓存起来供我们使用. [开发人员]--标注-->[Bean定义] ---搜集 -->[BeanDefinition]---创建--

Spring源码阅读系列总结

最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重要的设计模式简单的做了阐述.同时还会简单的加入一些GOF中提到的设计原则.Spring的源码阅读系列,也暂告一段落.下面是就带你走进Spring世界: Spring系列的引子 1)Spring WebApplicationContext初始化与消亡 这一节帮我们了解Spring是如何初始化WebAp

SpringMVC源码分析系列

说到java的mvc框架,struts2和springmvc想必大家都知道,struts2的设计基本上完全脱离了Servlet容器,而springmvc是依托着Servlet容器元素来设计的,同时springmvc基于Spring框架,Spring框架想必搞java的同学都很熟悉. 一进Spring的官网就发现了这样一排醒目的文字, spring可以让我们构造简单的.便携的.又快又易于扩展的基于jvm的系统和应用程序. 没错,基于Spring的MVC框架SpringMVC同样也可以构造具有这些特

Cordova Android源码分析系列一(项目总览和CordovaActivity分析)

PhoneGap/Cordova是一个专业的移动应用开发框架,是一个全面的WEB APP开发的框架,提供了以WEB形式来访问终端设备的API的功能.这对于采用WEB APP进行开发者来说是个福音,这可以避免了原生开发的某些功能.Cordova 只是个原生外壳,app的内核是一个完整的webapp,需要调用的原生功能将以原生插件的形式实现,以暴露js接口的方式调用. Cordova Android项目是Cordova Android原生部分的Java代码实现,提供了Android原生代码和上层We

jQuery源码分析系列(33) : AJAX中的前置过滤器和请求分发器

jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求,分别是: 1.前置过滤器 jQuery. ajaxPrefilter 2.请求分发器 jQuery. ajaxTransport, 3.类型转换器 ajaxConvert 源码结构: jQuery.extend({ /** * 前置过滤器 * @type {[type]} */ ajaxPrefilter: addToPrefiltersOrTransports(prefilters), /** * 请求分发器 *

修改CAS源码是的基于DB的认证方式配置更灵活

最近在做CAS配置的时候,遇到了数据源不提供密码等数据的情况下,怎样实现密码输入认证呢? 第一步:新建Java项目,根据假面算法生成CAS加密工具 出于保密需要不提供自定义的加密工具,在您的实际项目中,你可采用cas默认的加密方式比如md5. 第二步:修改CAS源码 找到cas-server-support-jdbc子模块找到包路径cas-server-support-jdbc\src\main\java\org\jasig\cas\adaptors\jdbc\,在复制一份QueryDataba