SpringSecurity源码分析

 

1 web.xml文件中配置

问题:为什么DelegatingFilterProxyfifilter-name必须是springSecurityFilterChain?

DelegatingFilterProxy并不是真正的Filter,在其initFilterBean方法中会从WebApplicationContext根据delegate

来获取到

在上这代码中this.targetBeanName=getFilterName()就是获取名称叫做springSecurityFilterChain

通过在doFilter就去中我们会发现真正干活的其实是delegate这个Filter,delegate其实就是FilterChainProxy

protected void initFilterBean() throws ServletException {

synchronized (this.delegateMonitor) {

if (this.delegate == null) {

// If no target bean name specified, use filter name.

if (this.targetBeanName == null) {

this.targetBeanName = getFilterName();

}

// Fetch Spring root application context and initialize the delegate early,

// if possible. If the root application context will be started after this

// filter proxy, we'll have to resort to lazy initialization.

WebApplicationContext wac = findWebApplicationContext();

if (wac != null) {

this.delegate = initDelegate(wac);

}

}

}

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)

throws ServletException, IOException {

// Lazily initialize the delegate if necessary.

Filter delegateToUse = this.delegate;

if (delegateToUse == null) {

synchronized (this.delegateMonitor) {

FilterChainProxyspring在解析配置文件时装配到上下文中,并且beanNamespringSecurityFilterChain

因此在web.xml中需要配置fifilter-namespringSecurityFilterChain

2.spring-security.xml文件中配置

在配置文件中我们主要使用标签来过多成配置

http标签是自定义标签,我们可以在spring-security-confifig包中查看

继续查看SecurityNamespaceHandler类,在其init方法

delegateToUse = this.delegate;

if (delegateToUse == null) {

WebApplicationContext wac = findWebApplicationContext();

if (wac == null) {

throw new IllegalStateException("No WebApplicationContext found: " +

"no ContextLoaderListener or DispatcherServlet registered?");

}

delegateToUse = initDelegate(wac);

}

this.delegate = delegateToUse;

}

}

// Let the delegate perform the actual doFilter operation.

invokeDelegate(delegateToUse, request, response, filterChain);

}

<!-- 配置不拦截的资源 -->

<security:http pattern="/login.jsp" security="none"/>

<security:http pattern="/failer.jsp" security="none"/>

<security:http pattern="/css/**" security="none"/>

<security:http pattern="/img/**" security="none"/>

<security:http pattern="/plugins/**" security="none"/>

<security:http auto-config="true" use-expressions="false">

<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>

<security:form-login

login-page="/login.jsp"

login-processing-url="/login.do"

default-target-url="/index.jsp"

authentication-failure-url="/failer.jsp"

authentication-success-forward-url="/pages/main.jsp"

/>

</security:http>

http\://www.springframework.org/schema/security=org.springframework.security.config.SecurityName

spaceHandler

loadParsers()方法中,指定由HttpSecurityBeanDefifinitionParser进行解析

HttpSecurityBeanDefifinitionParser完成具体解析的parse方法中

这里就是注册了名为springSecurityFilterChainfifilterChainProxy

接下我们在看一下注册一系列Filter的地方createFilterChain,在这个方法中我们重点关注

我们可以查看AuthenticationConfifigBuilder创建代码

public void init() {

loadParsers();

}

parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser());

registerFilterChainProxyIfNecessary(pc, pc.extractSource(element));

AuthenticationConfigBuilder authBldr = new AuthenticationConfigBuilder(element,

forceAutoConfig, pc, httpBldr.getSessionCreationPolicy(),

httpBldr.getRequestCache(), authenticationManager,

httpBldr.getSessionStrategy(), portMapper, portResolver,

httpBldr.getCsrfLogoutHandler());

public AuthenticationConfigBuilder(Element element, boolean forceAutoConfig,

ParserContext pc, SessionCreationPolicy sessionPolicy,

BeanReference requestCache, BeanReference authenticationManager,

BeanReference sessionStrategy, BeanReference portMapper,

BeanReference portResolver, BeanMetadataElement csrfLogoutHandler) {

this.httpElt = element;

this.pc = pc;

this.requestCache = requestCache;

autoConfig = forceAutoConfig

| "true".equals(element.getAttribute(ATT_AUTO_CONFIG));

this.allowSessionCreation = sessionPolicy != SessionCreationPolicy.NEVER

&& sessionPolicy != SessionCreationPolicy.STATELESS;

this.portMapper = portMapper;

this.portResolver = portResolver;

this.csrfLogoutHandler = csrfLogoutHandler;

createAnonymousFilter();

createRememberMeFilter(authenticationManager);

createBasicFilter(authenticationManager);

createFormLoginFilter(sessionStrategy, authenticationManager);

createOpenIDLoginFilter(sessionStrategy, authenticationManager);

createX509Filter(authenticationManager);

createJeeFilter(authenticationManager);

createLogoutFilter();

createLoginPageFilterIfNeeded();

createUserDetailsServiceFactory();

createExceptionTranslationFilter();

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值