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

Wildfly对所有CORS预检请求返回405的问题排查求助

解决Wildfly下CORS预检请求返回405的问题

核心问题定位

你的405错误并非来自Access-Control-Allow-Credentials:true与*的冲突(该冲突会返回特定CORS错误而非405),而是OPTIONS预检请求未被正确处理,导致容器返回"方法不允许"状态码。结合你的场景,主要原因有两点:

  1. 自定义UserCredentialFilter未正确拦截/处理OPTIONS请求,或执行顺序问题导致Wildfly的CORS配置无法生效
  2. JAX-RS端点未声明支持OPTIONS方法,容器默认拒绝该请求

解决方案步骤

1. 修正自定义Servlet过滤器,优先处理OPTIONS请求

你的UserCredentialFilter需要在请求链路最前端处理OPTIONS请求,确保返回200状态码,避免后续环节拒绝请求。同时明确指定拦截OPTIONS类型的请求:

修改后的过滤器代码:

@WebFilter(urlPatterns = {"/*"}, dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.OPTIONS})
public class UserCredentialFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserCredentialFilter.class);
    private final User user;

    @Inject
    public UserCredentialFilter(User user) {
        this.user = user;
    }

    @Override
    public void init(FilterConfig filterConfig) {
        // 无初始化逻辑
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 直接处理OPTIONS预检请求
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            // 若Wildfly的CORS配置未生效,可手动补充CORS头
            // response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5173");
            // response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT");
            // response.setHeader("Access-Control-Allow-Headers", "accept, authorization, content-type, x-requested-with");
            // response.setHeader("Access-Control-Allow-Credentials", "true");
            return;
        }

        // 处理其他请求的用户凭证逻辑
        Principal userPrincipal = request.getUserPrincipal();
        if (userPrincipal != null) {
            // 用户相关业务逻辑
        }
        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 无销毁逻辑
    }
}

关键修改:

  • 添加dispatcherTypes参数,确保过滤器拦截OPTIONS请求
  • 遇到OPTIONS请求直接返回200状态码,无需进入后续业务逻辑

2. 修正Wildfly的CORS配置,解决凭证与通配符冲突

虽然当前错误不是此原因导致,但该配置违反CORS规范,必须修正:

  • 将Access-Control-Allow-Origin设置为前端具体域名(如http://127.0.0.1:5173),而非*
  • 保留Access-Control-Allow-Credentials: true

调整后的Wildfly CLI配置脚本:

/subsystem=undertow/server=default-server/host=default-host/filter-ref=cors-filter:add(predicate="path-prefix('/my-services/rest-api')")
/subsystem=undertow/filter=cors-filter:write-attribute(name=access-control-allow-origin, value="http://127.0.0.1:5173")
/subsystem=undertow/filter=cors-filter:write-attribute(name=access-control-allow-methods, value="GET, POST, OPTIONS, PUT")
/subsystem=undertow/filter=cors-filter:write-attribute(name=access-control-allow-headers, value="accept, authorization, content-type, x-requested-with")
/subsystem=undertow/filter=cors-filter:write-attribute(name=access-control-allow-credentials, value=true)
/subsystem=undertow/filter=cors-filter:write-attribute(name=access-control-max-age, value=86400)

3. 确保JAX-RS端点支持OPTIONS方法(可选)

如果JAX-RS资源类未显式支持OPTIONS方法,容器可能拒绝请求。可通过两种方式处理:

  • 在资源类中添加@OPTIONS方法:
@Path("/selection-data")
public class SelectionDataResource {
    @OPTIONS
    @Path("/all")
    public Response handleOptions() {
        return Response.ok().build();
    }

    // 原有GET方法
    @GET
    @Path("/all")
    @Produces(MediaType.APPLICATION_JSON)
    public List<SelectionData> getAll() {
        // 业务逻辑实现
    }
}
  • 或通过Resteasy的CORSFilter注册全局处理逻辑,确保Wildfly识别:
@Provider
public class CORSFeature implements Feature {
    @Override
    public boolean configure(FeatureContext context) {
        CORSFilter filter = new CORSFilter();
        filter.setAllowedOrigins("http://127.0.0.1:5173");
        filter.setAllowedMethods("GET, POST, OPTIONS, PUT");
        filter.setAllowedHeaders("accept, authorization, content-type, x-requested-with");
        filter.setAllowCredentials(true);
        context.register(filter);
        return true;
    }
}

验证步骤

  1. 重启Wildfly,确保配置与代码修改生效
  2. 用浏览器开发者工具查看OPTIONS请求响应:
    • 确认状态码为200
    • 确认CORS头正确返回,且Access-Control-Allow-Origin为具体域名而非*
  3. 测试前端GET请求,确认CORS错误消失

内容的提问来源于stack exchange,提问作者georgebax

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:14:52