Spring Boot中如何根据环境(如PROD)禁用指定Swagger接口?
在PROD环境下隐藏/禁用Swagger中的指定接口
以下针对主流的ASP.NET Core和Spring Boot框架,提供具体实现方案:
ASP.NET Core 实现方案
方法1:自定义Swagger过滤器+环境判断(推荐)
既能在Swagger UI中隐藏接口,也能在逻辑层禁用生产环境的调用。
- 定义自定义特性,标记需要控制的接口:
[AttributeUsage(AttributeTargets.Method)] public class HideInProductionAttribute : Attribute { }
- 实现Swagger操作过滤器,结合环境判断隐藏接口:
public class HideInProductionFilter : IOperationFilter { private readonly IWebHostEnvironment _hostEnv; public HideInProductionFilter(IWebHostEnvironment hostEnv) { _hostEnv = hostEnv; } public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (_hostEnv.IsProduction() && context.MethodInfo.GetCustomAttribute<HideInProductionAttribute>() != null) { // 添加x-hidden标记,Swagger UI会自动隐藏该接口 operation.Extensions.Add("x-hidden", true); } } }
- 注册过滤器到Swagger配置:
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }); c.OperationFilter<HideInProductionFilter>(); });
- 标记接口并禁用生产环境调用:
[ApiController] [Route("api/[controller]")] public class MyController : ControllerBase { private readonly IWebHostEnvironment _hostEnv; public MyController(IWebHostEnvironment hostEnv) { _hostEnv = hostEnv; } // 普通接口:所有环境可见且可用 [HttpGet("normal")] public IActionResult NormalEndpoint() => Ok("Available everywhere"); // 受控接口:生产环境下Swagger隐藏+无法调用 [HttpGet("sensitive")] [HideInProduction] public IActionResult SensitiveEndpoint() { if (_hostEnv.IsProduction()) { return NotFound(); // 或返回403禁止访问 } return Ok("Only available in non-prod environments"); } }
方法2:简化版仅禁用接口调用
如果不需要在Swagger中隐藏,仅需禁止生产环境调用,可直接在接口逻辑中判断:
[HttpGet("sensitive")] public IActionResult SensitiveEndpoint() { if (_hostEnv.IsProduction()) { return Forbid(); } return Ok("Only for non-prod"); }
Spring Boot 实现方案
方法1:使用@Profile注解(最简便)
直接控制接口在指定环境下是否被Spring注册,既禁用调用也隐藏Swagger显示:
@RestController @RequestMapping("/api") public class MyController { // 普通接口:所有环境可用 @GetMapping("/normal") public String normalEndpoint() { return "Available everywhere"; } // 仅在非prod环境生效 @GetMapping("/sensitive") @Profile("!prod") public String sensitiveEndpoint() { return "Only available in non-prod"; } }
prod环境启动时,该接口不会被注册,自然无法调用,Swagger也不会扫描到。
方法2:自定义Swagger过滤器隐藏接口
需保留接口注册但在Swagger中隐藏时,可使用这种方式:
- 定义自定义注解:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface HideInProd { }
- 实现Swagger操作过滤器:
@Component public class HideInProdFilter implements OperationBuilderPlugin { @Autowired private Environment environment; @Override public void apply(OperationContext context) { if (Arrays.asList(environment.getActiveProfiles()).contains("prod") && context.getHandlerMethod().hasMethodAnnotation(HideInProd.class)) { context.operationBuilder().hidden(true); } } @Override public boolean supports(DocumentationType documentationType) { // 适配Swagger 3.x(OpenAPI 3.0) return documentationType == DocumentationType.OAS_30; } }
- 标记接口并禁用生产环境调用:
@GetMapping("/sensitive") @HideInProd public String sensitiveEndpoint() { if (Arrays.asList(environment.getActiveProfiles()).contains("prod")) { throw new ResponseStatusException(HttpStatus.FORBIDDEN); } return "Only visible in non-prod Swagger"; }
核心注意点
- 仅隐藏Swagger UI不足以保证安全,必须在接口逻辑中添加环境判断,防止生产环境下被直接调用。
- 不同Swagger版本(如2.x vs 3.x)的配置细节略有差异,需根据实际版本调整。
内容的提问来源于stack exchange,提问作者jijohn
相关产品推荐
相关产品推荐

