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

JSF应用集成Keycloak认证失败求助(附配置代码)

JSF应用集成Keycloak认证失败问题

Keycloak登录成功后跳转回JSF应用,应用未完成认证,无法进入门户。直接访问http://localhost:8080/myapp/callback时,org.pac4j.oidc.profile.creator.OidcProfileCreator.create()抛出空指针异常,原因是getIdToken()返回null。使用Keycloak 22版本。

配置信息

pom.xml

<pac4jVersion>5.7.0</pac4jVersion>
<bujiVersion>8.0.0</bujiVersion>
<jeePac4jVersion>7.1.0</jeePac4jVersion>

<dependency>
    <groupId>io.buji</groupId>
    <artifactId>buji-pac4j</artifactId>
    <version>${bujiVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>javaee-pac4j</artifactId>
    <version>${jeePac4jVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-javaee</artifactId>
    <version>${pac4jVersion}</version>
</dependency>
<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-core</artifactId>
    <version>${pac4jVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-cas</artifactId>
    <version>${pac4jVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-saml</artifactId>
    <version>${pac4jVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-oidc</artifactId>
    <version>${pac4jVersion}</version>
</dependency>

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-http</artifactId>
    <version>${pac4jVersion}</version>
</dependency>

shiro.ini

[main]

#Keycloack
oidcConfig = org.pac4j.oidc.config.OidcConfiguration
oidcConfig.discoveryURI = http://localhost:9009/auth/realms/myapp/.well-known/openid-configuration
oidcConfig.clientId = myapp-frontend
oidcConfig.secret = UMS5aWN4bnJ5Q0ZlOpEdn1tWcHlbx7H0
oidcConfig.clientAuthenticationMethodAsString = client_secret_basic
#oidcConfig.scope = openid
#oidcConfig.useNonce = true
#oidcConfig.responseType = code
oidcConfig.withState = false
oidcConfig.logoutUrl = http://localhost:9009/auth/realms/myapp/protocol/openid-connect/logout

oidcClient = org.pac4j.oidc.client.OidcClient
oidcClient.configuration = $oidcConfig

clients = org.pac4j.core.client.Clients
clients.callbackUrl = http://localhost:8080/myapp/callback
clients.clients = $oidcClient

pac4jRealm = io.buji.pac4j.realm.Pac4jRealm
pac4jRealm.principalNameAttribute = preferred_username

pac4jSubjectFactory = io.buji.pac4j.subject.Pac4jSubjectFactory
securityManager.subjectFactory = $pac4jSubjectFactory

config = org.pac4j.core.config.Config
config.clients = $clients

oidcSecurityFilter = org.pac4j.jee.filter.SecurityFilter
oidcSecurityFilter.config = $config
oidcSecurityFilter.clients = $oidcClient

callbackFilter = org.pac4j.jee.filter.CallbackFilter
callbackFilter.defaultUrl = http://localhost:8080/myapp
callbackFilter.config = $config

ajaxRequestResolver = org.pac4j.core.http.ajax.DefaultAjaxRequestResolver
ajaxRequestResolver.addRedirectionUrlAsHeader = true
oidcClient.ajaxRequestResolver = $ajaxRequestResolver

#logoutFilter = io.buji.pac4j.filter.LogoutFilter
#logoutFilter.defaultUrl = http://localhost:8080/myapp
#logoutFilter.localLogout = true
#logoutFilter.centralLogout = true
#logoutFilter.config = $config


# AuthStrategy
securityManager.realms = $pac4jRealm


# Using default form based security filter org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
authc.loginUrl = /common/login.jsf
authc.successUrl = /portal/dashboard.jsf


# Redirect to an access denied page if user does not have access rights
#[roles]
#roles.unauthorizedUrl = /common/access-denied.jsf
#perms.unauthorizedUrl = /accessdenied.jsp

anyofpermission = de.dpunkt.myaktion.util.CustomPermissionsAuthorizationFilter

# Protected URLs
[urls]
/callback = callbackFilter

## NO_SECURITY (Rendering)
#/portal/reporting/execution/** = authc, anon



## OTHER
/WEB-INF/layout/portal/** = authc
/portal/** = authc
/admin/** = authc
/community/** = authc

排查方向与解决方案

  1. 恢复OIDC核心配置项
    注释掉的几个关键参数是获取ID Token的必要条件,取消注释:

    • oidcConfig.scope = openid:openid是OIDC认证的必填scope,缺少它Keycloak不会返回ID Token
    • oidcConfig.responseType = code:授权码模式是标准流程,确保回调时能正确交换token
    • oidcConfig.useNonce = true:Nonce用于防止重放攻击,Keycloak默认要求验证该参数
  2. 检查Keycloak客户端配置

    • 确保客户端Access Type设置为confidential,匹配你使用的client_secret_basic认证方式
    • 确认Valid Redirect URIs包含http://localhost:8080/myapp/callback,路径和端口必须完全匹配
    • 检查Base URL是否设置为http://localhost:8080/myapp/,避免回调路径解析错误
  3. 调整Shiro过滤器链
    当前受保护路径使用的authc是Shiro表单认证过滤器,需替换为oidcSecurityFilter触发Keycloak认证,修改[urls]部分:

    /portal/** = oidcSecurityFilter
    /admin/** = oidcSecurityFilter
    /community/** = oidcSecurityFilter
    /callback = callbackFilter
    /common/login.jsf = anon
    

    同时移除原authc相关配置,避免冲突。

  4. 版本兼容性检查
    pac4j 5.7.0与Keycloak 22可能存在兼容性问题,尝试升级pac4j到最新稳定版(如5.9.0),同步升级buji-pac4j到对应适配版本,确保所有pac4j依赖版本一致。

  5. 日志排查
    开启pac4j和Keycloak的DEBUG日志,重点查看:

    • 回调请求的code、state等参数是否完整
    • token交换请求的响应是否返回id_token和access_token

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 10:09:51