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

Keycloak Jakarta Servlet Filter Adapter 在认证失败响应中未设置CORS头的问题

Keycloak Jakarta Servlet Filter Adapter 在认证失败响应中未设置CORS头的问题

先把你的问题场景再明确下:

我的Jakarta Web应用用了keycloak-jakarta-servlet-filter-adapter对接Keycloak做认证。当用户认证通过且拥有要求的受众(audience)时,预检请求和实际请求的响应都能正确设置CORS头;但如果用户已经认证,却没有对应的受众权限,预检响应的CORS头是正常的,可返回403状态码的实际响应里却没有CORS头,导致前端跨域报错。

我之前碰到过类似的情况,给你几个可行的解决思路:

  • 调整Keycloak适配器的CORS配置,覆盖错误场景的头设置
    先检查你的Keycloak配置文件(比如keycloak.json或者Spring Boot项目里的application.properties/yaml),确保已经明确开启并配置CORS参数:
    比如在keycloak.json里可以这么写:

    {
      "cors": true,
      "allowedOrigins": ["https://你的前端实际域名"],
      "allowedMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
      "allowedHeaders": ["Authorization", "Content-Type"]
    }
    

    有些旧版本的适配器默认只会在请求成功处理后添加CORS头,明确配置这些参数后,大概率能让适配器在返回403这类错误响应时,也自动带上CORS头。

  • 自定义一个优先级更高的CORS过滤器
    如果适配器本身的逻辑有缺陷,那我们可以自己写一个Jakarta Servlet过滤器,把它放在Keycloak过滤器的前面执行——这样不管请求最后是成功还是返回错误,这个过滤器都能先给响应加上CORS头。
    给你个简单的过滤器示例:

    @WebFilter(urlPatterns = "/*")
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class CustomCorsFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            // 替换成你的前端域名,或者动态获取请求头里的Origin
            httpResponse.setHeader("Access-Control-Allow-Origin", "https://你的前端实际域名");
            httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            httpResponse.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
            httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
            
            // 处理预检请求直接返回200
            if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
                httpResponse.setStatus(HttpServletResponse.SC_OK);
                return;
            }
            
            chain.doFilter(request, response);
        }
    }
    

    重点是要让这个过滤器的优先级比Keycloak的过滤器高,比如用@Order(Ordered.HIGHEST_PRECEDENCE)标记,确保它先执行,把CORS头提前加上。

  • 升级Keycloak适配器版本
    这个问题有可能是适配器的版本bug导致的——比如某些旧版的Jakarta适配器在处理授权失败(比如受众不匹配)的场景时,没有走CORS头的添加逻辑。你可以尝试把keycloak-jakarta-servlet-filter-adapter升级到最新的稳定版,看看官方有没有修复这个小问题。

备注:内容来源于stack exchange,提问作者Calcimicium

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:14:34