Spring Security:指定路径禁用JWT改用账号密码认证
解决方案:实现特定路径的HTTP Basic认证,避免JWT过滤器触发
你的需求完全可以实现!问题出在当前的两个Security配置没有明确划分处理范围,导致JWT过滤器依然会介入/api/data/**路径的请求。下面是调整后的完整方案:
1. 优化HTTP Basic认证配置(高优先级)
首先,给处理/api/data/**的配置加上securityMatcher,明确它只负责该路径的请求,同时确保它的优先级高于JWT配置:
@Configuration @Order(1) // 优先级更高,先匹配请求 public class BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin") .password("{noop}abc") // 注意:Spring Security 5+需要密码编码器,{noop}表示不加密(仅测试用) .roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { // 只对/api/data/**路径生效 http.securityMatcher("/api/data/**") .authorizeRequests() .anyRequest().hasRole("ADMIN") .and() .httpBasic() // 启用HTTP Basic认证 .and() .csrf().disable(); } }
2. 调整JWT认证配置(低优先级)
在JWT的配置里,把/api/data/**路径排除在外,让它不处理该路径的请求,同时指定低于Basic配置的优先级:
@Configuration @Order(2) // 优先级低于Basic配置 public class JwtSecurityConfig extends WebSecurityConfigurerAdapter { // 假设你已实现以下两个方法 private JwtAuthenticationFilter jwtAuthenticationFilter() { return new JwtAuthenticationFilter(); } private AuthenticationEntryPoint restAuthenticationEntryPoint() { return new RestAuthenticationEntryPoint(); } @Override protected void configure(HttpSecurity http) throws Exception { http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .exceptionHandling() .authenticationEntryPoint(restAuthenticationEntryPoint()) .and() .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() .antMatchers("/login/**", "/register/**").permitAll() .antMatchers("/api/data/**").permitAll() // 排除该路径,交给Basic配置处理 .antMatchers("/api/jwt/**").authenticated() .anyRequest().authenticated() .and() .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .csrf().disable(); } }
关键原理说明
securityMatcher的作用:让Basic认证配置只拦截/api/data/**的请求,不会干扰其他路径的JWT认证逻辑。- @Order优先级:Spring Security会按Order值从小到大的顺序匹配请求,高优先级的Basic配置先处理
/api/data/**,处理完成后JWT配置就不会再介入该路径了。 - 密码编码器注意:示例中用
{noop}是为了快速测试,生产环境一定要用正式的密码编码器(比如BCryptPasswordEncoder)来加密存储密码。
这样调整后,请求/api/data/**时只会触发HTTP Basic认证,JWT过滤器不会再被调用;其他路径则继续使用JWT认证,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Bart B
相关产品推荐
相关产品推荐

