如何为指定来源禁用CSRF?Swagger集成认证配置遇阻求助
问题描述
我需要在Swagger中添加认证,但不知道如何为每个请求传递CSRF Token。禁用CSRF保护虽能正常运行,但并非合理方案,因此希望为Swagger相关的特定来源禁用CSRF。
我的SecurityFilterChain配置如下:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .and() .exceptionHandling().authenticationEntryPoint(authEntryPoint) .and() .authorizeHttpRequests() .antMatchers("/swagger-resources/**","/v2/api-docs","/swagger-ui/**","/auth/**","/user","/csrf") .permitAll() .anyRequest() .authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authenticationProvider(authenticationProvider) .addFilterBefore(malformedTokenHandler, LogoutFilter.class) .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }
另外我的SwaggerConfig类如下:
public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .securityContexts(Arrays.asList(securityContext())) .securitySchemes(Arrays.asList(apiKey())) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } private ApiKey apiKey() { return new ApiKey("JWT", "Authorization", "header"); } List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return Arrays.asList(new SecurityReference("JWT", authorizationScopes)); } private List<Parameter> operationParameters(CsrfTokenRepository csrfTokenRepository) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); CsrfToken csrfToken = csrfTokenRepository.loadToken(request); return Arrays.asList( new ParameterBuilder() .name("X-CSRF-TOKEN") .modelRef(new ModelRef("string")) .parameterType("header") .defaultValue(csrfToken.getToken()) .required(false) .build()); } }
我尝试添加以下配置,但并未生效:
http.csrf().ignoringAntMatchers("/swagger-resources/**","/v2/api-docs","/swagger-ui/**")
解决方案
1. 修正CSRF忽略路径的配置方式
你之前的链式调用写法有误,需要将ignoringAntMatchers和csrfTokenRepository放在同一段CSRF配置中。使用Spring Security 5.2+推荐的Lambda式配置可以避免此类错误,修改后的SecurityFilterChain如下:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 统一配置CSRF规则 .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringAntMatchers( "/swagger-resources/**", "/v2/api-docs", "/swagger-ui/**", "/swagger-ui.html" // 补充该路径,避免遗漏Swagger入口页 )) .exceptionHandling().authenticationEntryPoint(authEntryPoint) .and() .authorizeHttpRequests(auth -> auth .antMatchers("/swagger-resources/**","/v2/api-docs","/swagger-ui/**","/auth/**","/user","/csrf") .permitAll() .anyRequest().authenticated()) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authenticationProvider(authenticationProvider) .addFilterBefore(malformedTokenHandler, LogoutFilter.class) .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); }
2. (可选)让Swagger自动携带CSRF Token
如果不想忽略Swagger路径的CSRF校验,可修改SwaggerConfig为所有接口添加全局CSRF请求头参数,方便手动输入或自动读取Cookie值:
@Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .securityContexts(Arrays.asList(securityContext())) .securitySchemes(Arrays.asList(apiKey())) // 添加全局CSRF Token参数 .globalOperationParameters(Arrays.asList( new ParameterBuilder() .name("X-CSRF-TOKEN") .modelRef(new ModelRef("string")) .parameterType("header") .description("从Cookie的XSRF-TOKEN字段获取") .required(true) .build() )) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); }
注:
CookieCsrfTokenRepository默认会将CSRF Token存入名为XSRF-TOKEN的Cookie中,Swagger UI通常会自动读取该Cookie并填充请求头,若未自动生效可手动复制Cookie值填入参数框。
3. 排查路径匹配问题
若忽略路径仍不生效,检查以下两点:
- 确认项目是否有上下文路径(Context Path),若有需在匹配路径前添加,例如
/your-app/swagger-ui/** - 改用
mvcMatchers替代antMatchers,它更贴合Spring MVC的路径匹配规则:
.ignoringMvcMatchers("/swagger-resources/**", "/v2/api-docs", "/swagger-ui/**")
内容的提问来源于stack exchange,提问作者Triarta
相关产品推荐
相关产品推荐

