如何基于 URL 模式应用 Spring Boot 过滤器?

Posted

技术标签:

【中文标题】如何基于 URL 模式应用 Spring Boot 过滤器?【英文标题】:How to apply spring boot filter based on URL pattern? 【发布时间】:2017-02-04 06:01:30 【问题描述】:

我创建了一个 Spring Boot 过滤器 - 使用 @Component 注释实现 GenericFilterBean

@Component 
public class MyAuthenticationFilter  extends GenericFilterBean 
...
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException 
...


过滤器由 Spring Boot Framework 自动识别,适用于所有 REST API。我希望此过滤器仅适用于某个 URL 路径,例如 /api/secure/*,但我找不到正确的方法。 我试过@WebFilter,但没用。 我没有使用 XML 配置或 servlet 初始化程序 - 只是注释。

什么是让它工作的正确方法?

【问题讨论】:

【参考方案1】:

@user1283002 我认为可以使用@WebFilter。我只是偶然发现了这个article。根据文章(我自己没试过):

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter
    // ..........


// and let Spring know to scan to find such @WebFilter annotation in your config
// class by using the @ServletComponentScan annotation like

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer 

    public static void main(String[] args) throws Exception 
        SpringApplication.run(MyApplication.class, args);
    

   // ..........


编辑: 在进一步阅读 @ServletComponentScan 的文档后,我发现了一个有趣的免责声明

仅在使用嵌入式网络服务器时执行扫描

这意味着在 Web 容器(例如:Apache Tomcat)中部署我们的应用程序时,Spring 框架不会扫描此类,因此不会应用其上的任何 spring 配置(如果有)。

如果没有要进行的 Spring 配置,你可以不用做任何进一步的更改,如果不是,只需将 @Component 扫描添加到过滤器并确保它的包位于你的 @ComponentScan 注释。

【讨论】:

【参考方案2】:

如果您能够扩展OncePerRequestFilter,还有另一种选择。例如:

public class SomeFilter extends OncePerRequestFilter 

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException 
        // your filter logic ....
    

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) 
        String path = request.getServletPath();
        return !path.startsWith("/api/secure/");
    

【讨论】:

这正是我想要的。泰【参考方案3】:

您可以像这样添加过滤器:

@Bean
public FilterRegistrationBean someFilterRegistration() 

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
 

@Bean(name = "someFilter")
public Filter someFilter() 
    return new SomeFilter();

【讨论】:

我仍然很奇怪为什么它不能通过像@WebFilter 这样的注释来解决,但这对我来说非常有效。谢谢! 可以通过注解来实现吗?

以上是关于如何基于 URL 模式应用 Spring Boot 过滤器?的主要内容,如果未能解决你的问题,请参考以下文章

在aws上忽略基于url到spring boot 2应用程序的黑客攻击是不是安全?

如何构建spring boot

如何从 URL、Spring Boot 和 AngularJs 应用程序中删除 #?

如何将重写规则添加到 Spring Boot 2.3.1

250.Spring Boot+Spring Security:基于URL动态权限:自定义AccssDesionManager

SpringBoot - Spring Boot 应用剖析