我正在使用jTDS连接到SQLServer。内部jTDS使用GSS获得kerberos'服务票证并建立安全的上下文。由于我的应用程序是长寿的,我的连接一直保持活着,我需要kerberos'服务票证可以更新,以便允许SQL服务器自行续订(kdc策略设置为在12小时后使所有票证到期)。
获取kerberos令牌的jTDS所做的是(或多或少)以下内容:
GSSManager manager = GSSManager.getInstance();
// Oids for Kerberos5
Oid mech = new Oid("1.2.840.113554.1.2.2");
Oid nameType = new Oid("1.2.840.113554.1.2.2.1");
// Canonicalize hostname to create SPN like MIT Kerberos does
GSSName serverName = manager.createName("MSSQLSvc/" + host + ":" + port, nameType);
GSSContext gssContext = manager.createContext(serverName, mech, null, GSSContext.DEFAULT_LIFETIME);
gssContext.requestMutualAuth(false);
gssContext.requestCredDeleg(true);
byte[] ticket = gssContext.initSecContext(new byte[0], 0, 0);
我怀疑我获得的机票不可更新。我正在通过执行以下操作来检查:
ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext;
boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS);
System.out.println("Renewable = " + flags[8]);
在我们的特定配置中,GSS从JAAS登录模块获取kerberos TGT。我们将以下变量设置为false -Djavax.security.auth.useSubjectCredsOnly=false
,并在login.cfg文件中配置以下登录模块:
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
useKeytTab=true
keyTab="/home/batman/.batman.ktab"
principal="batman@GOTHAMCITY.INT"
storeKey=true
doNotPrompt=true
debug=false
};
我注意到的另一件事是getLifetime()
的{{1}}方法似乎无效。无论故障单的实际生命周期是什么,它总是返回2147483647(max int)。
我对分支jTDS驱动程序感到很舒服,因此我可以根据需要修改它建立GSS上下文的方式。
我尝试了什么:
使用GSS api的原生实现:
在获取可更新票证方面,这对我来说很好,但它会产生另一组问题(在确保正确设置票证缓存和正确续订票证方面)。如果我可以绕过这个选项那就太好了。我在这里看到的一件事是GSSContext
方法实际上返回了票证的实际生命周期。
重新实现KerberosLoginModule:
基于此问题的答案Jaas - Requesting Renewable Kerberos Tickets我重新实现了LoginModule,以便在请求TGT之前在getLifetime()
中设置RENEW KDCOption
。从我获得可再生TGT的意义上来说这很好,但GSS从TGT获得的机票仍然不可再生。如果我在KDCOption对象的构造函数中设置一个断点并在每个请求上手动设置RENEW标志(即使是GSS完成的KrbAsReqBuilder
)它也能正常工作,但是要使这个变化有效,需要对GSS进行重大改写,我不会# 39;感觉很舒服。
答案 0 :(得分:1)
对于管理员来说,Kerberos票证具有生命周期这一事实是一项重要的安全功能。用户知道密码,因此他/她可以随时获得新票。但是对于入侵者来说这是一个问题 - 在票证到期后,它不能用于进入系统。管理员希望这个生命周期尽可能短,但不要太短(比如1小时),因为用户生成的登录请求比现在多10倍,而且ActiveDirectory很难处理。
当我们需要使用Kerberos进行身份验证时,我们应该使用连接池(和DataSource)。要在jTDS中使用此功能,您需要添加ConnectionPoolImplementation(建议:DBCP或c3p0,请参阅:http://jtds.sourceforge.net/features.html)。
如果您想使用较旧的连接数据库的方式编写应用程序(没有数据源,即创建连接并保持活动,因为创建它很昂贵......),那么下一个障碍就是“更新生命周期”。在ActiveDirectory中,默认情况下,Kerberos票证可在7天内续订。 AD中有一个全局设置允许设置为0(无限期更新生命周期),但是你需要说服域管理员降低整个域的安全性,因为一个服务在没有它的情况下就不会运行。