自定义拦截器拦截/v2/api"/>
记一次自定义拦截器拦截/v2/api
项目场景:
项目中使用swagger来自动生成接口文档,为了防止接口文档地址在外网被访问,需要对swagger的静态资源链接以及动态接口请求根据host属性做一些处理,使得外网域名不能访问接口文档地址。一个容易想到的办法就是通过Spring的Interceptor来实现,在preHandle方法中对swagger的请求路径做拦截。
问题描述
SwaggerInterceptor可以拦截到/swagger-ui.html请求,但是始终无法拦截/v2/api-docs接口,用户还是可以通过直接访 /v2/api-docs获取所有接口的json格式信息。
@Configuration
public class CorsConfig implements WebMvcConfigurer {@Beanpublic AuthInterceptor authInterceptor() {return new AuthInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authInterceptor())// 拦截所有请求.addPathPatterns("/**");}
}
原因分析:
首先,检查拦截器的配置,发现AuthInterceptor配置是拦截全部请求addPathPatterns(“/**”),并且可以拦截到/swagger-ui.html,确认不是拦截器全局配置的问题。
解决方案:
既然自定的HanderMapping初始化未绑定拦截器,导致拦截器失效,那我们换一种思路,通过ResponseBodyAdvice配合@ControllerAdvice注解,在请求响应体返回之前,校验请求URL,若为外网请求的Swagger路径,进行拦截。
@RestControllerAdvice
public class SwaggerAdvice implements ResponseBodyAdvice {private static final List<String> EXCLUDE_URL = Arrays.asList("/v2/api-docs");@Overridepublic Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {String url = serverHttpRequest.getURI().getHost() + serverHttpRequest.getURI().getPath();if (EXCLUDE_URL.stream().anyMatch(item -> url.contains(item))) {serverHttpResponse.setStatusCode(HttpStatus.FORBIDDEN);throw new BusinessException("鉴权失败,该行为未授权,暂无权访问");}return o;}@Overridepublic boolean supports(MethodParameter methodParameter, Class aClass) {return true;}
}
结果:
至此,可以做到拦截/v2/api-docs接口的外网请求
更多推荐
记一次自定义拦截器拦截/v2/api
发布评论