2015-04-13 21 views
5

Ich verwende jTDS, um eine Verbindung zu SQLServer. Intern verwendet jTDS GSS, um ein Kerberos-Serviceticket zu erhalten und einen sicheren Kontext einzurichten. Da meine App langlebig ist und meine Verbindungen die ganze Zeit über am Leben erhalten, muss das Serviceticket des Kerberos erneuerbar sein, damit der SQL Server sie selbst erneuern kann (die kdc-Richtlinien setzen alle Tickets nach 12 Stunden ab)).So erhalten Sie erneuerbare Kerberos-Tickets mit Java GSS + JAAS

Was jTDS macht einen Kerberos-Token zu erhalten ist (mehr oder weniger) die folgenden:

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); 

Was ich vermute, dass das Ticket ich den Erhalt nicht erneuerbar ist. Ich bin Überprüfung, dass durch so etwas wie die folgenden Aktionen ausführen:

ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext; 
boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS); 
System.out.println("Renewable = " + flags[8]); 

In unserer speziellen Konfiguration GSS ist kerberos TGT von JAAS Login-Modul zu bekommen. Wir haben die folgende Variable auf falsche -Djavax.security.auth.useSubjectCredsOnly=false und in der login.cfg Datei haben wir folgende Login-Modul konfiguriert:

com.sun.security.jgss.krb5.initiate { 
    com.sun.security.auth.module.Krb5LoginModule required 
     useKeytTab=true 
     keyTab="/home/batman/.batman.ktab" 
     principal="[email protected]" 
     storeKey=true 
     doNotPrompt=true 
     debug=false 
}; 

Eine andere Sache, die ich bemerken ist, dass die getLifetime() Methode der GSSContext nicht zu funktionieren scheint. Es gibt immer 2147483647 (max int) zurück, egal wie hoch die tatsächliche Lebensdauer des Tickets ist.

Ich fühle mich confortable mit verzweigenden jTDS-Treiber, so kann ich ändern, wie es einen GSS-Kontext bei Bedarf herstellt.

Was ich versucht:

Verwenden native Implementierung von GSS api:

Dies funktioniert gut für mich in Bezug auf erneuerbare Tickets zu erhalten, aber es imposesses eine weitere Reihe von Fragen (in Bezug auf die Gewährleistung dass der Ticket-Cache richtig eingestellt ist und die Tickets dort ordnungsgemäß erneuert werden). Wenn ich diese Option umgehen könnte, wäre es nett. Ich beobachte hier einmal, dass die Methode getLifetime() tatsächlich die tatsächliche Lebensdauer in Sekunden des Tickets zurückgibt.

Reimplementierung KerberosLoginModule:

auf die Antwort Basierend auf diese Frage Jaas - Requesting Renewable Kerberos Tickets ich Loginmodule neu implementiert die RENEW zu setzen KDCOption in KrbAsReqBuilder bevor ein TGT anfordern. Das funktioniert gut in dem Sinne, dass ich ein erneuerbares TGT erhalte, aber das Ticket, das von diesem TGT von GSS erhalten wird, ist immer noch nicht erneuerbar. Wenn ich im Konstruktor des KDCOption-Objekts einen Haltepunkt setze und das RENEW-Flag bei jeder Anforderung manuell anwähle (selbst die KrbTgsReq von GSS), funktioniert es, aber diese Änderung produktiv zu machen, erfordert eine wesentliche Neuschreibung auf GSS, mit der ich nicht vertraut bin .

Antwort

1

Für Administratoren ist die Tatsache, dass Kerberos-Tickets lebenslang gültig sind, ein wichtiges Sicherheitsmerkmal. Der Benutzer kennt ein Passwort, so dass er/sie jederzeit ein neues Ticket erhalten kann. Aber für Eindringlinge ist es ein Problem - nachdem das Ticket abgelaufen ist, kann es nicht verwendet werden, um in das System einzubrechen. Administratoren möchten, dass diese Lebensdauer so kurz wie möglich ist, aber nicht zu kurz (etwa 1 Stunde), da Benutzer etwa 10 Mal mehr Anmeldeanforderungen generieren würden als jetzt und ActiveDirectory damit schwer zu handhaben ist.

Wenn wir mit Kerberos authentifizieren müssen, sollten wir Verbindungspooling (und DataSource) verwenden. Um diese Funktion in jTDS zu verwenden, müssen Sie ConnectionPoolImplementation hinzufügen (empfohlen: DBCP oder c3p0, siehe: http://jtds.sourceforge.net/features.html).

Wenn Sie Ihre Anwendung schreiben möchten, indem Sie eine ältere Art der Verbindung zur Datenbank verwenden (ohne Datenquelle, dh eine Verbindung erstellen und am Leben erhalten, weil es teuer zu erstellen ist), dann wäre das nächste Hindernis "erneuere Lebensdauer" . In ActiveDirectory können Kerberos-Tickets standardmäßig innerhalb von 7 Tagen erneuert werden. Es gibt eine globale Einstellung in AD, die es erlaubt, dort 0 zu setzen (eine unbegrenzte Erneuerungslebensdauer), aber Sie müssten den Domain-Administrator dazu bringen, die Sicherheit der gesamten Domain zu reduzieren, nur weil ein Service nicht ohne diesen laufen würde.

+0

Danke! Wir verwenden einen Verbindungspool und wir setzen ihn so, dass unsere Verbindungen nach 6 Stunden ablaufen, so dass wir den Ablauf nicht erreichen. Ich stimme zu, dass es eine gute Übung und eine gute Problemumgehung meines Problems ist, aber in einigen Fällen kann ich diese Lösung nicht wählen. Ich verstehe, dass Tickets bis zu 7 Tagen verlängert werden können (unsere Konfiguration ist Standard in diesem Sinne), aber das ist in Ordnung für uns. Das Problem ist, dass die Tokens, die ich bekomme, nicht erneuerbar sind (sie haben das Erneuerungs-Flag auf "false" gesetzt), so dass sie nach 12 Stunden wertlos sind. – Claudio

+0

Ich gewährte diese Antwort mit der Bounty (die bald ablaufen würde). Es löst mein Problem nicht, aber vielleicht ist es hilfreich für jemand anderen. – Claudio