在Spring Gateway中仅对特定路由进行JWT认证校验
实现Spring Cloud Gateway路由级别的JWT认证控制
要实现路由独立配置认证要求,而非全局强制JWT校验,可以通过以下步骤完成,让路由配置和认证规则集中在一起:
1. 调整全局Security配置,取消强制认证
修改SecurityConfig,让全局默认放行所有请求,仅在需要的路由上通过过滤器触发认证:
@Configuration public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http .authorizeExchange(exchanges -> exchanges .anyExchange().permitAll() // 默认放行所有请求 ) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt .jwkSetUri("${CIAM_B2C_JWK_SET_URI}") .issuerUri("${CIAM_B2C_ISSUER_URI}") .jwtAuthenticationConverter(jwtAuthenticationConverter()) ) ); return http.build(); } // 配置JWT校验规则(包含issuer、audience验证) @Bean public JwtAuthenticationConverter jwtAuthenticationConverter() { JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); // 添加issuer和audience校验 JwtValidator validator = JwtValidators.createDefaultWithIssuer("${CIAM_B2C_ISSUER_URI}"); validator = validator.and(JwtValidators.createDefaultWithAudience("${CIAM_B2C_AUDIENCES}")); converter.setJwtValidator(validator); return converter; } }
2. 自定义路由认证过滤器
创建Gateway过滤器工厂,用于在指定路由上启用JWT校验:
@Component public class AuthenticationFilterGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthenticationFilterGatewayFilterFactory.Config> { private final ReactiveAuthenticationManager authenticationManager; public AuthenticationFilterGatewayFilterFactory(ReactiveAuthenticationManager authenticationManager) { super(Config.class); this.authenticationManager = authenticationManager; } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { // 提取Bearer令牌 String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION); if (authHeader == null || !authHeader.startsWith("Bearer ")) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } String token = authHeader.substring(7); JwtAuthenticationToken authToken = new JwtAuthenticationToken(Jwt.withTokenValue(token).build()); // 执行认证校验 return authenticationManager.authenticate(authToken) .flatMap(authentication -> chain.filter( exchange.mutate().principal(authentication).build() )) .onErrorResume(e -> { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); }); }; } // 过滤器配置类(可扩展添加权限校验等参数) public static class Config {} }
3. 路由配置中指定认证规则
在application.yaml里,仅给需要认证的路由添加自定义的AuthenticationFilter,公共路由不添加即可:
spring: cloud: gateway: routes: # 需要认证的服务1 - id: secure-service-one uri: http://localhost:8080 predicates: - Path=/api/secure-service-one/** filters: - StripPrefix=3 - AuthenticationFilter # 需要认证的服务2 - id: secure-service-two uri: http://localhost:8082 predicates: - Path=/api/secure-service-two/** filters: - StripPrefix=3 - AuthenticationFilter # 公共服务:无认证过滤器,直接放行 - id: public-service uri: http://localhost:8081 predicates: - Path=/api/public-service/** filters: - StripPrefix=3
说明
- 全局Security配置改为默认放行,避免了全局强制认证的问题;
- 自定义过滤器复用了Spring OAuth2资源服务器的认证逻辑,保证JWT校验的一致性;
- 路由配置和认证规则完全绑定,符合你希望的"集中配置"需求。
内容的提问来源于stack exchange,提问作者kism3t
相关产品推荐
相关产品推荐

