Spring Boot配置Swagger/OpenAPI权限时遇403 Forbidden问题求助
问题:Swagger UI配置Basic Auth后,仅保护Swagger相关API而开放其他API的正确配置方式
已查阅诸多相关问题,但未找到可行解决方案。我的服务需要运行OpenAPI和Swagger UI,无安全配置时运行正常;添加Basic Auth认证后,Swagger相关功能可正常使用,但所有其他API也被纳入该认证保护范围,这并非我想要的效果。
于是我尝试添加额外的requestMatcher,配置如下:
@Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeHttpRequests() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/v3/api-docs", "/swagger-ui.html") .hasRole("USER") .requestMatchers("/**").permitAll() .and() .httpBasic(Customizer.withDefaults()); return httpSecurity.build(); }
配置后,其他API可正常无需认证访问,Swagger UI也能弹出登录窗口,登录成功后,访问/v3/api-config却出现403 Forbidden或400错误,具体错误取决于permitAll requestMatcher的位置。
我希望实现的效果是:Swagger相关API需Basic Auth认证,其他所有API允许任何人访问。请问正确的配置方式是什么?
以下是我当前的安全配置,该配置会拦截所有请求,认证后仅允许访问Swagger相关内容:
@Configuration @EnableWebSecurity public class SecurityConfig { public static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeHttpRequests() .requestMatchers("/swagger-ui/**", "/v3/api-docs/**", "/v3/api-docs", "/swagger-ui.html") .hasRole("USER") .and() .httpBasic(Customizer.withDefaults()); return httpSecurity.build(); } @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails user = User.withUsername("user") .password(passwordEncoder.encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
解决方案
你的配置存在两个核心问题:一是遗漏了Swagger UI依赖的/v3/api-config路径,二是请求匹配的顺序和写法不符合Spring Security的规则。以下是修正后的完整配置:
@Configuration @EnableWebSecurity public class SecurityConfig { public static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class); @Bean public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception { httpSecurity .csrf(csrf -> csrf.disable()) // Swagger UI无需CSRF保护,禁用避免拦截 .authorizeHttpRequests(auth -> auth // 配置所有Swagger相关路径需要USER角色认证 .requestMatchers( "/swagger-ui/**", "/v3/api-docs/**", "/v3/api-docs", "/swagger-ui.html", "/v3/api-config" // 新增Swagger UI依赖的配置路径 ).hasRole("USER") // 所有未匹配的请求允许匿名访问 .anyRequest().permitAll() ) .httpBasic(Customizer.withDefaults()); return httpSecurity.build(); } @Bean public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) { UserDetails user = User.withUsername("user") .password(passwordEncoder.encode("password")) .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
关键调整说明:
- 新增
/v3/api-config路径:Swagger UI加载时会请求该路径获取OpenAPI配置,之前的配置未包含它,导致认证后访问出现403/400错误 - 用
anyRequest().permitAll()替代requestMatchers("/**"):Spring Security按顺序匹配请求,anyRequest()专门用于匹配所有未被前面规则覆盖的请求,语义更清晰,也能避免路径匹配优先级冲突 - 禁用CSRF:Basic Auth场景下不需要CSRF保护,禁用后可防止Swagger UI的请求被误拦截
配置完成后,Swagger相关路径会强制要求Basic Auth认证,其他所有API则完全开放,无需认证即可访问。
内容的提问来源于stack exchange,提问作者mal
相关产品推荐
相关产品推荐

