• 【Spring Security】使用 OncePerRequestFilter 过滤器校验登录过期、请求日志等操作



    前言

    OncePerRequestFilter 是一个过滤器,每个请求都会执行一次;一般开发中主要是做检查是否已登录、Token是否过期和授权等操作,而每个操作都是一个过滤器,下面演示一下。


    OncePerRequestFilter 使用

    检查是否登录过期过滤器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 检查是否登录过期
     *
     * @author francis
     * @create: 2023-08-30 16:45
     **/
    @Component
    @Slf4j
    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            log.info("进入 JwtAuthenticationTokenFilter ...");
            /**
             * 从 request 的 header 中拿出来 token
             */
    
            String token = request.getHeader("token");
            if (token == null || token.isEmpty()) {
                // 没有携带 token 则 放行
                filterChain.doFilter(request, response);
                return;
            }
    
            /**
             * 检查 token 是否过期逻辑 .....
             */
            // 放行
            filterChain.doFilter(request, response);
        }
    }
    
    • 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

    检查是否登录过期过滤器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * 请求日志
     *
     * @author francis
     * @create: 2023-08-31 10:15
     **/
    @Component
    @Slf4j
    public class OperationLogFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            log.info("OperationLogFilter ...");
            /**
             * 操作日志记录 ...
             */
            // 放行
            filterChain.doFilter(request, response);
        }
    
    }
    
    • 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

    SecurityConfiguration 配置

    
    import com.security.filter.JwtAuthenticationTokenFilter;
    import com.security.filter.OperationLogFilter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.config.http.SessionCreationPolicy;
    import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
    
    /**
     * Security 配置类
     *
     * @author francis
     * @create: 2023-08-30 14:19
     **/
    @Configuration
    @EnableWebSecurity
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
    
        @Autowired
        private OperationLogFilter operationLogFilter;
    
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    // 关闭csrf
                    .csrf().disable()
                    // 不通过 Session 获取 SecurityContext
                    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                        .authorizeRequests()
                            // 对于登录接口 允许匿名访问
                            .antMatchers("/login")
                                .permitAll()
                            // 除上面外的所有请求全部需要鉴权认证
                            .anyRequest()
                                .authenticated();
    
            // 在 UsernamePasswordAuthenticationFilter(验证用户) 之前执行
            // TODO 需要注意的是下面过滤器的顺序就是执行的顺序,使用 @Order 也没办法改变
            http
            		// 登录是否过期
                    .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
                    // 请求日志
                    .addFilterBefore(operationLogFilter, UsernamePasswordAuthenticationFilter.class);
        }
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }
    
    }
    
    • 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
    • 59
    • 60
    • 61
    • 62




    End


  • 相关阅读:
    【C语言】为什么建议使用枚举而不是#define?
    C++中OpenCV、Armadillo矩阵数据格式的转换方式
    MLOps的演进历程
    docker安装部署及优化详解(二)
    IPKISS Tutorials ------merge elements(合并对象)
    大数据:Storm和流处理简介
    Python控制流简介(条件语句、循环语句、异常处理语句)
    使用Java分析器优化代码性能,解决OOM问题
    Java学习笔记(十九)
    第十章 : 如何使用MockMvc 快速编写Reslful API 测试用例
  • 原文地址:https://blog.csdn.net/weixin_43657300/article/details/132596376