Spring Shiro基础组件 FilterChainResolver

相关阅读

简介

FilterChainResolver可以在ServletRequest请求过程中解析正确的过滤器链去执行,允许为任意请求或者URI/URL解析可以执行的任意过滤器链;
这种过滤器解析机制比通过web.xml定义servlet过滤器的方式更加灵活;

核心方法

/**
 * 获取给定request的过滤器链
 * 返回值为null,表示使用原始过滤器链
 */
FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);

实现子类

public interface FilterChainResolver
    public class PathMatchingFilterChainResolver implements FilterChainResolver

PathMatchingFilterChainResolver

简介

根据URL路径匹配,解析出ServletRequest请求过程中要执行的过滤器链;

核心方法

// 过滤器链管理器
private FilterChainManager filterChainManager;

// 路径匹配器
private PatternMatcher pathMatcher;

// 默认路径分隔符
private static final String DEFAULT_PATH_SEPARATOR = "/";

/**
 * 构造方法
 */
public PathMatchingFilterChainResolver() {
    // 默认为AntPathMatcher
    this.pathMatcher = new AntPathMatcher();
    // 默认为DefaultFilterChainManager
    this.filterChainManager = new DefaultFilterChainManager();
}

/**
 * 构造方法
 */
public PathMatchingFilterChainResolver(FilterConfig filterConfig) {
    // 默认为AntPathMatcher
    this.pathMatcher = new AntPathMatcher();
    // 默认为DefaultFilterChainManager
    this.filterChainManager = new DefaultFilterChainManager(filterConfig);
}

/**
 * 获取给定request的过滤器链
 * 返回值为null,表示使用原始过滤器链
 */
public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
    FilterChainManager filterChainManager = getFilterChainManager();
    if (!filterChainManager.hasChains()) {
        // 无配置,则使用原始过滤器链
        return null;
    }

    // 获取应用程序内的URI的相对路径
    final String requestURI = getPathWithinApplication(request);
    // 去除URL路径结尾处分隔符
    final String requestURINoTrailingSlash = removeTrailingSlash(requestURI);

    // 遍历配置的管理器链
    //the 'chain names' in this implementation are actually path patterns defined by the user.  We just use them
    //as the chain name for the FilterChainManager's requirements
    for (String pathPattern : filterChainManager.getChainNames()) {
        // If the path does match, then pass on to the subclass implementation for specific checks:
        if (pathMatches(pathPattern, requestURI)) {
            if (log.isTraceEnabled()) {
                log.trace("Matched path pattern [{}] for requestURI [{}].  " +
                        "Utilizing corresponding filter chain...", pathPattern, Encode.forHtml(requestURI));
            }
            // 代理原始过滤器链,即先执行配置的Shiro过滤器链,再执行原始过滤器链
            return filterChainManager.proxy(originalChain, pathPattern);
        } else {

            // in spring web, the requestURI "/resource/menus" ---- "resource/menus/" bose can access the resource
            // but the pathPattern match "/resource/menus" can not match "resource/menus/"
            // user can use requestURI + "/" to simply bypassed chain filter, to bypassed shiro protect

            // 对配置的路径去除结尾处分隔符,再进行一次匹配
            pathPattern = removeTrailingSlash(pathPattern);

            if (pathMatches(pathPattern, requestURINoTrailingSlash)) {
                if (log.isTraceEnabled()) {
                    log.trace("Matched path pattern [{}] for requestURI [{}].  " +
                              "Utilizing corresponding filter chain...", pathPattern, Encode.forHtml(requestURINoTrailingSlash));
                }
                // 代理原始过滤器链,即先执行配置的Shiro过滤器链,再执行原始过滤器链
                return filterChainManager.proxy(originalChain, requestURINoTrailingSlash);
            }
        }
    }

    // 无配置,则使用原始过滤器链
    return null;
}

/**
 * 路径匹配
 */
protected boolean pathMatches(String pattern, String path) {
    PatternMatcher pathMatcher = getPathMatcher();
    return pathMatcher.matches(pattern, path);
}

/**
 * 获取应用程序内的URI的相对路径
 */
protected String getPathWithinApplication(ServletRequest request) {
    return WebUtils.getPathWithinApplication(WebUtils.toHttp(request));
}

/**
 * 去除URL路径结尾处分隔符
 */
private static String removeTrailingSlash(String path) {
    if(path != null && !DEFAULT_PATH_SEPARATOR.equals(path)
       && path.endsWith(DEFAULT_PATH_SEPARATOR)) {
        return path.substring(0, path.length() - 1);
    }
    return path;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值