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

SpringBoot集成Swagger UI访问403及页面无法加载问题修复

SpringBoot+SpringSecurity+JWT集成Springfox Swagger2问题修复方案

问题说明

项目集成Springfox Swagger2时出现两个异常:

  • 本地启动服务后Swagger文档不会自动打开,手动访问host/v2/api-docs可正常返回JSON格式接口文档,但Swagger UI界面无法加载,已引入springfox-swagger-ui依赖仍未生效
  • 除v2/api-docs路径外,访问Swagger相关链接(如localhost:8000/swagger-ui.html#!/signin)返回403授权错误,页面提示There was an unexpected error (type=Forbidden, status=403). Access Denied

根因排查

Swagger UI无法加载根因

  • 静态资源放行规则缺失:Swagger UI渲染依赖webjars目录下的js、css等静态资源,以及swagger-resources接口返回的配置元数据,原配置未将这些路径加入放行列表,资源被拦截后无法完成页面渲染
  • 路径匹配规则无效:原配置中编写的/**/swagger-ui.html#/**包含URL锚点#,锚点后的内容仅在浏览器前端解析,不会作为请求路径发送到服务端,Spring Security的antMatchers永远无法匹配到该规则,等于swagger-ui.html路径本身未被放行
  • 静态资源未跳过安全过滤器链:Swagger相关静态资源会经过JWT校验过滤器,增加了被拦截的概率

Swagger页面403错误根因

核心原因为Swagger全量依赖路径未被完整放行,除已配置放行的v2/api-docs外,其余Swagger运行必需的路径都被Spring Security的anyRequest().authenticated()规则拦截,未携带有效JWT时直接返回403无权限错误。


可落地修复步骤

1. 修正Spring Security放行规则

修改WebSecurityConfig类的两个配置方法,原有业务权限规则全部保留,仅替换/新增Swagger相关配置:

  1. 替换configure(HttpSecurity http)方法中Swagger相关的错误放行规则:
http.authorizeRequests()
        // 原有业务放行路径保留
        .antMatchers("/**/signin/otp", "/**/signin/**").permitAll()
        // 替换为全量Swagger路径放行
        .antMatchers(
                "/**/v2/api-docs/**",
                "/**/swagger-ui.html",
                "/**/swagger-resources/**",
                "/**/webjars/**",
                "/**/swagger-ui/**"
        ).permitAll()
        // 以下原有业务权限规则全部保持不变,不要修改
        .antMatchers("/**/customers/create").hasAnyAuthority(SALES)
        .antMatchers("/**/customers/update").hasAnyAuthority(SALES)
        .antMatchers("/**/customers/all").hasAnyAuthority(SALES)
        .antMatchers("/**/customers/deactivate").hasAnyAuthority(SALES)
        .antMatchers("/**/customers/reactivate").hasAnyAuthority(SALES)
        .antMatchers("/**/products/create").hasAnyAuthority(SALES)
        .antMatchers("/**/products/update").hasAnyAuthority(SALES)
        .antMatchers("/**/users/create").hasAnyAuthority(SALES)
        .antMatchers("/**/users/update").hasAnyAuthority(SALES)
        .antMatchers("/**/users/deactivate").hasAnyAuthority(SALES)
        .antMatchers("/**/users/reactivate").hasAnyAuthority(SALES)
        .antMatchers("/**/admin/user/all").hasAnyAuthority(ADMIN)
        .antMatchers("/**/xicustomers/create").hasAnyAuthority(SALES)
        .antMatchers("/**/xicustomers/update").hasAnyAuthority(SALES)
        .antMatchers("/**/xicustomers/all").hasAnyAuthority(SALES)
        .antMatchers("/**/partner/create").hasAnyAuthority(SALES)
        .antMatchers("/**/xicustomers/list").hasAnyAuthority(XI_PARTNER,XI_CONSULTANT)
        .antMatchers("/**/report/list/**").hasAnyAuthority(XI_CONSULTANT)
        .antMatchers("/**/originator").hasAnyAuthority(STANDART)
        .antMatchers("/**/blackhour/add").hasAnyAuthority(STANDART)
        .antMatchers("/**/blackhour").hasAnyAuthority(STANDART)
        .antMatchers("/**/access/**").anonymous()
        .antMatchers("/**/pwd/forgot").anonymous()
        .antMatchers("/**/maximo").anonymous()
        .anyRequest().authenticated();
  1. 修改configure(WebSecurity web)方法,将Swagger静态资源加入全局忽略列表,不经过安全过滤器链:
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/*/")
            .antMatchers("/eureka/**")
            .antMatchers(HttpMethod.OPTIONS, "/**")
            // 新增Swagger静态资源全局忽略
            .antMatchers(
                    "/swagger-ui.html",
                    "/swagger-ui/**",
                    "/swagger-resources/**",
                    "/v2/api-docs/**",
                    "/webjars/**"
            );
}

2. 优化JWT过滤器逻辑,跳过Swagger路径校验

修改JwtTokenFilter的doFilter方法,在token校验逻辑前新增Swagger路径判断,直接放行不做JWT校验:

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    String requestURI = request.getRequestURI();

    // 新增:Swagger相关路径直接放行,跳过JWT校验
    if (requestURI.contains("swagger") || requestURI.contains("webjars") || requestURI.contains("v2/api-docs")) {
        filterChain.doFilter(req, res);
        return;
    }

    String token = getBearerToken((HttpServletRequest) req);
    // 原有token校验逻辑全部保留,不要修改
    if (token != null && !requestURI.contains("/signin/otp")) {
        TokenParams params = null;          
        try {
            params = this.jwtTokenProvider.validateToken(token);
        } catch (JwtException | IllegalArgumentException e) {
            log.warn("Invalid Token: {}, Error: {}", params, e.getMessage());
            throw new UnauthorizedException();
        }

        if (!params.getRoles().contains(WebSecurityConfig.ADMIN) && params.isForOtp() == true) {
            log.warn("Invalid Token: {}, it is for OTP!", params);
            throw new UnauthorizedException();
        }
        
        Authentication auth = this.jwtTokenProvider.getAuthentication(token);           
        SecurityContextHolder.getContext().setAuthentication(auth);

        HeaderMapRequestWrapper wrappedRequest = new HeaderMapRequestWrapper(request);
        wrappedRequest.addHeader("companyId", params.getCompanyId());
        wrappedRequest.addHeader("user", params.getEmail());

        filterChain.doFilter(wrappedRequest, res);

    } else {
        filterChain.doFilter(req, res);
    }
}

3. 版本兼容性处理(仅SpringBoot 2.6.x及以上版本需要配置)

如果项目使用SpringBoot 2.6.0及以上版本,需要在application配置文件中添加如下配置,解决Springfox与SpringMVC默认路径匹配规则不兼容的问题:

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

4. 静态资源映射配置(可选,上述步骤完成后仍无法加载UI时添加)

新增Spring MVC资源映射配置,确保Swagger静态资源可被正常解析:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

验证标准

  • 重启服务后访问http://localhost:8000/swagger-ui.html可正常加载Swagger UI界面,无静态资源404错误
  • 点击Swagger页面内的任意接口(包括/signin接口)不会返回403错误,可正常发起接口调试
  • 原有业务接口的权限校验逻辑不受影响

内容的提问来源于stack exchange,提问作者Defne Sabancı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:21:54