Featured image of post Filter Interceptor

Filter Interceptor

JavaWeb过滤器和拦截器

https://mp.weixin.qq.com/s/8K5yeVQP7A1U1n9zzbxwzA

1.FIlter

Filter:JavaWeb三大组件之一,另外两个是Servlet和Listener

概念:Web中的过滤器,当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些通用的功能(登陆验证、统一编码处理、敏感字符过滤……)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Filter配置信息通常写在web.xml配置文件中

<filter>
    <filter-name>xsscheck</filter-name>//名字
    <filter-class>com.anbai.sec.XssFilter</filter-class>//class
</filter>
<filter-mapping>
    <filter-name>xsscheck</filter-name>//名字
    <!-- 拦截路径  匹配模式-->
    <url-pattern>*.jsp</url-pattern>//路由
</filter-mapping>

1.1.Filter快速入门

img

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package cn.edu.test.Filetr;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

//@WebFilter表示拦截路径
@WebFilter("/*")
public class FilterDemo implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        System.out.println("filter...");
        //一定记得放行,否则无法访问对应资源
        chain.doFilter(request,response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void destroy() {}
}

1.2.Filter执行流程

img

1.3.Filter使用细节

1.3.1.Filter拦截路径配置

1
2
@WebFilter("/index.jsp")   拦截资源路径不是访问路径什么意思可以正常访问但是会经过过滤器拦截处理
比如这个拦截index.jsp当你访问index.jsp时会执行filter代码你访问login.jsp时不会执行filter代码

img

1.3.2.过滤器链

一个Web应用中,可以配置多个过滤器,这多个过滤器称为过滤器链

执行流程:从filter1入,最后从filter1出

img

使用注解配置Filter,优先级按照过滤器类名(字符串)的自然排序

1.4.Jeesns1.4.2-XSS跨站绕过

https://gitee.com/lxinet/jeesns

web.xml配置文件中存在XssSql的过滤器

1
2
3
4
5
6
7
8
9
    <filter>
        <filter-name>XssSqlFilter</filter-name>
        <filter-class>com.lxinet.jeesns.core.filter.XssFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>XssSqlFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

这个过滤器的作用是拦截所有请求,每次请求前都需要XssFilter进行验证,那就查看XssFilter具体的过滤规则

chain.doFilter这个放行方法新建了一个XssWrapper对象

img

可以看到这个cleanXSS方法设置了一个字典,字典中全是一些能够触发XSS常用的标签,也就是黑名单过滤,对于黑名单过滤可以使用XSS字典进行Bypass

img

2.拦截器Interceptor

概念:是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行。

作用:拦截请求,在指定的方法调用前店,根据业务需要执行预先设定的代码。

2.1.拦截器快速入门

定义一个拦截器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package cn.edu.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

//ctrl+o重写需要的方法
@Component
public class loginCheckInterceptor implements HandlerInterceptor {
    @Override
    //目标资源方法运行前运行,返回true,放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle...");
        return true;    //记得返回true,否则什么操作也干不了
    }

    @Override
    //目标资源方法运行后运行,返回true,放行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override
    //视图渲染完毕运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

preHandle在controller方法运行前执行所已进行校验时需要将方法写在preHandle中
postHandle&afterCompletion在controller方法运行后执行

配置定义的拦截器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package cn.edu.config;

import cn.edu.Filter.LoginCheckFilter;
import cn.edu.interceptor.loginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration     //表示当前类是一个配置类
public class Webconfig implements WebMvcConfigurer {

    @Autowired
    private loginCheckInterceptor loginCheckInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");  // /**表示拦截所有资源
    }
}

2.2.拦截器拦截路径配置

1
2
3
4
5
6
7
addPathPatterns拦截哪些资源
    addPathPatterns("/**")拦截所有资源
excludePathPatterns不拦截哪些资源

public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login");  // /**表示拦截所有资源
}

img

2.3.拦截器执行流程

img

如果一个springboot项目既有过滤器也有拦截器,先执行过滤器中放行前的逻辑,在执行拦截器中preHandle中的内容,在执行后面controller中方法,执行完成controller中方法后执行postHandle方法和afterCompletion方法,最后执行过滤器中放行后逻辑

2.4.过滤器和拦截器的区别

接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现Handlerlnterceptor接口。

拦截范围不同:过滤器Filter:会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。

过滤器放行需要执行:filterChain.doFilter(request, response);

而拦截器放行执行要执行:return true

2.5.使用拦截器完成登录校验

逻辑和过滤器一样,不同点在于放行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//ctrl+o重写需要的方法
@Slf4j
@Component
public class loginCheckInterceptor implements HandlerInterceptor {
    @Override
    //目标资源方法运行前运行,返回true,放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取请求url
        String url = request.getRequestURL().toString();
        log.info("获取请求url+{}",url);

        //2.判断url是否存在login关键字,登录操作直接放行
        if (url.contains("login")){
            return true;
        }
        //不是登录操作,其它操作
        //3.获取请求头中令牌token
        String jwt = request.getHeader("token");

        //4.判断令牌是否存在,不存在返回错误结果未登录
        if (!StringUtils.hasLength(jwt)){
            log.info("请求token为空,返回未登录信息");
            Result result = Result.error("login error");
            //手动转换为Json格式,使用Fastjson依赖
            String jsonString = JSONObject.toJSONString(result);
            //响应未登录结果
            response.getWriter().write(jsonString);
            return false;
        }
        //5.校验Jwt令牌,如果校验失败,返回错误结果未登录
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){
            e.printStackTrace();
            log.info("令牌解析失败,返回未登录信息");
            Result result = Result.error("login error");
            String jsonString = JSONObject.toJSONString(result);
            //响应未登录结果
            response.getWriter().write(jsonString);
            return false;
        }
        //6.放行
        log.info("令牌合法,放行");
        return true;
    }

    @Override
    //目标资源方法运行后运行,返回true,放行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }

    @Override
    //视图渲染完毕运行,最后运行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}
By Lsec
最后更新于 Sep 29, 2025 20:57 +0800
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计
¹鵵ҳ