SpringSecurity源码分析

1 web.xml文件中配置

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

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

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);
}
}
}
}
在上这代码中 this.targetBeanName=getFilterName() 就是获取名称叫做 springSecurityFilterChain
通过在 doFilter 就去中我们会发现真正干活的其实是 delegate 这个 Filter, delegate 其实就是 FilterChainProxy
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) {
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);
}
FilterChainProxy spring 在解析配置文件时装配到上下文中,并且 beanName springSecurityFilterChain
因此在 web.xml 中需要配置 filter-name springSecurityFilterChain

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

在配置文件中我们主要使用标签来过多成配置
<!-- 配置不拦截的资源 -->
<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 标签是自定义标签,我们可以在 spring-security-config 包中查看

http\://www.springframework.org/schema/security=org.springframework.security.config.SecurityName
spaceHandler
继续查看 SecurityNamespaceHandler 类,在其 init 方法
public void init() {
loadParsers();
}
loadParsers() 方法中,指定由 HttpSecurityBeanDefinitionParser 进行解析
parsers.put(Elements.HTTP, new HttpSecurityBeanDefinitionParser())

HttpSecurityBeanDefinitionParser 完成具体解析的 parse 方法中
registerFilterChainProxyIfNecessary(pc, pc.extractSource(element));

这里就是注册了名为 springSecurityFilterChain filterChainProxy
接下我们在看一下注册一系列 Filter 的地方 createFilterChain ,在这个方法中我们重点关注
AuthenticationConfigBuilder authBldr = new AuthenticationConfigBuilder(element,
forceAutoConfig, pc, httpBldr.getSessionCreationPolicy(),
httpBldr.getRequestCache(), authenticationManager,
httpBldr.getSessionStrategy(), portMapper, portResolver,
httpBldr.getCsrfLogoutHandler());
我们可以查看 AuthenticationConfigBuilder 创建代码
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();

}

相关推荐

  1. SpringSecurity学习六:授权

    2024-02-18 13:34:01       31 阅读
  2. 【第二篇】SpringSecurity详解

    2024-02-18 13:34:01       9 阅读
  3. SpringSecurity学习七:OAuth 2.0登录

    2024-02-18 13:34:01       34 阅读
  4. SDWebImage分析

    2024-02-18 13:34:01       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-18 13:34:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-18 13:34:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-18 13:34:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-18 13:34:01       20 阅读

热门阅读

  1. AWS认证SAA-C03每日一题

    2024-02-18 13:34:01       26 阅读
  2. https 为什么安全

    2024-02-18 13:34:01       33 阅读
  3. CDF和PDF的比较

    2024-02-18 13:34:01       27 阅读
  4. MCU中断里使用软延时函数delay_ms(u16 x)问题探讨:

    2024-02-18 13:34:01       31 阅读
  5. 工作心得——css让元素居中的方法

    2024-02-18 13:34:01       33 阅读
  6. devc++ 使用 winsock 实现 UDP 广播

    2024-02-18 13:34:01       34 阅读
  7. (一)初识C++

    2024-02-18 13:34:01       38 阅读
  8. StarRocks表设计——排序键和数据模型

    2024-02-18 13:34:01       29 阅读
  9. MySql优化策略

    2024-02-18 13:34:01       30 阅读
  10. 智能家居控制系统:让生活更智能、更便捷

    2024-02-18 13:34:01       36 阅读