三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

RuoYi项目上线前,别忘了给你的Swagger接口文档加把‘锁’(安全配置指南)

RuoYi项目上线前,别忘了给你的Swagger接口文档加把‘锁’(安全配置指南)

RuoYi项目上线前,Swagger接口文档安全防护全攻略

当RuoYi项目从开发环境走向生产环境时,很多团队会忽略一个看似微小却极其危险的安全漏洞——完全开放的Swagger接口文档。这些自动生成的API文档在开发阶段是团队协作的利器,但在线上环境中却可能成为黑客攻击的"藏宝图"。本文将深入探讨如何为Swagger文档加装多重安全防护,确保RuoYi项目上线后的接口安全。

1. 为什么生产环境必须保护Swagger文档

开发阶段为了方便调试和协作,我们通常会完全开放Swagger UI的访问权限。但在生产环境中,这种便利性会带来严重的安全隐患:

  • API结构完全暴露:Swagger清晰地展示了所有接口路径、参数格式和返回结构
  • 敏感信息泄露风险:文档中可能包含未充分脱敏的示例数据或内部命名规则
  • 自动化攻击入口:攻击者可以基于文档快速构建针对性攻击脚本

实际案例:某金融科技公司因未保护Swagger UI,导致攻击者通过/doc.html路径获取了所有转账接口规范,随后发起了精准的批量小额盗刷攻击。

提示:即使接口本身有权限验证,暴露API结构仍会大幅降低攻击者的探测成本

2. 基础防护:限制Swagger的访问环境

最简单的防护措施是在非开发环境禁用Swagger文档。RuoYi基于Spring Boot,可以通过配置文件实现环境区分:

# application-prod.yml spring: profiles: active: prod swagger: enabled: false

然后在Swagger配置类中添加条件判断:

@Configuration @EnableSwagger2 @ConditionalOnProperty(name = "swagger.enabled", havingValue = "true") public class SwaggerConfig { // 配置内容 }

进阶方案:更灵活的做法是通过Profile控制:

@Profile({"dev", "test"}) // 只在开发和测试环境生效 @Configuration @EnableSwagger2 public class SwaggerConfig {}

3. 访问控制:IP白名单与角色验证

完全禁用可能影响必要的运维工作,更精细的控制可以通过以下方式实现:

3.1 Spring Security集成方案

在RuoYi已有的安全框架上增加Swagger访问规则:

@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/v2/**", "/doc.html") .hasAnyRole("ADMIN", "DEVOPS") // 仅限特定角色访问 .and() .formLogin() .and() .csrf().disable(); }

3.2 基于IP的白名单控制

适合内部系统部署场景,通过自定义过滤器实现:

@Component public class SwaggerIPFilter implements Filter { private static final List<String> ALLOWED_IPS = Arrays.asList( "192.168.1.100", "10.0.0.15"); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String ip = request.getRemoteAddr(); String path = ((HttpServletRequest)request).getRequestURI(); if(path.contains("swagger") || path.contains("doc.html")) { if(!ALLOWED_IPS.contains(ip)) { ((HttpServletResponse)response).sendError(403); return; } } chain.doFilter(request, response); } }

4. 增强认证:为Swagger UI添加登录验证

对于需要更严格控制的场景,可以为Swagger本身添加独立认证层:

4.1 基础认证方案

@Configuration public class SwaggerSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.requestMatcher(EndpointRequest.toAnyEndpoint()) .authorizeRequests() .anyRequest().hasRole("SWAGGER_ADMIN") .and() .httpBasic(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("swaggeradmin") .password("{noop}ComplexPwd@123") .roles("SWAGGER_ADMIN"); } }

4.2 集成RuoYi现有认证

更推荐的方式是复用项目已有的认证体系:

@Controller public class SwaggerController { @GetMapping("/secure-api-docs") public String swaggerRedirect(HttpServletRequest request) { if(!SecurityUtils.getSubject().isPermitted("system:swagger:view")) { throw new UnauthorizedException(); } return "redirect:/swagger-ui.html"; } }

5. 生产环境最佳实践组合

根据不同的安全等级要求,推荐以下配置方案:

安全等级推荐配置适用场景
基础防护生产环境完全禁用Swagger对外公开服务,无内部调试需求
中等防护IP白名单+角色验证企业内部系统,需运维人员访问
高级防护独立认证+访问日志审计金融、政务等高安全要求系统

实施步骤检查清单

  1. 评估系统安全等级要求
  2. 选择适合的防护方案组合
  3. 在预发布环境充分测试
  4. 配置访问监控和告警机制
  5. 定期审计Swagger访问日志

6. 常见问题与故障排除

Q1:配置后无法访问Swagger页面

  • 检查是否同时存在多个安全规则冲突
  • 验证用户角色和权限是否配置正确
  • 查看浏览器控制台是否有认证相关的错误

Q2:如何验证防护是否生效

# 尝试从非白名单IP访问 curl -I http://your-domain.com/doc.html # 预期返回403或401 # 测试正确凭证访问 curl -u username:password http://your-domain.com/doc.html

Q3:Swagger资源文件被拦截确保以下路径也在保护规则内:

  • /swagger-resources/**
  • /webjars/**
  • /v2/api-docs
  • /favicon.ico

在实际项目中,我们曾遇到Nginx缓存导致安全配置失效的情况。解决方案是在Nginx配置中添加:

location ~* (swagger|api-docs|doc\.html) { proxy_no_cache 1; proxy_cache_bypass 1; }
← 返回列表