zoukankan      html  css  js  c++  java
  • CAS源码追踪系列一:Filter的初始化


    最近研究了一下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()
            ...
        }
    

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

    总结

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

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

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

  • 相关阅读:
    Jenkins job 之间实现带参数触发
    svn hooks post-commit钩子自动部署
    Ubuntu PPA软件源
    图片文字OCR识别-tesseract-ocr
    scala 学习笔记十 元组
    scala 学习笔记九 定义操作符
    scala 学习笔记八 简洁性
    scala 学习笔记七 基于类型的模式匹配
    scala 学习笔记六 推导
    scala 学习笔记五 foreach, map, reduce
  • 原文地址:https://www.cnblogs.com/xuxiaojian/p/9822414.html
Copyright © 2011-2022 走看看