Spring Security中代理过滤器是通过FilterChain如何工作的
来源:互联网 发布:java gzip 编辑:程序博客网 时间:2024/05/22 09:02
我们在搭建Spring Security框架的第一步配置是在项目的web.xml添加代理过滤器,配置如下
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
由此我我们可以得出一个结果,所有的请求都会经过DelegatingFilterProxy,从而实现权限的控制。让我们来看一下DelegatingFilterProxy的doFilter方法是如何实现的。
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) {if (this.delegate == null) {WebApplicationContext wac = findWebApplicationContext();if (wac == null) {throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");}this.delegate = initDelegate(wac);}delegateToUse = this.delegate;}}// Let the delegate perform the actual doFilter operation.invokeDelegate(delegateToUse, request, response, filterChain);}
最后调用invokeDelegate方法,让我们来看一下invokeDelegate方法。
protected void invokeDelegate(Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)throws ServletException, IOException {delegate.doFilter(request, response, filterChain);}
由此可见,请求在进入DelegatingFilterProxy后是实际上由delegate做的处理。那这个delegate是如何来得呢?由上面的
this.delegate = initDelegate(wac);可以看出,是通过initDelegate方法得到的。
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {Filter delegate = wac.getBean(getTargetBeanName(), Filter.class);if (isTargetFilterLifecycle()) {delegate.init(getFilterConfig());}return delegate;}
由此可见,delegate是在Spring容器的一个名为getTargetBeanName方法返回的字符串的bean.而这个方法的返回值就是我们在web.xml配置的<filter-name>的值springSecurityFilterChain。现在我们来探究一下这个bean的出处。
我们在spring的配置文件中搜索,发现并没有注册名为springSecurityFilterChain的bean,可以得出这个bean不是我们通过配置得到的,而是从代码层面实现的。
所以我们唯一的切入点就是为Spring的配置文件添加的Spring Security添加的xsd了。对Spring配置文件的解析都是通过BeanDefinitionParser来实现的,所以我们发现了一个叫做HttpSecurityBeanDefinitionParser的一个类。
@SuppressWarnings({"unchecked"}) public BeanDefinition parse(Element element, ParserContext pc) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)); pc.pushContainingComponent(compositeDef); //此方法就是用来将注册名为springSecurityFilterChain的bean. registerFilterChainProxyIfNecessary(pc, pc.extractSource(element)); // Obtain the filter chains and add the new chain to it BeanDefinition listFactoryBean = pc.getRegistry().getBeanDefinition(BeanIds.FILTER_CHAINS); List<BeanReference> filterChains = (List<BeanReference>) listFactoryBean.getPropertyValues().getPropertyValue("sourceList").getValue(); filterChains.add(createFilterChain(element, pc)); pc.popAndRegisterContainingComponent(); return null; }
static void registerFilterChainProxyIfNecessary(ParserContext pc, Object source) { if (pc.getRegistry().containsBeanDefinition(BeanIds.FILTER_CHAIN_PROXY)) { return; } // Not already registered, so register the list of filter chains and the FilterChainProxy BeanDefinition listFactoryBean = new RootBeanDefinition(ListFactoryBean.class); listFactoryBean.getPropertyValues().add("sourceList", new ManagedList()); pc.registerBeanComponent(new BeanComponentDefinition(listFactoryBean, BeanIds.FILTER_CHAINS)); BeanDefinitionBuilder fcpBldr = BeanDefinitionBuilder.rootBeanDefinition(FilterChainProxy.class); fcpBldr.getRawBeanDefinition().setSource(source); fcpBldr.addConstructorArgReference(BeanIds.FILTER_CHAINS); fcpBldr.addPropertyValue("filterChainValidator", new RootBeanDefinition(DefaultFilterChainValidator.class)); BeanDefinition fcpBean = fcpBldr.getBeanDefinition(); pc.registerBeanComponent(new BeanComponentDefinition(fcpBean, BeanIds.FILTER_CHAIN_PROXY)); //此段代码注册一个类进入到Spring的容器中 pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN); }这个类就是Spring Security进行过滤链初始化配置的的核心类。其中createFilterChain方法就是对Security配置文件解析以及自定义过滤器、默认过滤器进行添加的核心方法。
阅读全文
0 0
- Spring Security中代理过滤器是通过FilterChain如何工作的
- spring security 中spring bean组成的过滤器链如何初始化的
- spring-security的过滤器执行
- spring security中核心过滤器的基本作用
- spring security 2中使用通过自定义过滤器实现多登录页面
- spring security 二中使用通过自定义过滤器实现多登录页面
- Spring的AOP是如何实现代理
- spring security的form-login是如何关联dao的
- 图解Spring Security默认使用的过滤器
- 关于Spring-security的过滤器分析
- Spring Security 默认的过滤器链
- Servlet_Filter(过滤器)及FilterChain的使用详解
- Spring AutoConfigurationMetadataLoader是如何工作的 ?
- Spring ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry() 是如何工作的 ?
- Spring EnableAutoConfigurationImportSelector 是如何工作的 ?
- spring-boot-autoconfigure 是如何工作的?
- Spring MVC 到底是如何工作的?
- Spring Boot是如何工作的?
- Android运行程序在各层架构之间的相互关系
- Spring Boot 整合 MyBatis
- 【WEB API项目实战干货系列】- WEB API入门(一)
- ACM一些坑 (1)
- 你觉得程序员适合干一辈子吗?
- Spring Security中代理过滤器是通过FilterChain如何工作的
- Android UsbManager 获取不到HID设备(实际上就是Input设备)怎样通信的问题(已解决)!
- OpenSSL握手重协商过程中存在漏洞可导致拒绝服务
- 第七届蓝桥杯国赛 一步之遥
- 我与python约个会:23. 企业级开发基础4:面向对象
- 【备忘】甲骨论 价值1.67万的Oracle视频课程 共46节课
- 【win7】Python安装+gensim包安装
- 【WEB API项目实战干货系列】- 接口文档与在线测试(二)
- RecyclerView删除Item导致位置错乱问题