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

Apache Zeppelin集成Keycloak后AJAX请求空指针及PKCE验证失败

解决方案:Apache Zeppelin 0.11.1 + Keycloak 集成的PKCE验证失败与AJAX空指针问题

针对你遇到的两个核心问题(PKCE验证失败、AJAX请求空指针),结合使用的依赖版本(pac4j 5.7.6、buji-pac4j 8.1.0、Shiro 1.10.0),给出以下具体排查和修复步骤:


一、解决PKCE验证失败(invalid_grant)问题

1. 检查Keycloak客户端配置

  • 进入对应客户端的Settings页面,确认:
    • Access Type设置为confidential(Zeppelin作为服务端应用,需使用此类型配合PKCE);
    • Proof Key for Code Exchange Code Challenge Method设置为S256(若开启此选项,pac4j必须使用相同算法生成挑战值)。

2. 修正pac4j OIDC客户端配置

在OidcClient初始化代码中明确开启PKCE并指定算法:

OidcClient oidcClient = new OidcClient();
// 开启PKCE支持
oidcClient.setUsePkce(true);
// 匹配Keycloak配置的算法
oidcClient.setCodeChallengeMethod("S256");
// 其他配置(如client ID、secret、Keycloak issuer URL)...

3. 确保会话存储同步

buji-pac4j依赖Shiro会话存储PKCE的code_challenge和code_verifier,需确认:

  • Zeppelin的Shiro会话配置正确,session ID在AJAX请求中正常携带(检查请求Cookie是否包含Shiro的session ID);
  • 避免会话过期时间过短,导致回调时会话中已丢失PKCE参数。

二、解决DefaultAjaxRequestResolver空指针问题

1. 自定义AJAX请求解析器

DefaultAjaxRequestResolver在识别非标准AJAX请求时会返回null,导致空指针。针对Zeppelin的/api/前缀请求,自定义解析器避免返回null:

public class ZeppelinAjaxResolver extends DefaultAjaxRequestResolver {
    @Override
    public AjaxResponse buildAjaxResponse(WebContext context, String url) {
        // 对Zeppelin API路径强制返回非null响应
        if (context.getRequestPath().startsWith("/api/")) {
            return new AjaxResponse(url, false);
        }
        AjaxResponse response = super.buildAjaxResponse(context, url);
        return response != null ? response : new AjaxResponse(url, false);
    }

    @Override
    public boolean isAjax(WebContext context) {
        // 兼容Zeppelin可能的自定义AJAX标识Header
        boolean standardAjax = super.isAjax(context);
        String zeppelinAjaxHeader = context.getRequestHeader("X-Zeppelin-Ajax");
        return standardAjax || "true".equals(zeppelinAjaxHeader);
    }
}

然后在pac4j全局配置中替换默认解析器:

Config config = new Config(oidcClient);
config.setAjaxRequestResolver(new ZeppelinAjaxResolver());

2. 调整API路径的安全过滤规则

确保/api/路径的请求不会触发OIDC重定向(AJAX无法处理重定向),在SecurityFilter配置中添加:

SecurityFilter filter = new SecurityFilter();
filter.setConfig(config);
filter.setClients("OidcClient");
// 允许AJAX请求直接处理,不跳转登录页
filter.setAllowAjaxRequests(true);
// 针对/api/路径设置授权规则
filter.setMatchers(new PathMatcher().include("/api/**"));

三、版本兼容性与日志调试

1. 版本验证

当前依赖版本组合(pac4j 5.7.6 + buji-pac4j 8.1.0 + Shiro 1.10.0)是兼容的,可尝试升级pac4j到5.x最新版(如5.7.10),修复已知的PKCE或AJAX处理bug。

2. 开启调试日志

在Zeppelin的日志配置中添加:

log4j.logger.org.pac4j.core=DEBUG
log4j.logger.org.pac4j.oidc=DEBUG
log4j.logger.io.buji.pac4j=DEBUG

通过日志查看:

  • PKCE参数(code_challenge/code_verifier)是否在会话中正确存储;
  • AJAX请求的识别逻辑是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:28:29