今天做项目的时候,发现每次拦截器日志都会打两遍,很纳闷,怀疑是Filter被执行了两遍。结果debug之后发现还真是!记录一下这个神奇的BUG!

问题描述

项目中使用的是Spring-security作为权限框架,然后做了一个JwtAuthenticationTokenFilter作为拦截器拦截请求,校验Token,但是每次请求都会打两遍日志。下面是精简的源代码:

自定义的Filter类

@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain) throws ServletException, IOException {
//...省略
//打出两遍日志的地方
log.info("User:{} request path:{}, method:{}, param:{}", username, request.getServletPath(),
request.getMethod(), request.getParameterMap() == null ? null : OBJECT_MAPPER.writeValueAsString(request.getParameterMap()));
//...省略
chain.doFilter(request, response);
}
}

WebSecurityConfig配置类

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//...省略
@Bean
public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationTokenFilter();
} @Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//...省略
//把JwtAuthenticationTokenFilter加入到RememberMeAuthenticationFilter之前
httpSecurity.addFilterBefore(authenticationTokenFilterBean(), RememberMeAuthenticationFilter.class);
}
//...省略
}

请求日志如下:

问题解决

把自定义FilterJwtAuthenticationTokenFilter@Component取消掉就可以了,不让它被Spring容器管理。

原因

在spring容器托管的OncePerRequestFilter的bean,都会自动加入到servlet的filter chain,而上面的定义,还额外把filter加入到了spring security的

ememberMeAuthenticationFilter之前。而spring security也是一系列的filter,在mvc的filter之前执行。因此在鉴权通过的情况下,就会先后各执行一次。

参考资料

解决spring security自定义filter重复执行问题

解决Spring Security自定义filter重复执行问题的更多相关文章

  1. Spring+quartz集群解决多服务器部署定时器重复执行的问题

    一.问题描述 Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了.不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行. 二.解决方案 Spr ...

  2. Spring Security 自定义登录认证(二)

    一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Se ...

  3. spring security自定义指南

    序 本文主要研究一下几种自定义spring security的方式 主要方式 自定义UserDetailsService 自定义passwordEncoder 自定义filter 自定义Authent ...

  4. (二)spring Security 自定义登录页面与校验用户

    文章目录 配置 security 配置下 MVC 自定义登录页面 自定义一个登陆成功欢迎页面 效果图 小结: 使用 Spring Boot 的快速创建项目功能,勾选上本篇博客需要的功能:web,sec ...

  5. Spring的quartz定时器重复执行二次的问题解决

    Spring的quartz定时器同一时刻重复执行二次的问题解决 最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的ha ...

  6. Spring Security 案例实现和执行流程剖析

    Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...

  7. spring security 4 filter 顺序及作用

    Spring Security 有两个作用:认证和授权 一.Srping security 4 filter 别名及顺序 spring security 4 标准filter别名和顺序,因为经常要用就 ...

  8. Spring Security 自定义 登陆 权限验证

    转载于:https://www.jianshu.com/p/6b8fb59b614b 项目简介 基于Spring Cloud 的项目,Spring Cloud是在Spring Boot上搭建的所以按照 ...

  9. 02 spring security 自定义用户认证流程

    1. 自定义登录页面 (1)首先在static目录下面创建login.html       注意: springboot项目默认可以访问resources/resources, resources/s ...

随机推荐

  1. C# 定时器导致的内存泄露问题

    C# 中有三种定时器,System.Windows.Forms 中的定时器和 System.Timers.Timer 的工作方式是完全一样的,所以,这里我们仅讨论 System.Timers.Time ...

  2. 【Nginx入门系列】第四章 通过域名匹配虚拟主机,不修改端口

    域名访问原理 我们在显示生活中,我们怎样通过一个域名来访问到我们所需要的网站呢? 例如www.baidu.com,我们在浏览器输入百度网址会先发送请求到DNS服务器,DNS会通过我们的域名解析百度对应 ...

  3. mac如何用quick look预览多个文件或者图片

    1.先选中要查看的多个文件,然后点击 空格键 2.按住 command+return 就可以同时预览多个文件了 如果想全屏预览,则在1中,按住 option+空格键 ,然后再进行2 ,就实现全屏预览了 ...

  4. 开源虚拟机Bochs安装以及踩坑

    因为想要写一个简单的操作系统,所以需要安装虚拟机来模拟出硬件,VMware不适合这个场景,因为会使用硬件级别的虚拟化,而bochs这个开源虚拟机,是用软件虚拟了所有的硬件,所以调试可以做到非常细的粒度 ...

  5. PT教程 - 应用系列 - ECO修复Timing(理论+实践+脚本分享)

    ​本文转自:自己的微信公众号<集成电路设计及EDA教程> <PT教程 - 应用系列 - ECO修复Timing(理论+实践+脚本分享)> 这篇推文讲一下数字IC设计中的post ...

  6. Http POST 提交 415错误 Unsupported Media Type 解决方案

    1 问题 在调用webapi post 提交时出现 415 Unsupported Media Type 错误 前端代码如下: $.post("/api/student/poststuden ...

  7. Cheat sheet PySpark SQL Python(PySpark 速查表)

  8. VMware Workstation 14 Pro 安装 CentOS 7 Linux 虚拟机

    CentOS 7 下载地址:http://isoredirect.centos.org/centos/7/isos/x86_64/ ,选择 CentOS-7-x86_64-DVD-1908.iso : ...

  9. Qt 中 this->size() this->rect() event->size() 三者差异

    测试代码: void OsgEarthGraphicsView::resizeEvent(QResizeEvent* event) { //if (scene()) //{ // scene()-&g ...

  10. os.path.join() - 忽略绝对路径前的参数

    os.path.join()会忽略第一个绝对路径之前的参数! 示例: >>> import os >>> os.path.join('/home', 'mushro ...