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

Spring Security环境下无法访问Swagger URL,报403错误求助

解决Spring Security与Swagger OpenAPI 403冲突问题

问题分析

你的配置存在两处关键错误导致白名单规则失效:

  1. authorizeHttpRequests 内部链式调用语法错误,and().authenticationManager(authenticationManager) 放在lambda内会打断授权规则的正常解析;
  2. 错误禁用了CORS,同时又定义了CorsConfigurationSource Bean,导致跨域配置失效,影响Swagger资源加载。

修正后的完整配置代码

package com.mariojunior.todo.config;

import com.mariojunior.todo.security.JWTAuthenticationFilter;
import com.mariojunior.todo.security.JWTAuthorizationFilter;
import com.mariojunior.todo.security.JWTUtil;
import com.mariojunior.todo.service.UserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfig {

    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JWTUtil jwtUtil;

    private static final String[] PUBLIC_MATCHERS_POST = {
            "/users/",
            "/login"
    };

    private static final String[] AUTH_WHITELIST ={
            "/v3/api-docs/**",
            "/swagger-ui/**",
            "/swagger-ui.html"
    };


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        // 禁用CSRF,启用自定义CORS配置
        http.csrf(AbstractHttpConfigurer::disable)
                .cors(cors -> cors.configurationSource(corsConfigurationSource()));

        AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());

        this.authenticationManager = authenticationManagerBuilder.build();

        // 正确配置授权规则,将authenticationManager移到lambda外部
        http.authorizeHttpRequests(request -> {
            request.requestMatchers(AUTH_WHITELIST).permitAll();
            request.requestMatchers(HttpMethod.POST, PUBLIC_MATCHERS_POST).permitAll();
            request.anyRequest().authenticated();
        })
        .authenticationManager(authenticationManager);

        // 调整过滤器顺序:先认证过滤器,再授权过滤器
        http.addFilter(new JWTAuthenticationFilter(this.authenticationManager, jwtUtil));
        http.addFilter(new JWTAuthorizationFilter(this.authenticationManager, jwtUtil, userDetailsService));

        http.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        return http.build();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
        configuration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "DELETE", "OPTIONS"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

关键修改说明

  • 修复授权规则语法:将authenticationManager配置从authorizeHttpRequests的lambda内部移到外部,确保白名单规则被正确执行;
  • 启用CORS配置:替换cors(AbstractHttpConfigurer::disable)为自定义CORS配置,补充OPTIONS请求方法,避免预请求被拦截;
  • 补充Swagger路径:添加/swagger-ui.html到白名单,确保Swagger UI入口页面可访问;
  • 调整过滤器顺序:先添加认证过滤器,再添加授权过滤器,符合Spring Security的执行逻辑。

验证方式

重启应用后,访问http://localhost:你的端口/swagger-ui.html,若能正常加载Swagger页面则说明配置生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:12:36