zoukankan      html  css  js  c++  java
  • Shiro过滤器的维护与匹配执行

    servlet的初始化会触发核心过滤器的创建:

    public Object getObject() throws Exception {
        if (instance == null) {
            instance = createInstance();
        }
        return instance;
    }

    在createInstance方法中会调用

    FilterChainManager manager = createFilterChainManager();

    protected FilterChainManager createFilterChainManager() {
    
        DefaultFilterChainManager manager = new DefaultFilterChainManager();
        Map<String, Filter> defaultFilters = manager.getFilters();
        //apply global settings if necessary:
        for (Filter filter : defaultFilters.values()) {
            applyGlobalPropertiesIfNecessary(filter);
        }
    
        //Apply the acquired and/or configured filters:
        Map<String, Filter> filters = getFilters();
        if (!CollectionUtils.isEmpty(filters)) {
            for (Map.Entry<String, Filter> entry : filters.entrySet()) {
                String name = entry.getKey();
                Filter filter = entry.getValue();
                applyGlobalPropertiesIfNecessary(filter);
                if (filter instanceof Nameable) {
                    ((Nameable) filter).setName(name);
                }
                //'init' argument is false, since Spring-configured filters should be initialized
                //in Spring (i.e. 'init-method=blah') or implement InitializingBean:
                manager.addFilter(name, filter, false);
            }
        }
    
        //build up the chains:
        Map<String, String> chains = getFilterChainDefinitionMap();
        if (!CollectionUtils.isEmpty(chains)) {
            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue();
                manager.createChain(url, chainDefinition);
            }
        }
    
        return manager;
    }

    DefaultFilterChainManager默认构造器会填充所有默认的filter,为11个。

    public DefaultFilterChainManager() {
        this.filters = new LinkedHashMap<String, Filter>();
        this.filterChains = new LinkedHashMap<String, NamedFilterList>();
        addDefaultFilters(false);
    }
    
    protected void addDefaultFilters(boolean init) {
        for (DefaultFilter defaultFilter : DefaultFilter.values()) {
            addFilter(defaultFilter.name(), defaultFilter.newInstance(), init, false);
        }
    }

    当你有自己的实现时,如扩展了FormAuthenticationFilter,key为authc,增加了一个check和ssoAuthc。

    <property name="filters">  
        <util:map>  
            <entry key="authc" value-ref="formAuthenticationFilter" />
            <entry key="check" value-ref="authcFilter"/>
            <entry key="ssoAuthc" value-ref="MyShiroCasFilter"/>
        </util:map>  
    </property>  

    这时ShiroFilterFactoryBean维护这3个。

    createFilterChainManager方法会把默认的给覆盖掉,因为自定义和默认的key均为authc。

    public void addFilter(String name, Filter filter, boolean init) {
        addFilter(name, filter, init, true);
    }
    
    protected void addFilter(String name, Filter filter, boolean init, boolean overwrite) {
        Filter existing = getFilter(name);
        if (existing == null || overwrite) {
            if (filter instanceof Nameable) {
                ((Nameable) filter).setName(name);
            }
            if (init) {
                initFilter(filter);
            }
            this.filters.put(name, filter);
        }
    }

    操作完后DefaultFilterChainManager维护13个(覆盖1个,新增2个)

    然后构造Map

    /images/** = anon
    /css/** = anon  
    /resources/** = anon  
    /js/** = anon  
    /static/** = anon  
    /logout.do = anon
    /rest/** = anon
    /** = check,authc

    如上面的map转换成filterChains之后,key为”/**”的value是一个包含两个过滤器的NamedFilterList(一个名叫check 一个名为authc)。

    “/**” -> ” size = 2”

    当请求过来时,PathMatchingFilterChainResolver的getChain来获取需要的过滤器链,这个会匹配之前保存的Map集合,匹配上就立马返回这个代理的过滤器链(ProxiedFilterChain)。

    然后就是执行代理过滤器链:

    整个过程就是先解析配置文件中的映射关系,转化成内存中的Map映射,当一个请求过来时, 先被核心过滤器拦截,然后根据匹配规则构造代理过滤器链,这个代理过滤器链包含了需要走的过滤器。

    最后执行代理过滤器链的doFilter方法:遍历需要执行的匹配上的过滤器,挨个执行,但是自定义和默认的过滤器都是传的ProxiedFilterChain本身,所以放行的时候又会绕回ProxiedFilterChain的doFilter方法,这样就形成了逻辑上的链,shiro自己的链式执行。

    匹配的过滤器执行完后,才会放行到servlet的过滤器链继续执行。

  • 相关阅读:
    多态
    抽象类和接口
    面向对象3
    类的继承 设计模式
    面向对象2
    面向对象
    复习
    对json的简单认识
    关于AJAX
    PHP配置开发环境
  • 原文地址:https://www.cnblogs.com/lucare/p/8679134.html
Copyright © 2011-2022 走看看