spring-security源码-FilterChainProxy

FilterChainProxy内部存储了我们各个HttpSecurty生成的SecurityFilterChain。FilterChainProxy实现了ServletFilter接口。只真正的入口

org.springframework.security.web.FilterChainProxy.doFilter

复制代码
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
        if (!clearContext) {
            this.doFilterInternal(request, response, chain);
        } else {
            try {
                request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
                <1>执行
                this.doFilterInternal(request, response, chain);
            } catch (Exception var11) {
                Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(var11);
                Throwable requestRejectedException = this.throwableAnalyzer.getFirstThrowableOfType(RequestRejectedException.class, causeChain);
                if (!(requestRejectedException instanceof RequestRejectedException)) {
                    throw var11;
                }

                //自定义异常处理器
                this.requestRejectedHandler.handle((HttpServletRequest)request, (HttpServletResponse)response, (RequestRejectedException)requestRejectedException);
            } finally {
                //清理
                SecurityContextHolder.clearContext();
                request.removeAttribute(FILTER_APPLIED);
            }

        }
    }
复制代码

<1>

org.springframework.security.web.FilterChainProxy#doFilterInternal

复制代码
 private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest)request);
        HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse)response);
        <2>根据url获取filters 多登录逻辑实现
        List<Filter> filters = this.getFilters((HttpServletRequest)firewallRequest);
        if (filters != null && filters.size() != 0) {
            if (logger.isDebugEnabled()) {
                logger.debug(LogMessage.of(() -> {
                    return "Securing " + requestLine(firewallRequest);
                }));
            }

            VirtualFilterChain virtualFilterChain = new VirtualFilterChain(firewallRequest, chain, filters);
            //执行filter
            virtualFilterChain.doFilter(firewallRequest, firewallResponse);
        } else {
            if (logger.isTraceEnabled()) {
                logger.trace(LogMessage.of(() -> {
                    return "No security for " + requestLine(firewallRequest);
                }));
            }

            firewallRequest.reset();
            chain.doFilter(firewallRequest, firewallResponse);
        }
    }
复制代码

<2>

org.springframework.security.web.FilterChainProxy#getFilters(javax.servlet.http.HttpServletRequest)

复制代码
  private List<Filter> getFilters(HttpServletRequest request) {
        int count = 0;
        Iterator var3 = this.filterChains.iterator();

        SecurityFilterChain chain;
        do {
            if (!var3.hasNext()) {
                return null;
            }

            chain = (SecurityFilterChain)var3.next();
            if (logger.isTraceEnabled()) {
                ++count;
                logger.trace(LogMessage.format("Trying to match request against %s (%d/%d)", chain, count, this.filterChains.size()));
            }
        } while(!chain.matches(request));

        return chain.getFilters();
    }
复制代码

 

posted @   意犹未尽  阅读(108)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
历史上的今天:
2020-03-10 dubbo源码阅读-dubbo SPI实现原理(五)
点击右上角即可分享
微信分享提示