protected Filter initDelegate(WebApplicationContext wac) throws ServletException { Filter delegate = wac.getBean(getTargetBeanName(), Filter.class); if (isTargetFilterLifecycle()) { delegate.init(getFilterConfig()); } return delegate; }使用过springSecurity的朋友都知道,首先需要在web.xml进行以下配置,
<filter> <description>登录验证,访问权限控制。</description> <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类就是springSecurity的入口,但其实这个类位于spring-web-3.0.5.RELEASE.jar这个jar下面,说明这个类本身是和springSecurity无关。DelegatingFilterProxy类继承于抽象类GenericFilterBean,间接地implement 了javax.servlet.Filter接口,Servlet容器在启动时,首先会调用Filter的init方法,GenericFilterBean的作用主要是可以把Filter的初始化参数自动地set到继承于GenericFilterBean类的Filter中去。在其init方法的如下代码就是做了这个事:
public final void init(FilterConfig filterConfig) throws ServletException { Assert.notNull(filterConfig, "FilterConfig must not be null"); if (logger.isDebugEnabled()) { logger.debug("Initializing filter '" + filterConfig.getFilterName() + "'"); } this.filterConfig = filterConfig; // Set bean properties from init parameters. try { PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment)); initBeanWrapper(bw); bw.setPropertyValues(pvs, true); } catch (BeansException ex) { String msg = "Failed to set bean properties on filter '" + filterConfig.getFilterName() + "': " + ex.getMessage(); logger.error(msg, ex); throw new NestedServletException(msg, ex); } // 这个方法留给子类来扩展 initFilterBean(); if (logger.isDebugEnabled()) { logger.debug("Filter '" + filterConfig.getFilterName() + "' configured successfully"); } }
DelegatingFilterProxy initFilterBean方法的代码如下:
protected void initFilterBean() throws ServletException { // 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. synchronized (this.delegateMonitor) { WebApplicationContext wac = findWebApplicationContext(); if (wac != null) { this.delegate = initDelegate(wac); } } }可以看出上述代码首先看Filter是否提供了targetBeanName初始化参数,如果没有提供则直接使用filter的name做为beanName,产生了beanName后,由于我们在web.xml的filter的name是springSecurityFilterChain,从spring的IOC容器中取出bean的代码是initDelegate方法,下面是该方法代码
protected Filter initDelegate(WebApplicationContext wac) throws ServletException { Filter delegate = wac.getBean(getTargetBeanName(), Filter.class); if (isTargetFilterLifecycle()) { delegate.init(getFilterConfig()); } return delegate; }
通过跟踪代码,发现取出的bean是org.springframework.security.FilterChainProxy,该类也是继承于GenericFilterBean,取出bean后,判断targetFilterLifecycle属性是false还是true,决定是否调用该类的init方法。这个FilterChainProxy bean实例最终被保存在DelegatingFilterProxy类的delegate属性里
下面看一下DelegatingFilterProxy类的doFilter方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { // Lazily initialize the delegate if necessary. Filter 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(delegateToUse, request, response, filterChain);这句代码,在下面可以看出DelegatingFilterProxy类实际是用其delegate属性即org.springframework.security.FilterChainProxy实例的doFilter方法来响应请求
protected void invokeDelegate( Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { delegate.doFilter(request, response, filterChain); }
以上就是DelegatingFilterProxy类的一些内部运行机制,其实主要作用就是一个代理模式的应用,可以把servlet 容器中的filter同spring容器中的bean关联起来
相关推荐
通过上述分析,我们可以看出`DelegatingFilterProxy`在Spring MVC应用中的重要性,它使得过滤器可以充分利用Spring框架的优势,提高了代码的可维护性和可扩展性。同时,结合提供的代码示例,我们可以更好地理解和...
在深入分析SpringSecurity源码之前,我们先了解一些基础概念。 1. DelegatingFilterProxy:这是一个Spring框架提供的过滤器,它作为代理来调用实际的Filter。在web.xml中,filter-name设置为...
4. **过滤器链(Filter Chain)**:Spring Security通过一系列过滤器处理HTTP请求,如DelegatingFilterProxy、ChannelProcessingFilter、SecurityContextPersistenceFilter等。理解过滤器链的工作原理,能帮助优化...
Spring Security的核心在于Filter Chain,它由多个安全相关的过滤器组成,如DelegatingFilterProxy、ChannelProcessingFilter、SecurityContextHolderAwareRequestFilter等。每个过滤器都有特定职责,如检查HTTP请求...
1. **Filter Chain**: Spring Security的核心在于其过滤器链,它由多个安全过滤器组成,如`DelegatingFilterProxy`、`ChannelProcessingFilter`、`UsernamePasswordAuthenticationFilter`等。这些过滤器按照特定顺序...
尚硅谷_Shiro_DelegatingFilterProxy · 06. 尚硅谷_Shiro_权限 URL 配置细节 · 07. 尚硅谷_Shiro_认证思路分析 · 08.尚硅谷_Shiro_实现认证流程 · 09.尚硅谷_Shiro_实现认证 Realm · 10.尚硅谷_Shiro_密码...
这里定义了一个名为 `shiroFilter` 的过滤器,使用 `DelegatingFilterProxy` 类来代理 Shiro 的 Filter。`filter-mapping` 配置表明所有的请求都将通过 Shiro 过滤器进行处理。 然后,为了实现自定义的权限控制,...
从`DelegatingFilterProxy` 将Filter纳入Spring管理,到`FilterChainProxy` 根据请求路由到合适的`SecurityFilterChain`,整个流程展示了Spring Security如何巧妙地结合Servlet规范和Spring框架的优势,实现高效、可...
- `DelegatingFilterProxy`:将请求委托给Spring Security的`FilterSecurityInterceptor`。 - `SecurityContextPersistenceFilter`:在HTTP请求之间保持`SecurityContext`。 - `ConcurrentSessionFilter`:管理并发...
在Spring Session的配置中,`DelegatingFilterProxy`将通过指定的名字(如`springSessionRepositoryFilter`)去查找Spring容器中对应的Bean,并将其转换为过滤器进行工作。 - **Cookie跨域问题**:在多域名的环境中...
核心组件是`DelegatingFilterProxy`,它是一个Servlet过滤器,用于代理其他Spring Bean(如`SecurityContextPersistenceFilter`和`ConcurrentSessionFilter`)。 2. **鉴权流程**: - **身份验证(Authentication...
Spring Security Filter Chain 包括了如`DelegatingFilterProxy`、`ChannelProcessingFilter`、`SecurityContextHolderAwareRequestFilter`、`AnonymousAuthenticationFilter`、`SessionManagementFilter`、`...
- `DelegatingFilterProxy`: 用于代理Spring Security的Filter对象。 - `SecurityContextPersistenceFilter`: 保存和恢复用户的Security Context(安全上下文)。 - `UsernamePasswordAuthenticationFilter`: ...
6. **源码分析**:对于深入理解Spring Security的工作原理,阅读源码是十分有帮助的。可以研究`AuthenticationManager`、`FilterSecurityInterceptor`、`AbstractAuthenticationProcessingFilter`等关键类的实现。 ...
7. **Spring框架中的Filter**:在Spring MVC中,虽然可以使用传统的Servlet Filter,但Spring也提供了DelegatingFilterProxy,它可以用来代理Spring的Bean,这样过滤器也能享受到Spring的依赖注入。 通过分析和实践...
- **Filter的注册与配置**:理解Spring Security如何通过`DelegatingFilterProxy`将Spring Bean注册为Servlet Filter,并配置过滤链。 - **SecurityContextHolder**:查看如何在应用程序中设置和获取安全上下文,...
通过分析案例中的代码和配置,我们可以学习如何设置基本的安全规则,处理用户认证和授权,以及如何自定义Spring Security的行为以适应我们的应用程序需求。这个案例是深入学习Spring Security和实践安全控制的一个...
在Spring MVC框架中,可以使用Spring的DelegatingFilterProxy来代理Spring的Bean,这样可以利用Spring的依赖注入和AOP特性。 9. **动态过滤** 通过编程方式动态地添加、删除过滤器,可以实现更加灵活的过滤策略。...
1. **DelegatingFilterProxy**:这是一个Spring框架的过滤器,它将请求委托给Spring容器中的Bean,通常是`FilterSecurityInterceptor`。 2. **ChannelProcessingFilter**:处理HTTP和HTTPS之间的切换,确保敏感操作...
例如,`DelegatingFilterProxy`用于代理Spring Security的配置,`UsernamePasswordAuthenticationFilter`处理表单登录请求。 4. **会话管理(Session Management)**:Spring Security可以管理用户的会话,包括会话...