Sto provando a modificare un'applicazione dall'utilizzo di java7u51 a java8u40 ma l'autenticazione SSO non riesce. Il client non è cambiato, utilizza le chiamate Windows JNA (Secur32.INSTANCE.InitializeSecurityContext
) ma il server non accetta più il ticket. Il codice del server non è cambiato, ma sta utilizzando le librerie java standard che sembrano essere cambiate. Il server funziona sotto linux.Cambiamento autenticazione lato server Kerberos/SPNEGO in Java8
Il codice server è di seguito. Sul mio computer Windows scrivo un file contenente il ticket in modo da poter eseguire il codice sottostante per il test. Ho un altissimo clockskew impostato in modo da poter testare contro il biglietto. Ho scritto il ticket del cliente usando java7u51 per ogni evenienza, ma questo non ha aiutato. Lo stesso ticket funziona bene quando eseguo il codice del server sottostante in java7.
Il bit che non riesce è che isEstablished
restituisce falso. Non ci sono informazioni utili per il debug. isEstablished
restituendo false implica che sono necessari più cicli, ma quello non è il caso, e non penso che dovrebbe essere.
Qualcuno sa di un motivo che ora non funzionerebbe in java8? Non è solo un problema di aggiornamento 40, non funziona con le versioni precedenti di java 8.
grazie
Properties.setProp("sun.security.krb5.debug", "true")
Properties.setProp("java.security.krb5.realm", "xxxx")
Properties.setProp("java.security.krb5.kdc", "xxxx")
Properties.setProp("java.security.krb5.conf", url(getClass, "/krb5.conf.auth").toExternalForm)
Properties.setProp("java.security.auth.login.config", url(getClass, "/jaas.conf.auth").toExternalForm)
Properties.setProp("javax.security.auth.useSubjectCredsOnly", "true")
val loginCtx: LoginContext = new LoginContext("Server", new LoginCallbackHandler(password))
loginCtx.login()
val subject = loginCtx.getSubject
val ticket = StringIO.readStringFromFile(new File("/tmp/ticket"))
val decoder: BASE64Decoder = new BASE64Decoder
val serviceTicket = decoder.decodeBuffer(ticket)
val user = Subject.doAs(subject, new PrivilegedAction[Option[String]]() {
def run = {
try {
val manager = GSSManager.getInstance
val context: GSSContext = manager.createContext(null: GSSCredential)
val arrayOfBytes = context.acceptSecContext(serviceTicket, 0, serviceTicket.length)
// we ignore arrayOfBytes
assert(context.isEstablished, "Failed to establish context: " + context)
val username = context.getSrcName.toString
Some(username)
} catch {
case e: Exception =>
println("failed: " + e.getMessage)
None
}
}
})
krb5.conf.auth
[libdefaults]
default_realm = XXX
allow_weak_crypto=true
default_tkt_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
default_tgs_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
permitted_enctypes = rc4-hmac des-cbc-md5 des-cbc-crc des3-cbc-sha1
default_checksum = rsa-md5
kdc_timesync = 0
kdc_default_options = 0x40000010
clockskew = 30000
check_delegate = 0
ccache_type = 3
kdc_timeout = 60000
forwardable = true
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
#excluding realms and domain_realm
jaas.conf.auth (server section)
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=false
debug=true
isInitiator=false
storeKey=true
useTicketCache=false
principal="XXX";
};
Aggiornamento: Nel caso in cui questo aiuta. Penso che il client stia inviando un ticket SPNEGO, perché se provo a forzare il contesto ad accettare solo Kerberos (1.2.840.113554.1.2.2) ottengo l'errore failed: No credential found for: 1.3.6.1.5.5.2 usage: Accept
Update 2: Questa non è proprio la risposta , ma se cambio il modo in cui il client Windows crea il ticket funziona. Quindi se invece di creare un ticket incapsulato SPNEGO si crea un ticket solo Kerberos, esso viene accettato da Java8. Quindi modificare "Negozia" in "Kerberos" in basso risolve il problema.
Secur32.INSTANCE.AcquireCredentialsHandle(
servicePrincipalName,
"Negotiate", // Change to "Kerberos"
new NativeLong(Sspi.SECPKG_CRED_OUTBOUND),
null,
authIdentity.getPointer,
null,
null,
phClientCredential,
ptsClientExpiry)
Provare a utilizzare "NTLM" invece di "Negoziare" e dirmi se funziona. Ho avuto un problema simile. – kukis
java8 forse ha abbandonato il supporto per 'allow_weak_crypto = true'? –
Java 8 ha cambiato il valore predefinito di allow_weak_crypto in false, quindi non è possibile utilizzare DES a meno che non sia specificato esplicitamente come true: https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8 .html –