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

Keycloak会话过期后JSF AJAX请求出现CORS问题求助

Keycloak 20.0.1 + WildFly 26 JSF AJAX会话过期CORS问题解决方案

问题根源

会话过期后,Keycloak OIDC适配器在Undertow底层直接触发302重定向至登录页,自定义CORS过滤器还未执行就被拦截,导致跨域请求无法获取Access-Control-Allow-Origin响应头,浏览器抛出CORS错误;而预期应返回401状态码让前端处理全页重定向。


具体解决方案

1. 配置Keycloak OIDC适配器,让AJAX请求返回401而非302

修改应用WAR包中WEB-INF/oidc.json,添加AJAX请求识别配置,让适配器对AJAX请求返回401:

{
  "realm": "你的Realm名称",
  "auth-server-url": "https://你的Keycloak地址/auth",
  "ssl-required": "external",
  "resource": "你的客户端ID",
  "credentials": {
    "secret": "你的客户端密钥"
  },
  "ajaxRequestCheckMethod": "HEADER",
  "bearerOnly": false,
  "enableBasicAuth": false,
  "exposeToken": true,
  "verify-token-audience": true,
  "use-resource-role-mappings": true,
  "confidential-port": 0
}

该配置会让适配器检查请求头(如X-Requested-With: XMLHttpRequest),识别AJAX请求后返回401而非302。

2. 调整WildFly Undertow过滤器,确保错误响应带CORS头

修改WildFly的standalone.xml/domain.xml,让CORS过滤器覆盖所有请求(包括错误响应):

<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host">
  <server name="default-server">
    <http-listener name="default" socket-binding="http" redirect-socket="https"/>
    <host name="default-host" alias="localhost">
      <location name="/" handler="welcome-content"/>
      <!-- 让所有请求(含错误响应)经过CORS过滤器 -->
      <filter-ref name="cors-filter" predicate="true"/>
    </host>
  </server>
  <filters>
    <filter name="cors-filter" class-name="io.undertow.servlet.handlers.security.CorsFilter" module="io.undertow.servlet">
      <param name="allowedOrigins" value="*"/>
      <param name="allowedMethods" value="GET, POST, HEAD, OPTIONS, PUT, DELETE"/>
      <param name="allowedHeaders" value="Origin, Accept, X-Requested-With, Content-Type, Authorization"/>
      <param name="exposedHeaders" value="Access-Control-Allow-Origin, Access-Control-Allow-Credentials"/>
      <param name="allowCredentials" value="true"/>
      <param name="maxAge" value="120"/>
    </filter>
  </filters>
</subsystem>

3. 前端处理401响应,触发全页重定向

在JSF页面中添加全局AJAX错误处理,捕获401状态码后跳转至登录页:

$(document).ajaxError(function(event, xhr) {
  if (xhr.status === 401) {
    window.location.href = '/你的应用上下文/login';
  }
});

也可通过JSF原生的<f:ajax onerror="handleAjaxError(event)" />实现全局错误处理。

4. 验证EAR打包与WildFly配置

  • 确保WAR包的WEB-INF/oidc.json路径正确,EAR的application.xml正确包含WAR模块;
  • 若使用WildFly Keycloak子系统,可在standalone.xml中集中配置客户端,替代WAR内的oidc.json:
<subsystem xmlns="urn:jboss:domain:keycloak:12.0">
  <secure-deployment name="你的应用.war">
    <realm>你的Realm名称</realm>
    <auth-server-url>https://你的Keycloak地址/auth</auth-server-url>
    <ssl-required>external</ssl-required>
    <resource>你的客户端ID</resource>
    <credential name="secret">你的客户端密钥</credential>
    <ajax-request-check-method>HEADER</ajax-request-check-method>
  </secure-deployment>
</subsystem>

5. 确认Keycloak客户端配置

  • 确保客户端的Valid Redirect URIs配置正确,匹配应用跳转路径;
  • 检查Advanced Settings中Access Type为confidential,Web Origins保持为*,且允许X-Requested-With请求头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:26:01