SpringSecurity的Filter链式调用机制

来源:互联网 发布:鳄鱼肉 知乎 编辑:程序博客网 时间:2024/06/18 13:25

本文通过书写自定义拦截器的方式模仿SpringSecurity中Filter的链式调用机制

在web.xml中配置拦截器,自定义拦截器

<filter>  <filter-name>springSecurityFilterChain</filter-name>  <filter-class>com.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping>  <filter-name>springSecurityFilterChain</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>

被拦截器拦截下的请求会进入DelegatingFilterProxy 中

package com.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.springframework.web.filter.GenericFilterBean;public class DelegatingFilterProxy extends GenericFilterBean {    private Filter delegate=new FilterChainProxy();    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain filterChain) throws IOException, ServletException {        // TODO Auto-generated method stub        // Let the delegate perform the actual doFilter operation.        invokeDelegate(delegate,request,response,filterChain);    }    private void invokeDelegate(Filter delagate, ServletRequest request,            ServletResponse response, FilterChain filterChain) throws IOException, ServletException {        // TODO Auto-generated method stub        delagate.doFilter(request, response, filterChain);    }}

实现链式调用的核心环节

package com.filter;import java.io.IOException;import java.util.ArrayList;import java.util.List;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import org.springframework.security.web.FilterInvocation;import org.springframework.web.filter.GenericFilterBean;public class FilterChainProxy extends GenericFilterBean implements Filter {    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain fc) throws IOException, ServletException {        // TODO Auto-generated method stub        // 此处的List为举例数据,实际情况中可以动态获取        FilterInvocation fi=new FilterInvocation(request,response,fc);        List<Filter> filters = getFilters(fi.getRequest());        if (filters == null || filters.size() == 0) {            fc.doFilter(request, response);            return;        }        VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters);        virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());    }    private List<Filter> getFilters(HttpServletRequest request) {        // TODO Auto-generated method stub        List<Filter> filters=new ArrayList<Filter>();        filters.add(new UsernamePasswordAuthenticationFilter());        return filters;    }    private static class VirtualFilterChain implements FilterChain {            private final FilterInvocation fi;            private final List<Filter> additionalFilters;            private final int size;            private int currentPosition = 0;            private VirtualFilterChain(FilterInvocation filterInvocation, List<Filter> additionalFilters) {                this.fi = filterInvocation;                this.additionalFilters = additionalFilters;                this.size = additionalFilters.size();            }            public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {                if (currentPosition == size) {                    fi.getChain().doFilter(request, response);                } else {                    currentPosition++;                    Filter nextFilter = additionalFilters.get(currentPosition - 1);                    nextFilter.doFilter(request, response, this);                }            }        }}

样例UsernamePasswordAuthenticationFilter 类,作为链中的一环出现

package com.filter;import java.io.IOException;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.springframework.web.filter.GenericFilterBean;public class UsernamePasswordAuthenticationFilter extends GenericFilterBean {    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain fc) throws IOException, ServletException {        // TODO Auto-generated method stub        System.out.println("-----------");        fc.doFilter(request, response);        System.out.println("-----------");    }}
0 0
原创粉丝点击