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
相关产品推荐
相关产品推荐

