Spring Gateway中AuthenticationFilter的apply方法未被调用求助
问题:Gateway的AuthenticationFilter apply方法未被调用
请求能命中/api/gateway/v1/user-info路由,但AuthenticationFilter中的apply方法完全未执行,日志与System.out语句均无输出。
AuthenticationFilter 代码
@Component("Authenticate") @Slf4j public class AuthenticationFilter extends AbstractGatewayFilterFactory<AuthenticationFilter.Config>{ private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class); @Autowired private RouteValidator routeValidator; @Autowired private JwtUtil jwtUtil; private final Auth_Manager_Service authManagerFeignClient; public AuthenticationFilter(@Lazy Auth_Manager_Service authManagerFeignClient) { super(Config.class); this.authManagerFeignClient = authManagerFeignClient; } @PostConstruct public void init() { logger.info("!!!!!!!!!!!!!!!!!!!!AuthenticationFilter initialized and registered!!!!!!!!!!!!!!!!!!!!"); } public static class Config {} @Override public GatewayFilter apply(Config config) { return ((exchange, chain)->{ logger.debug("\nEnter Authentication Filter"); ServerHttpRequest httpRequest = null; logger.debug("\n--- Authentication Filter Debug Information ---"); logger.debug("Request URL: {}", exchange.getRequest().getURI()); logger.debug("Request Headers: {}", exchange.getRequest().getHeaders()); logger.info("Processing request: {} {}", exchange.getRequest().getMethod(),exchange.getRequest().getURI().getPath()); logger.debug("\n{}",routeValidator.isSecured.test(exchange.getRequest())); if (routeValidator.isSecured.test(exchange.getRequest())) { //header contains token or not if (!exchange.getRequest().getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) { logger.error("Missing or invalid authorization header"); throw new RuntimeException("Missing authorization header"); } String authHeader = exchange.getRequest().getHeaders().get(HttpHeaders.AUTHORIZATION).get(0); //it's a token System.out.println("Token: "+authHeader); logger.error("Token: {}",authHeader); if (authHeader != null && authHeader.startsWith("Bearer ")) { authHeader = authHeader.substring(7); } try { System.out.println("Checking if it even reach here?"); jwtUtil.validateToken(authHeader); logger.debug("Auth Header: {}", authHeader); System.out.println("authHeader: "+authHeader); String username = jwtUtil.extractUsername(authHeader); System.out.println("username: "+username); List<String> roles = authManagerFeignClient.getRolesByUsername(username); System.out.println("roles: "+roles); String rolesAsString = String.join(",", roles); System.out.println("roles: "+rolesAsString); logger.debug("Authenticated User: {}", username); logger.debug("User Roles: {}", rolesAsString); httpRequest = exchange.getRequest().mutate() .header("loggedInUser", jwtUtil.extractUsername(authHeader)) .header("loggedInUserRoles", rolesAsString) // Only for now as we are taking roles as single value and not as list .build(); logger.debug("Header Info: {}", httpRequest); } catch (ExpiredJwtException e) { logger.error("JWT token has expired", e); throw new RuntimeException("JWT token has expired", e); } catch (MalformedJwtException e) { logger.error("JWT token is malformed", e); throw new RuntimeException("JWT token is malformed", e); } catch (SignatureException e) { logger.error("JWT signature is invalid", e); throw new RuntimeException("JWT signature is invalid", e); } catch (Exception e) { logger.error("Invalid access: Unauthorized access to application", e); System.out.println("Invalid access...!"); throw new RuntimeException("!!Unauthorized access to application!!"); } } logger.debug("---------------------------\n"); return chain.filter(exchange.mutate().request(httpRequest).build()); }); } }
GatewayConfig 代码
@Configuration public class GatewayConfig { @Bean public WebClient.Builder webClientBuilder() { return WebClient.builder(); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder, AuthenticationFilter authFilter) { return builder.routes() .route("Gateway", r -> r .path("/api/gateway/v1/user-info") // The specific path to route .filters(f -> f.filter(authFilter.apply(new AuthenticationFilter.Config()))) .uri("http://localhost:8084")) .build(); } }
RouteValidator 代码
@Component public class RouteValidator { private static final Logger logger = LoggerFactory.getLogger(RouteValidator.class); public static final List<String> openApiEndpoints = List.of( "/api/auth/v1/register", "/api/auth/v1/token", "/eureka", "/api-docs" ); public Predicate<ServerHttpRequest> isSecured = request -> { String currentPath = request.getURI().getPath(); logger.info("Checking security for path: {}", currentPath); boolean isOpen = openApiEndpoints.stream() .anyMatch(uri -> currentPath.contains(uri)); logger.info("Path {} is {}secured", currentPath, isOpen ? "not " : ""); return !isOpen; }; }
AuthConfig 代码
package com.auth_am.AM.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.authentication.AuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.auth_am.AM.service.CustomUserDetailsService; @Configuration @EnableWebSecurity public class AuthConfig { private static final Logger logger = LoggerFactory.getLogger(AuthConfig.class); @Autowired private JWTAuthenticationFilter jwtAuthenticationFilter; @Bean UserDetailsService userDetailsService(){ logger.info("UserDetailsService bean created"); return new CustomUserDetailsService(); } @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http.csrf(csrf -> csrf.disable()) // Disable CSRF .authorizeHttpRequests(authorize -> authorize .requestMatchers("/api/auth/v1/register", "/api/auth/v1/token", "/api/auth/v1/validate").permitAll() // Public endpoint .anyRequest().authenticated() // Other requests require authentication ) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) .build(); } @Bean PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationProvider authenticationProvider(){ DaoAuthenticationProvider authenticationProvider=new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsService()); authenticationProvider.setPasswordEncoder(passwordEncoder()); return authenticationProvider; } @Bean AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); } }
排查方向
- 确认Filter实例是否加载:检查启动日志是否有
AuthenticationFilter initialized and registered输出,确认Spring容器已正确加载该Bean。 - 修正Filter注册方式:
AbstractGatewayFilterFactory的正确注册方式是用gatewayFilter()而非filter(),修改GatewayConfig中的路由配置:.filters(f -> f.gatewayFilter(authFilter.apply(new AuthenticationFilter.Config()))) - 检查路由匹配精度:确认请求路径与配置的
/api/gateway/v1/user-info完全一致,避免多余斜杠、大小写差异,同时排查是否有其他优先级更高的路由规则拦截了请求。 - 调整日志级别:当前apply方法内使用
logger.debug,若日志级别高于DEBUG则不会输出,可临时改为logger.info或调整日志配置为DEBUG级别。 - 排查全局Filter干扰:检查网关是否存在全局Filter在自定义Filter之前拦截了请求,导致apply方法未触发。
内容的提问来源于stack exchange,提问作者A_B
相关产品推荐
相关产品推荐

