Alfresco Share Kerberos SSO运行10小时后失效:凭据无法委派
我们在Docker部署的Alfresco Community 7.3中配置了Kerberos SSO,初始运行正常——Windows域用户无需输入凭据即可直接访问Alfresco Share。但运行10小时(AD默认票据生命周期)后,Share的SSO失效,Kerberos票据无法续期,日志出现警告:
WARN [site.servlet.KerberosSessionSetupPrivilegedAction] [http-nio-8080-exec-2] credentials can not be delegated!
注意:Alfresco API(如/alfresco/api/-default-/public/alfresco/versions/1/people/-me-)在10小时后仍可正常使用SSO,票据能正常续期,仅Share的SSO失效。重启Share后,SSO恢复正常,可再次运行10小时。
Alfresco Share 关键日志
(真实域名替换为DOMAIN.LOCAL,真实用户替换为username,真实主体替换为host.domain.local@DOMAIN.LOCAL)
Found KeyTab /etc/alfresco.keytab for HTTP/host.domain.local@DOMAIN.LOCAL Found ticket for HTTP/host.domain.local@DOMAIN.LOCAL to go to krbtgt/DOMAIN.LOCAL@DOMAIN.LOCAL expiring on Mon Dec 02 20:53:26 CET 2024 Removed and destroyed the expired Ticket Destroyed KerberosTicket Found ticket for username@DOMAIN.LOCAL to go to HTTP/host.domain.local@DOMAIN.LOCAL expiring on Mon Dec 02 20:53:26 CET 2024 Removed and destroyed the expired Ticket Destroyed KerberosTicket Entered Krb5Context.acceptSecContext with state=STATE_NEW Looking for keys for: HTTP/host.domain.local@DOMAIN.LOCAL Added key: 18, version: 14 >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType default etypes for permitted_enctypes: 18. >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType MemoryCache: add 1733214106/000040/337274E60DE6EBB25D556DFE9379D79E49896CA751E2E9E323D7E6E85615F44E/username@DOMAIN.LOCAL to username@DOMAIN.LOCAL|HTTP/host.domain.local@DOMAIN.LOCAL >>> KrbApReq: authenticate succeed. Krb5Context setting peerSeqNumber to: 1696515610 >>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType Krb5Context setting mySeqNumber to: 805644649 >>> Constrained deleg from GSSCaller{UNKNOWN} 2024-12-03T09:22:04,007 [] WARN [site.servlet.KerberosSessionSetupPrivilegedAction] [http-nio-8080-exec-2] credentials can not be delegated!
环境配置
- AD/DC:Windows Server 2019
- 客户端:Windows 10
- Alfresco服务器:宿主机Ubuntu 24.04,Docker部署Alfresco 7.4 CE,JDK版本OpenJDK 17.0.6
核心配置文件
alfresco-global.properties
# Configuration of authentication chain authentication.chain=kerberos1:kerberos,alfinst:alfrescoNtlm,ldap1:ldap-ad # Kerberos configuration kerberos.authentication.realm=DOMAIN.LOCAL kerberos.authentication.sso.enabled=true kerberos.authentication.user.configEntryName=Alfrecso kerberos.authentication.defaultAdministratorUserNames=Administrator,admin kerberos.authentication.cifs.enabled=false kerberos.authentication.http.configEntryName=AlfrescoHTTP kerberos.authentication.http.password=secret kerberos.authentication.http.allowGuest=false kerberos.authentication.http.allowed.useragents=.*
krb5.conf
[libdefaults] default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 default_realm = DOMAIN.LOCAL dns_lookup_realm = false dns_lookup_kdc = true [realms] DOMAIN.LOCAL = { kdc = ad.server.address admin_server = ad.server.address } [domain_realm] .domain.local = DOMAIN.LOCAL domain.local = DOMAIN.LOCAL
jaas.config(ACS)
Alfresco { com.sun.security.auth.module.Krb5LoginModule sufficient; }; AlfrescoHTTP { com.sun.security.auth.module.Krb5LoginModule required storeKey=true useKeyTab=true doNotPrompt=true keyTab="/etc/alfresco.keytab" principal="HTTP/host.domain.local@DOMAIN.LOCAL"; }; com.sun.net.ssl.client { com.sun.security.auth.module.Krb5LoginModule sufficient; }; other { com.sun.security.auth.module.Krb5LoginModule sufficient; };
jaas.config(Share)
Alfresco { com.sun.security.auth.module.Krb5LoginModule sufficient; }; ShareHTTP { com.sun.security.auth.module.Krb5LoginModule required storeKey=true useKeyTab=true doNotPrompt=true keyTab="/etc/alfresco.keytab" principal="HTTP/host.domain.local@DOMAIN.LOCAL"; }; com.sun.net.ssl.client { com.sun.security.auth.module.Krb5LoginModule sufficient; }; other { com.sun.security.auth.module.Krb5LoginModule sufficient; };
share-config-custom.xml
<!-- Kerberos settings --> <!-- To enable kerberos rename this condition to "Kerberos" --> <config evaluator="string-compare" condition="Kerberos" replace="true"> <kerberos> <password>secret</password> <realm>DOMAIN.LOCAL</realm> <endpoint-spn>HTTP/host.domain.local@DOMAIN.LOCAL</endpoint-spn> <config-entry>ShareHTTP</config-entry> <stripUserNameSuffix>true</stripUserNameSuffix> </kerberos> </config>
已尝试操作
- 修改AD/DC及域组策略
- 测试Stack Overflow、Alfresco论坛提供的多种解决方案
解决思路
校验Kerberos委托权限
- 确认AD中
HTTP/host.domain.local服务账户的委托配置:需启用允许委派任何服务(或针对Alfresco服务的约束性委派),且未勾选敏感账户,不能被委派。 - 检查Windows客户端组策略,确保允许向该SPN委派票据。
- 确认AD中
调整Share会话缓存与认证逻辑
- 在Share的JVM参数中添加
-Djavax.security.auth.useSubjectCredsOnly=false,强制重新触发Kerberos认证而非复用缓存凭据。 - 检查Share的会话超时配置,确认超时后是否会重新发起Kerberos协商。
- 在Share的JVM参数中添加
统一JAAS与Keytab配置
- 确保Share的
ShareHTTPJAAS条目与ACS的AlfrescoHTTP参数完全一致,包括storeKey、useKeyTab等关键属性。 - 验证Share容器内keytab文件权限(需为运行Share的用户可读),并使用
ktutil确认keytab包含有效密钥。
- 确保Share的
排查JDK Kerberos兼容性
- OpenJDK 17的Kerberos实现可能存在续期逻辑问题,可尝试降级至Alfresco官方支持的JDK 11测试,或添加JVM参数
-Dsun.security.krb5.debug=true获取详细调试日志。
- OpenJDK 17的Kerberos实现可能存在续期逻辑问题,可尝试降级至Alfresco官方支持的JDK 11测试,或添加JVM参数
启用Kerberos调试日志
- 在Share的启动参数中添加
-Dsun.security.krb5.debug=true,重点观察票据续期阶段的错误细节,定位具体失败节点。
- 在Share的启动参数中添加
内容的提问来源于stack exchange,提问作者David Dejmal
相关产品推荐
相关产品推荐

