HttpSecurityBeanDefinitionParser是众多SpringSecurity解析器中的一种,也是最为核心的一个解析器,其解析的节点是http声明的节点。
其主要作用有两个,
- 实例化org.springframework.security.web.FilterChainProxy,并将其注入到Spring容器当中;
- 根据配置文件初始化SpringSecurity的过滤器链,并将其注入到FilterChainProxy实例的filterChains属性中;
那么,这个类是如何将FilterChainProxy实例化并注入到Spring容器当中的呢?让我们直接贴代码
在我们解析xml文件的http节点时,首先进入这个类的parse方法
public BeanDefinition parse(Element element, ParserContext pc) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), pc.extractSource(element)); pc.pushContainingComponent(compositeDef); //这个方法就是实例化FilterChainProxy对象,并注入进Spring容器 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(); //createFilterChain方法是得到过滤链
pc.popAndRegisterContainingComponent(); return null; } 让我们来查看一下registerFilterChainProxyIfNecessary是如何做到的filterChains.add(createFilterChain(element, pc));
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 //创造一个ListFactoryBean,这个类的具体用法可以参考http://www.ithao123.cn/content-10108965.html BeanDefinition listFactoryBean = new RootBeanDefinition(ListFactoryBean.class); listFactoryBean.getPropertyValues().add("sourceList", new ManagedList()); pc.registerBeanComponent(new BeanComponentDefinition(listFactoryBean, BeanIds.FILTER_CHAINS)); //创造一个FilterChainProxy实例
fcpBldr.getRawBeanDefinition().setSource(source);BeanDefinitionBuilder fcpBldr = BeanDefinitionBuilder.rootBeanDefinition(FilterChainProxy.class);
//为定义添加构造方法参数,其指向的是一个listFactoryBean,实例化的时候会将listFactoryBean中的sourceList属性值付给对应的属性
fcpBldr.addPropertyValue("filterChainValidator", new RootBeanDefinition(DefaultFilterChainValidator.class)); BeanDefinition fcpBean = fcpBldr.getBeanDefinition();fcpBldr.addConstructorArgReference(BeanIds.FILTER_CHAINS);
//注入到Spring容器中,指定bean的id为org.springframework.security.filterChainProxy
pc.registerBeanComponent(new BeanComponentDefinition(fcpBean, BeanIds.FILTER_CHAIN_PROXY));
//设置此bean的别名为springSecurityFilterChain
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN); } 让我们来查看一下createFilterChain方法是如何获取filterChains的private BeanReference createFilterChain(Element element, ParserContext pc) { //判断http节点的security属性是否为none值,如果是,则返回一个空的过滤器链,表示这个url不经过springsecurity的拦截 boolean secured = !OPT_SECURITY_NONE.equals(element.getAttribute(ATT_SECURED)); if (!secured) { //........... return createSecurityFilterChainBean(element, pc, Collections.emptyList()); } final BeanReference portMapper = createPortMapper(element, pc); final BeanReference portResolver = createPortResolver(portMapper, pc); ManagedList<BeanReference> authenticationProviders = new ManagedList<BeanReference>(); BeanReference authenticationManager = createAuthenticationManager(element, pc, authenticationProviders); //对有关于http请求的节点属性进行解析 HttpConfigurationBuilder httpBldr = new HttpConfigurationBuilder(element, pc, portMapper, portResolver, authenticationManager); //对授权认证方面节点属性进行解析 AuthenticationConfigBuilder authBldr = new AuthenticationConfigBuilder(element, pc, httpBldr.getSessionCreationPolicy(), httpBldr.getRequestCache(), authenticationManager, httpBldr.getSessionStrategy(), portMapper, portResolver); //设置登出成功的处理器 httpBldr.setLogoutHandlers(authBldr.getLogoutHandlers()); authenticationProviders.addAll(authBldr.getProviders()); List<OrderDecorator> unorderedFilterChain = new ArrayList<OrderDecorator>(); //添加关于http的一些拦截器 unorderedFilterChain.addAll(httpBldr.getFilters()); //添加授权认证的一些拦截器 unorderedFilterChain.addAll(authBldr.getFilters()); //添加自定义拦截器 unorderedFilterChain.addAll(buildCustomFilterList(element, pc)); //对这些拦截器进行排序 Collections.sort(unorderedFilterChain, new OrderComparator()); checkFilterChainOrder(unorderedFilterChain, pc, pc.extractSource(element)); // The list of filter beans List<BeanMetadataElement> filterChain = new ManagedList<BeanMetadataElement>(); for (OrderDecorator od : unorderedFilterChain) { filterChain.add(od.bean); } //返回封装后的过滤器链 return createSecurityFilterChainBean(element, pc, filterChain); }