如何通过Waffle复用Windows Kerberos票据缓存并查询令牌有效期?
问题解答
是否可以借助Windows缓存保存/获取Kerberos令牌?
可以。Waffle底层依赖Windows的SSPI(安全支持提供程序接口),而SSPI本身会自动缓存Kerberos令牌,你当前的WindowsSecurityContextImpl.getCurrent()调用其实已经在复用Windows缓存里的有效令牌——只有当缓存令牌过期、失效,或者目标SPN变更时,才会重新向KDC申请新令牌,不需要你手动实现缓存逻辑。
需要注意:
- 缓存基于当前登录用户的安全上下文,不同用户的令牌相互隔离。
- 除非是跨用户上下文复用令牌的特殊场景,否则没必要手动缓存,还可能带来安全风险。
如何查询令牌的有效期?
Waffle的IWindowsSecurityContext接口没有直接暴露有效期字段,但可以通过SSPI的底层API获取。借助Waffle自带的JNA封装,调用QueryContextAttributes方法就能拿到令牌过期时间。
Groovy实现示例
import waffle.windows.auth.impl.WindowsSecurityContextImpl import com.sun.jna.platform.win32.Sspi import com.sun.jna.platform.win32.Sspi.CtxtHandle import com.sun.jna.platform.win32.Sspi.SecPkgContext_Expiry String securityPackage = 'Negotiate' String spnTarget = 'HTTP/dummy.serve' WindowsSecurityContextImpl ctx = (WindowsSecurityContextImpl) WindowsSecurityContextImpl.getCurrent(securityPackage, spnTarget) // 获取底层SSPI上下文句柄 CtxtHandle contextHandle = ctx.getHandle() Sspi sspi = Sspi.INSTANCE SecPkgContext_Expiry expiry = new SecPkgContext_Expiry() // 查询令牌过期属性 int result = sspi.QueryContextAttributes(contextHandle, Sspi.SECPKG_ATTR_EXPIRY, expiry) if (result == 0) { // 0代表调用成功 // Windows文件时间转Java Date(1601年1月1日起的100纳秒间隔数) Date expiryDate = new Date(expiry.ExpiryTime.longValue()) println "令牌过期时间: ${expiryDate}" } else { println "查询有效期失败,错误码: ${result}" } // 原有令牌使用逻辑不变 byte[] token = ctx.getToken() String token64 = Base64.getEncoder().encodeToString(token)
说明
- 代码依赖Waffle自带的JNA库,无需额外引入依赖。
- 若手动缓存令牌,必须严格校验有效期,避免用过期令牌导致认证失败。
内容的提问来源于stack exchange,提问作者Madgui
相关产品推荐
相关产品推荐

