Vaadin 14.6及以上版本嵌入式Undertow应用启动返回403 Forbidden错误
问题根因
Vaadin 14.6 版本新增了静态资源访问安全校验逻辑,会拦截所有直接指向 META-INF/、WEB-INF/ 这类受保护 classpath 路径的资源请求。你当前的 Undertow 配置直接将 META-INF/resources 绑定为根路径的全局资源管理器,所有静态资源的实际访问路径都会被 Vaadin 判定为指向受保护的 META-INF 前缀路径,因此返回 403 错误。14.5 及更早版本没有这项校验,所以运行正常。
修复方案
无需引入额外依赖,仅需要调整 Undertow 的资源映射规则和 Vaadin 初始化参数即可,整体内存开销几乎无变化:
- 移除全局资源管理器绑定,改为仅针对 Vaadin 专用静态资源前缀做路径映射
- 添加 Vaadin 静态资源校验豁免参数,避免合法资源请求被拦截
修改后核心代码
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); ServletContainerInitializerInfo initInfo = new ServletContainerInitializerInfo(RouteRegistryInitializer.class,setOfRouteAnnotatedClasses()) ; // 保留原资源管理器配置,不再绑定到部署全局 ClassPathResourceManager resMgr = new ClassPathResourceManager(classLoader, "META-INF/resources"); DeploymentInfo deploymentInfo = Servlets.deployment() .setClassLoader(classLoader) .setContextPath("/") .setDeploymentName("cb200") .setDefaultEncoding("UTF-8") .addServletContainerInitializer(initInfo) .addListener(Servlets.listener(ServletDeployer.class)) .addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, wsdi) // 新增Vaadin静态资源校验豁免参数 .addInitParameter("com.vaadin.flow.server.disableStaticResourceCheck", "true") // 可选:开启生产模式进一步降低内存占用 .addInitParameter("vaadin.productionMode", "true"); DeploymentManager deploymentMgr = Servlets.defaultContainer().addDeployment(deploymentInfo); deploymentMgr.deploy(); // 单独配置静态资源处理器,仅匹配Vaadin需要的资源前缀 Handler resourceHandler = new PathHandler() .addPrefixPath("/VAADIN", new ResourceHandler(resMgr)) .addPrefixPath("/frontend", new ResourceHandler(resMgr)); // 拼接处理器链:优先匹配静态资源,再转发到Vaadin Servlet处理动态请求 PathHandler path = path(redirect("/")) .addPrefixPath("/", resourceHandler) .addPrefixPath("/", deploymentMgr.start()); Undertow server = Undertow.builder() .addHttpListener(SERVER_PORT, SERVER_HOST) .setHandler(path) .build(); server.start();
验证说明
修改后启动应用,静态资源会先通过独立的资源处理器返回,不会进入Vaadin的安全校验逻辑,同时动态请求依然走原有Vaadin Servlet处理,不会影响原有功能,启动速度和内存占用和14.5版本基本一致。
内容的提问来源于stack exchange,提问作者carnecro
相关产品推荐
相关产品推荐

