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匹配

 

转载于:https://www.cnblogs.com/BINGJJFLY/p/9354709.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值