Spring Security 6整合Swagger UI 3.0配置遇401错误求助
问题描述
把应用从Spring 2.7升级到Spring 3.1.2,需要配置Swagger UI 3.0和Spring Security 6。已经尝试用新的requestMatchers写法,但访问Swagger页面时一直报HTTP 401错误。以下是我的WebConfig代码片段:
package com.grammercetamol.securities.configurations; import com.grammercetamol.implementation.UserDetailsServicesImpl; import com.grammercetamol.securities.jwt.AuthFilter; import com.grammercetamol.securities.jwt.JwtEntryPoint; import com.grammercetamol.securities.passwordEncoder.PasswordEncrypt; import lombok.AllArgsConstructor; 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.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import static org.springframework.security.config.http.SessionCreationPolicy.NEVER; @Configuration @EnableWebSecurity(debug = true) @EnableMethodSecurity @AllArgsConstructor public class WebConfig { private static final String[] AUTH_WHITELIST = { "/api/v1/auth/**", "/v3/api-docs/**", "/v3/api-docs.yaml", "/swagger-ui/**", "/swagger-ui.html" }; @Autowired private UserDetailsServicesImpl userDetailsServices; @Autowired private PasswordEncrypt passwordEncrypt; @Autowired private JwtEntryPoint entryPoint; @Autowired @Bean public AuthFilter filter() { return new AuthFilter(); } public DaoAuthenticationProvider daoAuthenticationProvider() { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsServices); authenticationProvider.setPasswordEncoder(passwordEncrypt.bCryptPasswordEncoder()); return authenticationProvider; } @Bean public AuthenticationManager authenticationManager( AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable); http .exceptionHandling(auth -> auth.authenticationEntryPoint(entryPoint)); http .sessionManagement(auth -> auth.sessionCreationPolicy(NEVER)); http .authorizeHttpRequests((requests) -> requests .requestMatchers("/api/auth/**").permitAll() .requestMatchers("/api/secured/**").permitAll() .requestMatchers("/api/cloudinary/**").permitAll() .requestMatchers("/api/v1/auth/**").permitAll() .requestMatchers(AUTH_WHITELIST).permitAll() .anyRequest().authenticated() ); http .authenticationProvider(daoAuthenticationProvider()); http .addFilterBefore( filter(), UsernamePasswordAuthenticationFilter.class ); return http.build(); } }
解决方案
401问题的核心是Swagger相关路径没被正确放行,或者自定义JWT过滤器拦截了这些请求。结合你的代码,给出以下修正方案:
1. 简化并修正配置
把所有需要放行的路径统一管理,避免重复配置导致遗漏,同时优化注入方式:
@Configuration @EnableWebSecurity(debug = true) @EnableMethodSecurity @AllArgsConstructor public class WebConfig { // 把所有公开路径(含Swagger)统一放到白名单 private static final String[] AUTH_WHITELIST = { // 认证接口 "/api/auth/**", "/api/v1/auth/**", // 业务公开接口 "/api/secured/**", "/api/cloudinary/**", // Swagger全量路径 "/v3/api-docs/**", "/v3/api-docs.yaml", "/swagger-ui/**", "/swagger-ui.html" }; // 用@AllArgsConstructor实现构造注入,去掉@Autowired字段 private final UserDetailsServicesImpl userDetailsServices; private final PasswordEncrypt passwordEncrypt; private final JwtEntryPoint entryPoint; private final AuthFilter authFilter; @Bean public DaoAuthenticationProvider daoAuthenticationProvider() { DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); authenticationProvider.setUserDetailsService(userDetailsServices); authenticationProvider.setPasswordEncoder(passwordEncrypt.bCryptPasswordEncoder()); return authenticationProvider; } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable) .exceptionHandling(auth -> auth.authenticationEntryPoint(entryPoint)) .sessionManagement(auth -> auth.sessionCreationPolicy(SessionCreationPolicy.NEVER)) // 关键:直接用统一白名单放行所有公开路径 .authorizeHttpRequests(requests -> requests .requestMatchers(AUTH_WHITELIST).permitAll() .anyRequest().authenticated() ) .authenticationProvider(daoAuthenticationProvider()) .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }
2. 检查自定义JWT过滤器
你的AuthFilter可能没跳过白名单路径,导致Swagger请求被拦截。给过滤器加个跳过逻辑:
public class AuthFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String requestPath = request.getRequestURI(); AntPathMatcher pathMatcher = new AntPathMatcher(); // 遍历白名单,匹配到就直接放行 for (String whitePath : WebConfig.AUTH_WHITELIST) { if (pathMatcher.match(whitePath, requestPath)) { filterChain.doFilter(request, response); return; } } // 下面是原有JWT校验逻辑 // ... } }
3. 调试确认
开启了debug=true,启动后看控制台的路径匹配日志,确认Swagger的请求路径是否被归类到permitAll规则里。如果还有问题,打开浏览器开发者工具,看具体报401的请求路径,检查是否在白名单中。
内容的提问来源于stack exchange,提问作者Badmus Sodiq
相关产品推荐
相关产品推荐

