解决Spring Security自定义filter重复执行问题
今天做项目的时候,发现每次拦截器日志都会打两遍,很纳闷,怀疑是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重复执行问题的更多相关文章
- Spring+quartz集群解决多服务器部署定时器重复执行的问题
一.问题描述 Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了.不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行. 二.解决方案 Spr ...
- Spring Security 自定义登录认证(二)
一.前言 本篇文章将讲述Spring Security自定义登录认证校验用户名.密码,自定义密码加密方式,以及在前后端分离的情况下认证失败或成功处理返回json格式数据 温馨小提示:Spring Se ...
- spring security自定义指南
序 本文主要研究一下几种自定义spring security的方式 主要方式 自定义UserDetailsService 自定义passwordEncoder 自定义filter 自定义Authent ...
- (二)spring Security 自定义登录页面与校验用户
文章目录 配置 security 配置下 MVC 自定义登录页面 自定义一个登陆成功欢迎页面 效果图 小结: 使用 Spring Boot 的快速创建项目功能,勾选上本篇博客需要的功能:web,sec ...
- Spring的quartz定时器重复执行二次的问题解决
Spring的quartz定时器同一时刻重复执行二次的问题解决 最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的ha ...
- Spring Security 案例实现和执行流程剖析
Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...
- spring security 4 filter 顺序及作用
Spring Security 有两个作用:认证和授权 一.Srping security 4 filter 别名及顺序 spring security 4 标准filter别名和顺序,因为经常要用就 ...
- Spring Security 自定义 登陆 权限验证
转载于:https://www.jianshu.com/p/6b8fb59b614b 项目简介 基于Spring Cloud 的项目,Spring Cloud是在Spring Boot上搭建的所以按照 ...
- 02 spring security 自定义用户认证流程
1. 自定义登录页面 (1)首先在static目录下面创建login.html 注意: springboot项目默认可以访问resources/resources, resources/s ...
随机推荐
- 设计模式-03工厂方法模式(Factory Method Pattern)
插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...
- java反射机制梳理
java反射机制梳理 Java反射简介 反射简介 编译和运行 编译时刻加载类是静态加载类.运行时刻加载类是动态加载类 要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载.Java类如 ...
- 【WPF学习】第三十八章 行为
样式提供了重用一组属性设置的实用方法.它们为帮助构建一致的.组织良好的界面迈出了重要的第一步——但是它们也是有许多限制. 问题是在典型的应用程序中,属性设置仅是用户界面基础结构的一小部分.甚至最基本的 ...
- TortoiseSVN使用教程[多图超详细]
安装及下载client 端 下载Windows 端程序:http://tortoisesvn.net/downloads.一般而言,如果是32-bit的Windows XP 应该使用TortoiseS ...
- Codeforces_818
A.winners总数为(k+1)diplomas. #include<bits/stdc++.h> using namespace std; long long n,k; int mai ...
- Codeforces_729_E
http://codeforces.com/problemset/problem/729/E 存在的数必须连续,若不连续,从最后选人来补,注意根不是0和其他点是0的情况. #include<io ...
- WeChall_Training: Crypto - Caesar I (Crypto, Training)
As on most challenge sites, there are some beginner cryptos, and often you get started with the good ...
- 关于将笔记本电脑作为wifi热点的详细步骤
常规做法直接度娘.如果出现无法打开wifi功能,可找对应解决方法. 1.先检查网卡是否支持承载网络,检查方法为在cmd中使用管理员权限运行,输入netsh wlan show drivers.查看支持 ...
- c语言小游戏-三子棋的完成
三子棋的实现 一.实现思路 1.初始化数组 三子棋是九宫格的格式,所以用二维数组接收数据.用‘O’代表电脑下的子,‘X’代表玩家下的子.未下子的时候初始化 ’ ‘(space).则二维数组为“char ...
- CentOS使用465端口发送邮件
1)邮件发送示例 方法1:echo "This is a test mail" | mail -s '邮件测试' 452666750@qq.com 方法2:mail -s '服务运 ...