Keycloak 24.x Docker容器Kerberos校验和失败问题求助
Keycloak 24.x Docker容器Kerberos配置问题排查
问题描述
已完成以下Kerberos配置操作:
- 构建自定义Docker镜像,安装
krb5-workstation - 在Docker Swarm中挂载有效的
/etc/krb5.conf
但配置完成后,Keycloak持续抛出以下错误:
Debug is true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /var/kerberos/keycloak/keycloak.keytab_AES refreshKrb5Config is false principal is HTTP/keycloak.contoso.net@CONTOSO.NET tryFirstPass is false useFirstPass is false storePass is false clearPass is false principal is HTTP/keycloak.contoso.net@CONTOSO.NET Will use keytab Commit Succeeded 2024-06-11 00:00:07,379 WARN [org.keycloak.federation.kerberos.impl.SPNEGOAuthenticator] (executor-thread-1) SPNEGO login failed: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed) at java.base/java.security.AccessController.doPrivileged(AccessController.java:716) [...] at java.base/java.lang.Thread.run(Thread.java:840) Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed) at java.security.jgss/sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:864) [...] at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) ... 25 more Caused by: KrbException: Checksum failed at java.security.jgss/sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:102) [...] at java.security.jgss/sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:837) ... 35 more Caused by: java.security.GeneralSecurityException: Checksum failed [...] at java.security.jgss/sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType.decrypt(Aes256CtsHmacSha1EType.java:100) ... 41 more [Krb5LoginModule]: Entering logout [Krb5LoginModule]: logged out Subject 2024-06-11 00:00:07,385 WARN [org.keycloak.authentication.authenticators.browser.SpnegoAuthenticator] (executor-thread-1) Received kerberos token, but there is no user storage provider that handles kerberos credentials.
已完成的验证(均成功)
- 使用
kinit和klist验证keytab有效性:
bash-5.1$ kinit -v -k -t /var/kerberos/keycloak/keycloak.keytab_AES HTTP/keycloak.contoso.net@CONTOSO.NET bash-5.1$ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: HTTP/keycloak.contoso.net@CONTOSO.NET Valid starting Expires Service principal 06/11/2024 00:14:47 06/11/2024 10:14:47 krbtgt/CONTOSO.NET@CONTOSO.NET renew until 06/18/2024 00:14:47
- 使用模拟Keycloak参数的Java测试代码验证登录成功:
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; import javax.security.auth.Subject; import com.sun.security.auth.module.Krb5LoginModule; /** * This is simple Java program that tests ability to authenticate * with Kerberos using the JDK implementation. * * The program uses no libraries but JDK itself. */ public class Krb { private void loginImpl(final String propertiesFileName) throws Exception { System.out.println("NB: system property to specify the krb5 config: [java.security.krb5.conf]"); //System.setProperty("java.security.krb5.conf", "/etc/krb5.conf"); System.out.println(System.getProperty("java.version")); System.setProperty("sun.security.krb5.debug", "true"); final Subject subject = new Subject(); final Krb5LoginModule krb5LoginModule = new Krb5LoginModule(); final Map<String,String> optionMap = new HashMap<String,String>(); if (propertiesFileName == null) { //optionMap.put("ticketCache", null); optionMap.put("keyTab", "/var/kerberos/keycloak/keycloak.keytab_AES"); optionMap.put("principal", "HTTP/keycloak.contoso.net@CONTOSO.NET"); // default realm optionMap.put("doNotPrompt", "true"); optionMap.put("refreshKrb5Config", "false"); optionMap.put("useTicketCache", "false"); optionMap.put("renewTGT", "false"); optionMap.put("useKeyTab", "true"); optionMap.put("storeKey", "true"); optionMap.put("isInitiator", "false"); optionMap.put("tryFirstPass", "false"); optionMap.put("useFirstPass", "false"); optionMap.put("storePass", "false"); optionMap.put("clearPass", "false"); } else { File f = new File(propertiesFileName); System.out.println("======= loading property file ["+f.getAbsolutePath()+"]"); Properties p = new Properties(); InputStream is = new FileInputStream(f); try { p.load(is); } finally { is.close(); } optionMap.putAll((Map)p); } optionMap.put("debug", "true"); // switch on debug of the Java implementation krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap); boolean loginOk = krb5LoginModule.login(); System.out.println("======= login: " + loginOk); boolean commitOk = krb5LoginModule.commit(); System.out.println("======= commit: " + commitOk); System.out.println("======= Subject: " + subject); } public static void main(String[] args) throws Exception { System.out.println("A property file with the login context can be specified as the 1st and the only parameter."); final Krb krb = new Krb(); krb.loginImpl(args.length == 0 ? null : args[0]); } }
运行结果:
[...] ======= login: true Commit Succeeded ======= commit: true ======= Subject: Subject: Principal: HTTP/keycloak.contoso.net@CONTOSO.NET Private Credential: /var/kerberos/keycloak/keycloak.keytab_AES for HTTP/keycloak.contoso.net@CONTOSO.NET
排查解决方案
1. 对齐JDK版本与加密策略
Keycloak容器内的JDK可能和测试用的JDK版本不一致,尤其是AES256加密的JCE策略限制。执行以下命令检查容器内JDK版本:
docker exec <your-keycloak-container-id> java -version
确保版本与测试环境一致,Java 9+默认启用无限制加密策略,Java 8及以下版本需确认已安装对应策略文件。
2. 核对Keycloak Kerberos配置参数
检查Keycloak的Kerberos配置(控制台Realm设置或keycloak.conf文件),确保:
principal严格匹配HTTP/keycloak.contoso.net@CONTOSO.NETkeytab路径正确指向/var/kerberos/keycloak/keycloak.keytab_AESuse-ticket-cache设为falsestore-key设为true
3. 检查Keycloak运行用户的keytab权限
Keycloak默认以keycloak用户运行,确认该用户对keytab文件有读取权限:
docker exec <your-keycloak-container-id> ls -l /var/kerberos/keycloak/keycloak.keytab_AES docker exec <your-keycloak-container-id> id keycloak
如果权限不足,执行以下命令调整:
docker exec <your-keycloak-container-id> chown keycloak:keycloak /var/kerberos/keycloak/keycloak.keytab_AES docker exec <your-keycloak-container-id> chmod 600 /var/kerberos/keycloak/keycloak.keytab_AES
4. 确认Kerberos加密类型匹配
错误提示AES256校验和失败,需确保KDC为该SPN颁发的令牌加密类型与keytab支持的一致。在KDC端检查SPN的加密类型配置,确保包含aes256-cts-hmac-sha1-96,同时Keycloak的JDK支持该加密算法。
5. 配置Kerberos用户存储提供商
日志中的警告说明缺少对应的用户存储配置:
- 登录Keycloak控制台,进入目标Realm → 用户存储 → 添加Kerberos用户存储
- 配置Kerberos用户存储参数,关联到对应的LDAP/Active Directory后端(如果使用AD集成),确保与SPNEGO配置的Realm、Principal等参数匹配。
内容的提问来源于stack exchange,提问作者Arnaud F.
相关产品推荐
相关产品推荐

