首页 > 编程语言 >spring-security源码-如何初始化SecurityFilterChain到Servlet

spring-security源码-如何初始化SecurityFilterChain到Servlet

时间:2024-03-10 15:14:02浏览次数:29  
标签:requestMatcher return spring class SecurityFilterChain 源码 delegate filters publi

1.SecurityFilterChain是由HttpSecurty根据各个config配置生成的Filter

SecurityFilterChain是接口,默认实现是由DefaultSecurityFilterChain SecurityFilterChain只充当描述的作用,描述哪些url走这批filter
public final class DefaultSecurityFilterChain implements SecurityFilterChain {
    private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
    //匹配url 多套url登录逻辑由这里实现 默认/** 比如/product  /user 逻辑相互隔离
    private final RequestMatcher requestMatcher;
    //相关servlet
    private final List<Filter> filters;

    public DefaultSecurityFilterChain(RequestMatcher requestMatcher, Filter... filters) {
        this(requestMatcher, Arrays.asList(filters));
    }

    public DefaultSecurityFilterChain(RequestMatcher requestMatcher, List<Filter> filters) {
        if (filters.isEmpty()) {
            logger.info(LogMessage.format("Will not secure %s", requestMatcher));
        } else {
            logger.info(LogMessage.format("Will secure %s with %s", requestMatcher, filters));
        }

        this.requestMatcher = requestMatcher;
        this.filters = new ArrayList(filters);
    }

    public RequestMatcher getRequestMatcher() {
        return this.requestMatcher;
    }

    public List<Filter> getFilters() {
        return this.filters;
    }

    public boolean matches(HttpServletRequest request) {
        return this.requestMatcher.matches(request);
    }

    public String toString() {
        return this.getClass().getSimpleName() + " [RequestMatcher=" + this.requestMatcher + ", Filters=" + this.filters + "]";
    }
}

2.初始化是通过

org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration 实现

@AutoConfiguration(after = SecurityAutoConfiguration.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SecurityProperties.class)
@ConditionalOnClass({ AbstractSecurityWebApplicationInitializer.class, SessionCreationPolicy.class })
public class SecurityFilterAutoConfiguration {

    private static final String DEFAULT_FILTER_NAME = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME;

    //存在 springSecurityFilterChain
    @Bean
    @ConditionalOnBean(name = DEFAULT_FILTER_NAME)
    public DelegatingFilterProxyRegistrationBean securityFilterChainRegistration(
            SecurityProperties securityProperties) {
//<3> DelegatingFilterProxyRegistrationBean registration = new DelegatingFilterProxyRegistrationBean( DEFAULT_FILTER_NAME); registration.setOrder(securityProperties.getFilter().getOrder()); registration.setDispatcherTypes(getDispatcherTypes(securityProperties)); return registration; } private EnumSet<DispatcherType> getDispatcherTypes(SecurityProperties securityProperties) { if (securityProperties.getFilter().getDispatcherTypes() == null) { return null; } return securityProperties.getFilter() .getDispatcherTypes() .stream() .map((type) -> DispatcherType.valueOf(type.name())) .collect(Collectors.toCollection(() -> EnumSet.noneOf(DispatcherType.class))); } }

<3>

委托给DelegatingFilterProxyRegistrationBean

他是 org.springframework.boot.web.servlet.AbstractFilterRegistrationBean的子类,用于注入自定义filter,实现了getFilter方法

org.springframework.boot.web.servlet.DelegatingFilterProxyRegistrationBean#getFilter

public DelegatingFilterProxy getFilter() {
//<4>ServletFilter的实现类 return new DelegatingFilterProxy(this.targetBeanName, this.getWebApplicationContext()) { protected void initFilterBean() throws ServletException { } }; }

<4>

DelegatingFilterProxy就是sevletFilter的实现类

org.springframework.web.filter.DelegatingFilterProxy#doFilter

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        Filter delegateToUse = this.delegate;
        if (delegateToUse == null) {
            synchronized(this.delegateMonitor) {
                delegateToUse = this.delegate;
                if (delegateToUse == null) {
                    WebApplicationContext wac = this.findWebApplicationContext();
                    if (wac == null) {
                        throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener or DispatcherServlet registered?");
                    }
                    //<5>delegate初始化
                    delegateToUse = this.initDelegate(wac);
                }

                this.delegate = delegateToUse;
            }
        }
       // <6>最终是委托给delegate执行的
        this.invokeDelegate(delegateToUse, request, response, filterChain);
    }

<5>

org.springframework.web.filter.DelegatingFilterProxy#initDelegate

   protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
        String targetBeanName = this.getTargetBeanName();
        Assert.state(targetBeanName != null, "No target bean name set");
        //就是我们的 springSecurityFilterChain
        Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class);
        if (this.isTargetFilterLifecycle()) {
            delegate.init(this.getFilterConfig());
        }

        return delegate;
    }

 

<6>

org.springframework.web.filter.DelegatingFilterProxy#invokeDelegate

 protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        delegate.doFilter(request, response, filterChain);
    }

 

 

 

