Sto lavorando a un'applicazione Web con SSO basata sull'accesso al dominio di Windows, per questo motivo ho scelto di convalidare i ticket Kerberos. Ma ora sto affrontando un problema per il quale non riesco a trovare una soluzione. Riesco a convalidare un ticket senza eccezioni, ma quando sto cercando di ottenere l'userName, viene generato NullPointerException
, perché il nome utente è null
e non so dove sia il problema.GSSContext con null SrcName
Perché il nome utente è nullo se non ottengo alcuna eccezione durante la convalida?
Come ottengo Nome utente: String clientName = gssContext.getSrcName().toString();
Creo il mio cliente sulla base di questo:
Using GSSManager to validate a Kerberos ticket
How to obtain a kerberos service ticket via GSS-API?
http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/single-signon.html
Aggiornamento 1:
Come contenuti di installazione, basta copiare e incollare modulo qui https://stackoverflow.com/a/25450862/1646082:
final Oid spnegoOid = new Oid("1.3.6.1.5.5.2");
GSSManager gssmgr = GSSManager.getInstance();
// tell the GSSManager the Kerberos name of the service
GSSName serviceName = gssmgr.createName(this.servicePrincipal, GSSName.NT_USER_NAME);
// get the service's credentials. note that this run() method was called by Subject.doAs(),
// so the service's credentials (Service Principal Name and password) are already
// available in the Subject
GSSCredential serviceCredentials = gssmgr.createCredential(serviceName,
GSSCredential.INDEFINITE_LIFETIME, spnegoOid, GSSCredential.ACCEPT_ONLY);
// create a security context for decrypting the service ticket
GSSContext gssContext = gssmgr.createContext(serviceCredentials);
// decrypt the service ticket
System.out.println("Entering accpetSecContext...");
System.out.println(new String (Base64.encodeBase64(gssContext.acceptSecContext(this.kerberosTicket, 0,
this.kerberosTicket.length))));
// get the client name from the decrypted service ticket
// note that Active Directory created the service ticket, so we can trust it
String clientName = gssContext.getSrcName().toString();
Aggiornamento 2:
Se ho la sicurezza di primavera di installazione basato su questo https://spring.io/blog/2009/09/28/spring-security-kerberos-spnego-extension ho anche avuto la stessa errore:
java.lang.NullPointerException at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136) at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:125) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422)
private static class KerberosValidateAction implements PrivilegedExceptionAction<String> {
byte[] kerberosTicket;
public KerberosValidateAction(byte[] kerberosTicket) {
this.kerberosTicket = kerberosTicket;
}
@Override
public String run() throws Exception {
GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);
context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
String user = context.getSrcName().toString(); // ERROR!
context.dispose();
return user;
}
}
.515.053.691,36321 milioni
Update 3:
provato anche il cambiamento versione Java 1,8-1,7 come suggerito qui Domain authentication with Kerberos fails. Nessun risultato.
Update 4:
Prima di tutto. Non utilizzare Java 1.8 b40 e b45, entrambi sono danneggiati. E non testarlo sul PC locale, non funziona (non so perché).
Dopo aver modificato la versione più recente (b65) di Java, ho ottenuto un'eccezione sulla codifica (Impossibile trovare la chiave del tipo appropriato per decrittografare AP REP - AES256 ...). Questo ho fissato da Java Cryptography Extension (JCE) per Java 1.8 e ri-creare keytab con /crypto AES256-SHA1
dopo tutto questo ho ottenuto eccezione:
GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed) at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source) at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) at GssServer$GssServerAction.run(GssServer.java:159) ... 4 more Caused by: KrbException: Checksum failed at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source) at sun.security.krb5.EncryptedData.decrypt(Unknown Source) at sun.security.krb5.KrbApReq.authenticate(Unknown Source) at sun.security.krb5.KrbApReq.(Unknown Source) at sun.security.jgss.krb5.InitSecContextToken.(Unknown Source) ... 8 more Caused by: java.security.GeneralSecurityException: Checksum failed at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(Unknown Source) at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(Unknown Source) ... 14 more
ho provato this tutorial e l'altro modo per creare keytabfile, ma ho ancora don' Ho una soluzione.
prega, mostrano il codice che si utilizza per stabilire il contesto –
So che questo è un vecchio thread, ma di recente ho avuto lo stesso problema esatto e nel mio caso è stato un problema con lo spn. Ho chiamato il mio servizio e poi ho digitato 'klist' in cmd per cercare il mio servizio. dopo averlo trovato ho visto qualcosa di simile a questo: HTTP/[email protected] Quello che devi fare è verificare che venga creato un SPN per questo. Crea un account di servizio e crea lo spn con 'setspn -un dominio HTTP/service.domain.com \ serviceAccout' e successivamente crea un keytab con' ktab -k FILE: your_filename.ktab -un dominio HTTP/service.domain.com \ password_of_service_account'. – Nico