Spring Boot 2.7.18整合SpringDoc 1.8.0时Swagger UI遇401授权问题
问题解决:Swagger UI 401未授权(启用CustomAuthenticationFilter时)
环境信息
- Java 1.8
- Spring Boot 2.7.18
- springdoc-openapi-ui 1.8.0
核心问题
启用自定义CustomAuthenticationFilter后,访问/api/myservice/swagger-ui/index.html返回401;注释该Bean后页面正常加载。要求不禁用CSRF的前提下,实现Swagger页面无需授权访问。
问题根源
CustomAuthenticationFilter的RequestMatcher匹配所有请求(/**),导致Swagger相关请求被拦截,过滤器逻辑未处理匿名访问场景,返回401。- application.yml中springdoc配置存在YAML语法错误(使用
=而非:),可能导致配置不生效。 - Swagger全局配置了Bearer Auth安全要求,UI默认要求携带Token。
解决方案
1. 修复application.yml的YAML语法错误
将配置中的=替换为YAML标准的:,并修正api-docs路径配置:
springdoc: api-docs: path: /api-docs swagger-ui: enabled: true path: /swagger-ui.html tryItOutEnabled: false filter: false syntaxHighlight: activated: true spring: mvc: pathmatch: matching-strategy: ant_path_matcher server: servlet: context-path: /api/myservice
2. 修改CustomAuthenticationFilter的请求匹配规则,排除Swagger路径
调整requestMatcher() Bean,让过滤器仅处理业务API,不拦截Swagger相关请求:
@Bean public RequestMatcher requestMatcher() { log.debug("Creating request matcher"); // 定义需要排除的Swagger相关路径 List<RequestMatcher> excludeMatchers = Arrays.asList( new AntPathRequestMatcher("/swagger-ui/**"), new AntPathRequestMatcher("/api-docs/**") ); RequestMatcher allRequestsMatcher = new AntPathRequestMatcher("/**"); return request -> { boolean isExcluded = excludeMatchers.stream().anyMatch(matcher -> matcher.matches(request)); return allRequestsMatcher.matches(request) && !isExcluded; }; }
3. 调整SecurityFilterChain配置,启用CSRF并允许Swagger匿名访问
开启CSRF,并配置忽略Swagger路径的CSRF验证,同时明确授权Swagger路径无需认证:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf .ignoringRequestMatchers( new AntPathRequestMatcher("/swagger-ui/**"), new AntPathRequestMatcher("/api-docs/**") ) ) .authorizeRequests(auth -> auth // 允许Swagger相关路径匿名访问 .antMatchers("/swagger-ui/**", "/api-docs/**").permitAll() // 其他业务请求需认证(根据实际需求调整) .anyRequest().authenticated() ); // 确保自定义过滤器添加到正确的位置(如果之前未手动添加) // http.addFilterBefore(customAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); }
4. 调整Swagger全局安全配置,移除强制Token要求
修改SwaggerConfig,移除全局的SecurityRequirement,改为在需要认证的接口上通过@SecurityRequirement注解单独配置:
@Bean public OpenAPI apiInfo() { final String securitySchemeName = "bearerAuth"; return new OpenAPI() // 移除全局安全要求,避免UI默认要求Token // .addSecurityItem(new SecurityRequirement().addList(securitySchemeName)) .components(new Components().addSecuritySchemes( securitySchemeName, new SecurityScheme() .name(securitySchemeName) .type(SecurityScheme.Type.HTTP) .in(SecurityScheme.In.HEADER) .scheme("bearer") .bearerFormat("JWT") )) .info(new Info() .title(title) .version(version) .description("") ) .servers(Collections.singletonList( new Server() .url(contextPath) .description("Default Server URL") )); }
验证
重启应用后,访问localhost/api/myservice/swagger-ui/index.html,页面应正常加载且无需授权;业务API仍会被CustomAuthenticationFilter拦截处理,同时CSRF保护正常生效。
内容的提问来源于stack exchange,提问作者Emalee
相关产品推荐
相关产品推荐

