zoukankan      html  css  js  c++  java
  • Shiro FilterChain的设计概念

    FilterChainManager

    其行为有:

    其主要职责就是增,查Filter、增,查Chain

    DefaultFilterChainManager

    其具备javax.servlet.FilterConfig(过滤器配置)、Map<String, Filter> filters(过滤器集合)、Map<String, NamedFilterList> filterChains(过滤器链集合)

    构造器中添加Shiro的默认过滤器

    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);
        }
    }
    
    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);
        }
    }

    添加Chain到filterChains集合中

    public void createChain(String chainName, String chainDefinition) {
        if (!StringUtils.hasText(chainName)) {
            throw new NullPointerException("chainName cannot be null or empty.");
        }
        if (!StringUtils.hasText(chainDefinition)) {
            throw new NullPointerException("chainDefinition cannot be null or empty.");
        }
    
        if (log.isDebugEnabled()) {
            log.debug("Creating chain [" + chainName + "] from String definition [" + chainDefinition + "]");
        }
    
        // 切割字符串切出chain和filter
        String[] filterTokens = splitChainDefinition(chainDefinition);
    
        for (String token : filterTokens) {
            String[] nameConfigPair = toNameConfigPair(token);
    
            // 添加chain到集合中
            addToChain(chainName, nameConfigPair[0], nameConfigPair[1]);
        }
    }
    
    public void addToChain(String chainName, String filterName, String chainSpecificFilterConfig) {
        if (!StringUtils.hasText(chainName)) {
            throw new IllegalArgumentException("chainName cannot be null or empty.");
        }
        Filter filter = getFilter(filterName);
        if (filter == null) {
            throw new IllegalArgumentException("There is no filter with name '" + filterName +
                    "' to apply to chain [" + chainName + "] in the pool of available Filters.  Ensure a " +
                    "filter with that name/path has first been registered with the addFilter method(s).");
        }
    
        applyChainConfig(chainName, filter, chainSpecificFilterConfig);
    
        // 确保有Chain并将Chain添加到filterChains集合中
        NamedFilterList chain = ensureChain(chainName);
    // chain中加入Filter chain.add(filter); }
    protected NamedFilterList ensureChain(String chainName) { NamedFilterList chain = getChain(chainName); if (chain == null) { chain = new SimpleNamedFilterList(chainName); this.filterChains.put(chainName, chain); } return chain; }

    Manager具备Filter的集合和FilterChain的集合,其中FilterChain还具备Filter集合

    FilterChainResolver

    其行为有:

    PathMatchingFilterChainResolver

    其具备了FilterChainManager(过滤器链管理器)和PatternMatcher(路径匹配器)

    public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
        FilterChainManager filterChainManager = getFilterChainManager();
        // 通过FilterManager是否有FilterChain
        if (!filterChainManager.hasChains()) {
            return null;
        }
    
        String requestURI = getPathWithinApplication(request);
    
        // 通过FilterManager获得ChainName即路径匹配器的Pattern
        for (String pathPattern : filterChainManager.getChainNames()) {
    
            // 路径匹配了才返回FilterChain
            if (pathMatches(pathPattern, requestURI)) {
                if (log.isTraceEnabled()) {
                    log.trace("Matched path pattern [" + pathPattern + "] for requestURI [" + requestURI + "].  " +
                            "Utilizing corresponding filter chain...");
                }
          // 返回FilterChain的代理
    return filterChainManager.proxy(originalChain, pathPattern); } } return null; }
    public FilterChain proxy(FilterChain original, String chainName) {
        NamedFilterList configured = getChain(chainName);
        if (configured == null) {
            String msg = "There is no configured chain under the name/key [" + chainName + "].";
            throw new IllegalArgumentException(msg);
        }
        return configured.proxy(original);
    }

    包装FilterChain

    public FilterChain proxy(FilterChain orig) {
        return new ProxiedFilterChain(orig, this);
    }

    获得requestURI

    WebUtils.getPathWithinApplication(HttpServletRequest request);

    路径匹配Demo(天下文章一大抄,Shiro就有抄袭Spring的地方)

    package com.wjz.demo;
    
    import org.apache.shiro.util.AntPathMatcher;
    
    public class AntPathMatcherDemo {
    
        private static final String pattern = "/admin/**";
    
        public static void main(String[] args) {
            AntPathMatcher matcher = new AntPathMatcher();
            Boolean isMatched = matcher.match(pattern, "/admin/list.do");
            System.out.println(isMatched);
        }
    }

    ProxiedFilterChain

    具备了FilterChain和Filter集合

    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        // 判断filter是否是FilterChain的最后一个Filter
        if (this.filters == null || this.filters.size() == this.index) {
            //we've reached the end of the wrapped chain, so invoke the original one:
            if (log.isTraceEnabled()) {
                log.trace("Invoking original filter chain.");
            }
            // FilterChain执行doFilter
            this.orig.doFilter(request, response);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Invoking wrapped filter at index [" + this.index + "]");
            }
            // 获得第index个Filter执行doFilter
            this.filters.get(this.index++).doFilter(request, response, this);
        }
    }

    设计概念

    对应关系

    /admin/list.do=loginFilter,user为FilterChain(Entry,/admin/list.do为Chain name(String),loginFilter,user为Chain(NamedFilterList)

    核心类

    org.apache.shiro.web.filter.mgt.FilterChainManager

      职责是解析xml文件关于shiroFilter的配置信息获得java.servlet.Filter和FilterChain(java.util.LinkedHashMap.Entry),存储Shiro的默认Filter和解析xml获得的Filter,存储FilterChain(这其中还会有创建Chain(org.apache.shiro.web.filter.mgt.NamedFilterList)的行为),包装javax.servlet.FilterChain

    org.apache.shiro.web.filter.mgt.NamedFilterList

      职责是存储Chain Name,存储javax.servlet.Filter,包装javax.servlet.FilterChain为org.apache.shiro.web.servlet.ProxiedFilterChain

    org.apache.shiro.web.filter.mgt.FilterChainResolver

      职责是获得javax.servlet.FilterChain,过程为FilterChainManager.proxy(javax.servlet.FilterChain,String chainName) ==> NamedFilterList.proxy(javax.servlet.FilterChain,String chainName) ==> Result:org.apache.shiro.web.servlet.ProxiedFilterChain

    org.apache.shiro.util.PatternMatcher

      职责是判断requestURI是否与chainName匹配

  • 相关阅读:
    struct与class的区别
    C#锐利体验第五讲 构造器与析构器(转)
    Sort Table
    WinXP(NTFS分区下)Vista系统文件的删除方法
    关于上海居住证我们不得不说的实情!(转)
    让你眼花缭乱的JS代码~~
    ASP的URL重写技术(IIS的ISAPI)[转]
    JS实现从照片中裁切自已的肖像
    C#锐利体验第二讲 C#语言基础介绍(转)
    装箱和拆箱
  • 原文地址:https://www.cnblogs.com/BINGJJFLY/p/9354709.html
Copyright © 2011-2022 走看看