Sto usando jTDS per connettermi a SQLServer. JTDS internamente utilizza GSS per ottenere un ticket di servizio di kerberos e stabilire un contesto sicuro. Poiché la mia app è longeva e le mie connessioni sono mantenute in vita per tutto il tempo ho bisogno che il ticket di servizio di kerberos sia rinnovabile per consentire al server SQL di rinnovarle da solo (le politiche kdc sono impostate per scadere tutti i ticket dopo 12 ore).Come ottenere i biglietti di kerberos rinnovabili usando java GSS + JAAS
Cosa jTDS fa per ottenere un token Kerberos è (più o meno) i seguenti:
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);
Quello che ho il sospetto è che il biglietto io sto ottenendo non è rinnovabile. Sto controllando che facendo qualcosa di simile a quanto segue:
ExtendedGSSContext extendedContext = (ExtendedGSSContext) gssContext;
boolean[] flags = (boolean[]) extendedContext.inquireSecContext(InquireType.KRB5_GET_TKT_FLAGS);
System.out.println("Renewable = " + flags[8]);
Nella nostra particolare configurazione GSS sta ottenendo Kerberos TGT dal modulo di login JAAS. Abbiamo la seguente variabile impostata su false -Djavax.security.auth.useSubjectCredsOnly=false
e nel file login.cfg abbiamo la seguente modulo di login configurato:
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
};
Un'altra cosa che ho notato è che il metodo di GSSContext
getLifetime()
non sembra funzionare. Restituisce sempre 2147483647 (max int) indipendentemente dalla durata effettiva del ticket.
Mi sento a mio agio con il driver jTDS ramificato, così posso modificare il modo in cui stabilisce un contesto GSS se necessario.
Quello che ho cercato:
usare l'esecuzione nativa di GSS api:
Questo funziona bene per me in termini di ottenimento di biglietti rinnovabili ma imposesses un'altra serie di questioni (in termini di garanzia che la cache del ticket sia impostata correttamente e che i ticket siano correttamente rinnovati). Se riesco a bypassare questa opzione sarebbe bello. Una cosa che osservo qui è che il metodo getLifetime()
restituisce effettivamente la durata effettiva in secondi del ticket.
reimplementare KerberosLoginModule:
Sulla base della risposta a questa domanda ho Jaas - Requesting Renewable Kerberos Tickets reimplementato LoginModule per impostare la RENEW KDCOption
in KrbAsReqBuilder
prima di richiedere un TGT. Ciò funziona bene nel senso che ottengo un TGT rinnovabile, ma il ticket ottenuto da quel TGT da GSS non è ancora rinnovabile. Se imposto un breakpoint nel costruttore dell'oggetto KDCOption e imposta manualmente il flag RENEW su ogni richiesta (anche il KrbTgsReq
eseguito da GSS) funziona, ma rendere produttiva tale modifica richiede una riscrittura maggiore su GSS che non mi sento a mio agio con .
Grazie! Usiamo un pool di connessioni e lo impostiamo per scadere le nostre connessioni dopo 6 ore, quindi non stiamo raggiungendo la scadenza. Sono d'accordo che è una buona pratica e un buon workaround il mio problema, ma in alcuni casi non posso andare per quella soluzione. Capisco che i biglietti possono essere rinnovati fino a 7 giorni (la nostra configurazione è quella predefinita in tal senso) ma va bene per noi. Il problema è che i token che ottengo non sono rinnovabili (hanno la flag di rinnovo impostata su false) quindi dopo 12 ore sono inutili. – Claudio
Ho assegnato questa risposta con la taglia (che stava per scadere). Non risolve il mio problema ma forse è utile per qualcun altro. – Claudio