You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swagger UI不显示控制器端点,因csrf接口请求失败

问题:集成Swagger UI后控制器API未显示,控制台请求localhost:9000/和localhost:9000/csrf失败

集成Swagger UI后,控制器的API未在界面上显示。查看浏览器开发者控制台,发现localhost:9000/和localhost:9000/csrf接口请求失败,推测问题与CSRF配置相关,但无法确定具体解决方法。


Security配置

@Override
protected void configure(AuthenticationManagerBuilder auth) {
    auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}

@Bean
public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
    ActiveDirectoryLdapAuthenticationProvider authenticationProvider =
            new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl,ldapBase);

    authenticationProvider.setConvertSubErrorCodesToExceptions(true);
    authenticationProvider.setUseAuthenticationRequestCredentials(true);
    authenticationProvider.setSearchFilter("(sAMAccountName={1})");
    return authenticationProvider;
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .csrf()
            .disable()
            .exceptionHandling().authenticationEntryPoint(jwtUnAuthorizedResponseAuthenticationEntryPoint).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests()
            .antMatchers("/v2/api-docs",
                    "/configuration/ui",
                    "/swagger-resources/**",
                    "/configuration/security",
                    "/swagger-ui.html",
                    "/webjars/**").permitAll()
            .anyRequest().authenticated();
    httpSecurity
            .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    httpSecurity
            .headers()
            .frameOptions().sameOrigin()  //H2 Console Needs this setting
            .cacheControl(); //disable caching
}

@Override
public void configure(WebSecurity webSecurity) throws Exception {
    webSecurity
            .ignoring()
            .antMatchers(
                    HttpMethod.POST,
                    authenticationPath
            )
            .antMatchers(HttpMethod.OPTIONS, "/**")
            .and()
            .ignoring()
            .antMatchers(
                    HttpMethod.GET,
                    "/" //Other Stuff You want to Ignore
            )
            .and()
            .ignoring()
            .antMatchers("/h2-console/**/**");//Should not be in Production!
}

Swagger配置

public static final String DEFAULT_INCLUDE_PATTERN = "/deployer/*.*";

@Bean
public Docket productApi() {
    return new Docket(DocumentationType.SWAGGER_2).select()
            .apis(RequestHandlerSelectors.basePackage("com.org.deployer.controller"))
            .paths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN)).build().apiInfo(metaData())
            .securityContexts(Lists.newArrayList(securityContext()))
            .securitySchemes(Lists.newArrayList(apiKey()))
            .useDefaultResponseMessages(false);
}

private ApiKey apiKey() {
    return new ApiKey("JWT", AUTHORIZATION_HEADER, "header");
}

private SecurityContext securityContext() {
    return SecurityContext.builder()
            .securityReferences(defaultAuth())
            .forPaths(PathSelectors.regex(DEFAULT_INCLUDE_PATTERN))
            .build();
}

List<SecurityReference> defaultAuth() {
    AuthorizationScope authorizationScope
            = new AuthorizationScope("global", "accessEverything");
    AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
    authorizationScopes[0] = authorizationScope;
    return Lists.newArrayList(
            new SecurityReference("JWT", authorizationScopes));
}

/v2/api-docs接口响应

{
  "swagger": "2.0",
  "info": {
    "description": "deployment Tool ",
    "version": "1.0",
    "title": " api",
    "termsOfService": "Terms of service",
    "contact": {
      "name": "Support Team"
    },
    "license": {
      
    }
  },
  "host": "localhost:9000",
  "basePath": "/",
  "securityDefinitions": {
    "JWT": {
      "type": "apiKey",
      "name": "Authorization",
      "in": "header"
    }
  }
}

控制器代码

package com.org.deployer.controller;


@RestController
@CrossOrigin(origins = "http://localhost:4200")
@Api(value = "package operations", description = "Operations pertaining to Package Schedule")
public class PackageScheduleController {

    private static final Logger logger = LoggerFactory.getLogger(PackageScheduleController.class);

    @Autowired
    PackageScheduleService packageScheduleService;


    @PostMapping("/schedule")
    @ApiOperation(value = "This method is used to get the clients.")
    public PackageScheduleResponse schedule(@RequestBody PackageScheduleRequest packageScheduleRequest){
        try{
        logger.info("Schedule Request received for {}",packageScheduleRequest.getName());
            System.out.println(packageScheduleRequest.getScheduleTime().toLocalTime());
        return packageScheduleService.schedule(packageScheduleRequest);
        }
        catch(Exception e){
            logger.error("Exception occured",e);
            throw new RuntimeException("Some Error Occured");
        }
    }

    @GetMapping("/view-schedule")
    public List<PackageScheduleDto> schedule(){
        try{
            logger.info("Request received for fetching upcoming schedule jobs");
            return packageScheduleService.fetchAllScheudules();
        }
        catch(Exception e){
            logger.error("Exception occured",e);
            throw new RuntimeException("Some Error Occured");
        }
    }
}

解决方案

1. 修正Swagger路径匹配规则

当前Swagger配置的DEFAULT_INCLUDE_PATTERN = "/deployer/*.*"与控制器实际接口路径/schedule、/view-schedule完全不匹配,导致Swagger无法扫描到接口。修改路径匹配规则:

// 匹配控制器的具体接口路径
public static final String DEFAULT_INCLUDE_PATTERN = "/(schedule|view-schedule).*";
// 或宽松匹配所有路径(适合后续扩展接口)
public static final String DEFAULT_INCLUDE_PATTERN = "/.*";

2. 处理/csrf请求失败问题

虽然已禁用CSRF,但Swagger UI仍可能尝试获取CSRF令牌,导致请求失败。在HttpSecurity的允许列表中添加/csrf:

.antMatchers("/v2/api-docs",
        "/configuration/ui",
        "/swagger-resources/**",
        "/configuration/security",
        "/swagger-ui.html",
        "/webjars/**",
        "/csrf").permitAll()

3. 验证Swagger扫描范围

确认RequestHandlerSelectors.basePackage("com.org.deployer.controller")的包名与控制器实际包名一致,避免因包名错误导致扫描失败。

4. 确认接口扫描结果

修正配置后,重新访问/v2/api-docs,响应中应包含paths字段,显示控制器的接口信息,此时Swagger UI即可正常展示API。

内容的提问来源于stack exchange,提问作者Manish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:09:30