标签:requestMatcher,return,spring,class,SecurityFilterChain,源码,delegate,filters,publi
From: https://www.cnblogs.com/LQBlog/p/18064192

相关文章

  • SpringMVC声明式事务
    事务并发、传播性、隔离级别(重难点)导读:本节重点在于多线程并发环境下的事务处理、和数据库在并发环境下的表锁和行锁。案例:在新增图书的时候,肯定需要先新增作者。SpringMVC声明式事务事务分两种:编程式事务、声明式事务Connectionconnconn.setAutoCommit(false)conn.comm......
  • 通达信空转多反击副图指标公式源码
    {通达信空转多反击副图指标公式源码}ZEROS:0,NODRAW;RSV:=(CLOSE-LLV(LOW,9))/(HHV(HIGH,9)-LLV(LOW,9))*100;K:=SMA(RSV,3,1);D:=SMA(K,3,1);J:=3*K-2*D;VARV:=(2*C+H+L)/4;VARU:=LLV(LOW,30);VARA1:=HHV(HIGH,30);B:=EMA((VARV-VARU)/(VARA1-VARU)*100,8);B1:=EMA......
  • 通达信强烈反转指标,趋势改变上翘有力度源码
    {通达信强烈反转指标,趋势改变上翘有力度源码}N1:=20;N2:=60;VAR1:=(LOW+HIGH+CLOSE)/3;X:MA(VAR1,5);A1:HHV(X,N1)COLORMAGENTA;A2:HHV(X,N2),COLORGREEN;A3:HHV(HIGH,N2)*0.98,COLOR0000FF;B1:LLV(X,N1);B2:LLV(LOW,N2)*1.02;DRAWICON(X>B1ANDREF(X,1)=REF......
  • 通达信龙头起涨指标公式源码
    {通达信龙头起涨指标公式源码}趋势:EMA(100*(C-LLV(LOW,34))/(HHV(H,34)-LLV(LOW,34)),3),COLORRED;强弱:30,COLORWHITE;逃顶:90,COLORWHITE;Jbs:=C/REF(C,1)>1.05ANDC=HANDBETWEEN(FORCAST(V,4),0.2*FORCAST(V,12),2.1*FORCAST(V,12));必升:=FILTER(JBS,28)*100;VAR......
  • 通达信股价飞升指标公式源码副图
    {通达信股价飞升指标公式源码副图}VAR11:=3*SMA((C-LLV(L,480))/(HHV(H,480)-LLV(L,480))*100,5,1)-2*SMA(SMA((C-LLV(L,480))/(HHV(H,480)-LLV(L,480))*100,180,1),15,1);超级主升:=EMA(VAR11,5);主升1:=超级主升-100;D1:=EMA(C,5);D2:=(EMA(C,1)+EMA(C,5)+EMA(C,10)+EM......
  • 通达信跳空缺口完美版主图指标公式源码
    {通达信跳空缺口完美版主图指标公式源码}N:=30;LL:=REF(L,1);HH:=REF(H,1);SQK:=L>HH;XQK:=H<ll;向上跳几元钱:IF(SQK=1,L-HH,DRAWNULL),COLORGREEN,crOSSDOT,LINETHICK3,NODRAW;逃命跳空元:IF(XQK=1,H-LL,DRAWNULL),COLORYELLOW,CROSSDOT,LINETHICK3,NODRAW;DRAWTEXT(......
  • 通达信突破当天买入主图指标公式源码
    {通达信突破当天买入主图指标公式源码}{#跨周期时,可能会引用到未来数据}X_A:=cci#WEEK;X_B:=CCI#MONTH;突破当天买入:=X_B-REF(X_B,1)>90ORX_A-REF(X_A,1)>70;DRAWTEXT(突破当天买入,LLV(L,8),'突破当天买入'); ......
  • 通达信大牛异动指标公式源码
    {通达信大牛异动指标公式源码}N:=10;N1:=5;N2:=3;X_1:=REF(CLOSE,1)<ref(close,2)and=""close="">REF(CLOSE,1);X_2:=REF(CLOSE,1)>REF(CLOSE,2)ANDCLOSE<ref(close,1);<span="">X_3:=CLOSE=REF(CLOSE,1);X_4:=REF(CLOSE,1......
  • 通达信顶底准确指标公式源码
    {通达信顶底准确指标公式源码}VDD6:=MA(CLOSE,1);VDD8:=(LOW+HIGH+CLOSE)/3;VDD7:=MA(VDD8,5);顶底准确率:=LLV(VDD7,10);技术指标:=LLV((VDD6<顶底准确率),5);准确率100:=LLV((VDD6<顶底准确率),10);STICKLINE(准确率100,0,100,3,0),COLORRED;STICKLINE(技术指标,0,5......
  • 通达信价格笼子警示主图指标公式源码
    {通达信价格笼子警示主图指标公式源码}STB:=IF(INBLOCK('ST板块'),1,0);TSB:=IF(INBLOCK('ST板块')ANDCODELIKE('30')ANDDATE>1200823,1,0);{2020月8月24日创业板ST开始20%涨跌幅}BK:=IF(CODELIKE('68'),0.2,IF(CODELIKE('30')ANDDATE>12......