You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 初始化参数即可,整体内存开销几乎无变化:

  1. 移除全局资源管理器绑定,改为仅针对 Vaadin 专用静态资源前缀做路径映射
  2. 添加 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:36:05