Spring Boot集成Swagger遇403错误求助
Spring Boot集成Swagger遇403错误排查与解决
问题描述
基于Spring Boot开发的API集成Swagger后,访问/swagger-ui/、/swagger-ui.html均返回403错误,但/v3/api-docs可正常获取JSON文档。已在SecurityConfig中配置Swagger相关路径permitAll(),但问题未解决,配置代码如下:
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private JwtAuthenticationFilter jwtAuthenticationFilter; @Autowired private MyUserDetailsService myUserDetailsService; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{ httpSecurity .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> authorize .requestMatchers("/employees/**").hasRole("EMPLOYEE") .requestMatchers("/movies/**").hasRole("EMPLOYEE") .requestMatchers("/clients/**").hasRole("CLIENT") .requestMatchers("/rents/**").hasRole("CLIENT") .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/auth/**").permitAll() // Allow Swagger .requestMatchers("/actuator/**").permitAll() .requestMatchers("/actuator/mappings/**").permitAll() //.anyRequest().authenticated() .requestMatchers("/v3/**", "/swagger-ui/**").permitAll() .anyRequest().authenticated() ) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return httpSecurity.build(); } @Bean public AuthenticationProvider authenticationProvider(){ DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setUserDetailsService(myUserDetailsService); daoAuthenticationProvider.setPasswordEncoder(passwordEncoder()); return daoAuthenticationProvider; } @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); } }
排查与修复方案
1. 优化SecurityConfig的请求匹配顺序与规则
Spring Security的请求匹配是从上到下按顺序生效,重复的配置会导致逻辑混乱。调整配置,将开放路径放在角色限制路径之前,并精简重复规则:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception{ httpSecurity .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorize -> authorize // 优先开放Swagger、认证、监控相关路径 .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/auth/**").permitAll() .requestMatchers("/actuator/**").permitAll() // 配置角色专属路径 .requestMatchers("/employees/**", "/movies/**").hasRole("EMPLOYEE") .requestMatchers("/clients/**", "/rents/**").hasRole("CLIENT") // 剩余所有请求需认证 .anyRequest().authenticated() ) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return httpSecurity.build(); }
2. 检查JWT过滤器是否拦截了Swagger路径
你添加的JwtAuthenticationFilter会在Spring Security的认证过滤器之前执行,如果过滤器内没有排除Swagger相关路径,即使SecurityConfig配置了permitAll(),过滤器仍会校验Token导致403。需在过滤器中添加路径排除逻辑:
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestUri = request.getRequestURI(); // 排除Swagger、认证、监控路径,直接放行 if (requestUri.startsWith("/v3/api-docs/") || requestUri.equals("/swagger-ui.html") || requestUri.startsWith("/swagger-ui/") || requestUri.startsWith("/auth/") || requestUri.startsWith("/actuator/")) { filterChain.doFilter(request, response); return; } // 原有JWT校验逻辑 String authHeader = request.getHeader("Authorization"); String token = null; String username = null; if (authHeader != null && authHeader.startsWith("Bearer ")) { token = authHeader.substring(7); username = jwtUtil.extractUsername(token); } // ... 剩余JWT验证代码 }
3. 确认Swagger依赖适配Spring Boot版本
如果使用Spring Boot 3.x,需确保依赖为springdoc-openapi-starter-webmvc-ui(而非旧版的springfox):
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.2.0</version> </dependency>
4. 排查其他拦截器/过滤器
检查项目中是否存在自定义全局拦截器,若有需确保排除Swagger相关路径,避免拦截UI页面的静态资源请求。
内容的提问来源于stack exchange,提问作者MAximy
相关产品推荐
相关产品推荐

