【Spring Security】使用 OncePerRequestFilter 过滤器校验登录过期、请求日志等操作
作者:mmseoamin日期:2023-12-21

文章目录

  • 前言
  • OncePerRequestFilter 使用
      • 检查是否登录过期过滤器
      • 检查是否登录过期过滤器
      • SecurityConfiguration 配置

        前言

        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);
            }
        }
        

        检查是否登录过期过滤器

        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);
            }
        }
        

        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();
            }
        }
        

        End