Spring Boot集成Vaadin时如何全局禁用PUT/DELETE请求?
问题
在Spring Boot中运行Vaadin时,尝试通过实现WebMvcConfigurer和HandlerInterceptor来禁用PUT、DELETE请求,但自定义拦截器的preHandle方法从未被调用。已确认WebMvcConfigurer已加载,怀疑Vaadin的AtmosphereInterceptor覆盖了自定义Spring配置,想知道如何在Vaadin中默认对所有路径(/**)禁用PUT和DELETE请求。
尝试的代码如下:
@Component class HTTPRequestInterceptor extends HandlerInterceptor { override def preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean = { if (HttpMethod.GET.matches(request.getMethod) || HttpMethod.POST.matches(request.getMethod)) { true } else { response.sendError(HttpStatus.METHOD_NOT_ALLOWED.value()) false } } } @Configuration class HTTPRequestInterceptorConfig (@Autowired interceptor: HTTPRequestInterceptor) extends WebMvcConfigurer { private val log = LoggerFactory.getLogger(classOf[HTTPRequestInterceptorConfig]) override def addInterceptors(registry: InterceptorRegistry): Unit = { log.info("adding interceptors") registry.addInterceptor(interceptor).addPathPatterns("/**") } }
注:带@Autowired参数和不带@Autowired参数的方式都试过了。
解决方案
方法1:实现Vaadin RequestHandler拦截请求
Vaadin的请求处理优先级高于Spring MVC拦截器,直接实现Vaadin的RequestHandler可以拦截所有Vaadin相关请求:
@Component class VaadinMethodRestrictionHandler extends RequestHandler { override def handleRequest(request: VaadinRequest, response: VaadinResponse): Boolean = { val httpRequest = request.asInstanceOf[VaadinServletRequest].getHttpServletRequest val method = httpRequest.getMethod if (!Set("GET", "POST").contains(method)) { val httpResponse = response.asInstanceOf[VaadinServletResponse].getHttpServletResponse httpResponse.sendError(HttpStatus.METHOD_NOT_ALLOWED.value()) true // 标记请求已处理,终止后续流程 } else { false // 放行,让后续处理器处理请求 } } override def supportsRequest(request: VaadinRequest): Boolean = true // 对所有请求生效 }
将该类注册为Spring组件后,会在Vaadin处理请求前执行,直接拦截非GET/POST请求。
方法2:通过Spring Security限制HTTP方法
若项目使用Spring Security,可直接配置安全规则禁用PUT/DELETE,不受Vaadin拦截器优先级影响:
@Configuration @EnableWebSecurity class SecurityConfig extends WebSecurityConfigurerAdapter { override def configure(http: HttpSecurity): Unit = { http .authorizeRequests() .antMatchers(HttpMethod.PUT, "/**").denyAll() .antMatchers(HttpMethod.DELETE, "/**").denyAll() .anyRequest().permitAll() } }
该配置会在安全层直接拦截非法请求,返回405状态码。
方法3:提升Spring MVC拦截器优先级
若坚持使用Spring MVC的HandlerInterceptor,可通过设置拦截器优先级让其优先执行:
修改HTTPRequestInterceptorConfig,添加拦截器时指定最高优先级:
@Configuration class HTTPRequestInterceptorConfig (@Autowired interceptor: HTTPRequestInterceptor) extends WebMvcConfigurer { private val log = LoggerFactory.getLogger(classOf[HTTPRequestInterceptorConfig]) override def addInterceptors(registry: InterceptorRegistry): Unit = { log.info("adding interceptors") registry.addInterceptor(interceptor) .addPathPatterns("/**") .order(Ordered.HIGHEST_PRECEDENCE) // 设置最高优先级 } }
注意:此方法可能因Vaadin Servlet直接处理请求路径,导致Spring MVC拦截器无法捕获,前两种方法更可靠。
内容的提问来源于stack exchange,提问作者TiN
相关产品推荐
相关产品推荐

