Spring Boot OpenAPI 3.0:私有端点403错误文档配置咨询
解决方案
可以通过以下几种方式实现需求,无需逐个给私有端点添加注解,就能让OpenAPI仅在需要权限验证的端点文档中显示403错误信息:
方法一:自定义OperationCustomizer过滤私有路径端点
- 先移除Controller Advice上的
@ApiResponse注解,避免全局给所有端点添加403响应。 - 实现
OperationCustomizer接口,在逻辑中识别/private前缀的端点,为其添加403响应定义:
@Component public class PrivateEndpointResponseCustomizer implements OperationCustomizer { @Override public Operation customize(Operation operation, HandlerMethod handlerMethod) { // 处理@RequestMapping注解的路径 RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class); if (requestMapping != null) { for (String path : requestMapping.value()) { if (path.startsWith("/private")) { ApiResponse forbiddenResponse = new ApiResponse() .responseCode("403") .description("Forbidden: 权限不足"); operation.addApiResponse("403", forbiddenResponse); break; } } } // 处理GetMapping、PostMapping等其他请求注解 GetMapping getMapping = handlerMethod.getMethodAnnotation(GetMapping.class); if (getMapping != null) { for (String path : getMapping.value()) { if (path.startsWith("/private")) { ApiResponse forbiddenResponse = new ApiResponse() .responseCode("403") .description("Forbidden: 权限不足"); operation.addApiResponse("403", forbiddenResponse); break; } } } return operation; } }
- 这个类会被Spring自动扫描,生成OpenAPI文档时,仅为
/private前缀的端点添加403响应,公共端点不会包含该信息。
方法二:结合Spring Security权限注解自动添加
如果你的私有端点是用@PreAuthorize、@Secured这类权限注解标记的,可以基于注解判断:
- 同样先移除Controller Advice上的
@ApiResponse。 - 修改
OperationCustomizer的逻辑,检查方法或类是否有权限注解:
@Component public class SecuredEndpointResponseCustomizer implements OperationCustomizer { @Override public Operation customize(Operation operation, HandlerMethod handlerMethod) { // 检查方法或类是否有@PreAuthorize注解 if (handlerMethod.hasMethodAnnotation(PreAuthorize.class) || handlerMethod.getBeanType().hasAnnotation(PreAuthorize.class)) { ApiResponse forbiddenResponse = new ApiResponse() .responseCode("403") .description("Forbidden: 权限不足"); operation.addApiResponse("403", forbiddenResponse); } // 可扩展支持@Secured、@RolesAllowed等注解 return operation; } }
这种方式更灵活,无论路径如何,只要标记了权限注解的端点都会自动添加403响应。
方法三:拆分OpenAPI文档分组
如果公共和私有端点边界清晰,可以将它们拆分为两个独立的OpenAPI文档:
- 配置两个OpenAPI实例,分别对应公共和私有端点:
@Configuration public class OpenApiConfig { @Bean public OpenAPI publicApi() { return new OpenAPI() .info(new Info().title("公共API").version("v1")) .paths(getFilteredPaths(false)); } @Bean public OpenAPI privateApi() { // 给私有API添加全局403响应 Components components = new Components() .addResponses("403", new ApiResponse().description("Forbidden: 权限不足")); return new OpenAPI() .info(new Info().title("私有API").version("v1")) .components(components) .paths(getFilteredPaths(true)); } // 筛选对应路径的端点 private Map<String, PathItem> getFilteredPaths(boolean isPrivate) { // 实现逻辑:根据isPrivate参数,筛选出对应前缀的端点路径 } }
- 公共API文档不会包含403响应,私有API文档则全局添加该响应,用户可分别访问两个文档地址。
推荐根据你标记私有端点的实际方式选择第一种或第二种方案,配置成本更低且更贴合业务场景。
内容的提问来源于stack exchange,提问作者azuosxela
相关产品推荐
相关产品推荐

