I am getting following error for SPNEGO/Kerberos Authentication
I get this error when I run HelloKeyTab.java file.
***Exception in thread "main" javax.security.auth.login.LoginException: Client not
found in Kerberos database (6)**
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(K
b5LoginModule.java:763)
at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.j
va:584)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl
java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcce
sorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:762)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:
03)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:690)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:
87)
at javax.security.auth.login.LoginContext.login(LoginContext.java:595)
at net.sourceforge.spnego.SpnegoHttpURLConnection.<init>(SpnegoHttpURLC
nnection.java:207)
at HelloKeytab.main(HelloKeytab.java:17)
Caused by: KrbException: Client not found in Kerberos database (6)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:76)
at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:319)
at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:364)
at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(K
b5LoginModule.java:735)
... 14 more
Caused by: KrbException: Identifier doesn't match expected value (906)
at sun.security.krb5.internal.KDCRep.init(KDCRep.java:143)
at sun.security.krb5.internal.ASRep.init(ASRep.java:65)
at sun.security.krb5.internal.ASRep.<init>(ASRep.java:60)
at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:60)
... 17 more*
Setup,link and files I have used for SPNEGO/Kerberos Authentication.
link- http://spnego.sourceforge.net/
Domain account for tomcat server
user - xyztest
password - ****
principal - princ HTTP/[email protected]
1)HelloKeyTab.java - Test keytab generated for apache tomcat server
public class HelloKeytab {
public static void main(final String[] args) throws Exception {
System.setProperty("java.security.krb5.conf", "krb5.conf");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.auth.login.config", "login.conf");
SpnegoHttpURLConnection spnego = null;
try {
System.out.println("11111111");
spnego = new SpnegoHttpURLConnection("custom-client");
spnego.connect(new URL("http://localhost:8080/DemoAuth/hello_spnego.jsp"));
System.out.println("2222222");
System.out.println("HTTP Status Code: "
+ spnego.getResponseCode());
System.out.println("HTTP Status Message: "
+ spnego.getResponseMessage());
} finally {
if (null != spnego) {
spnego.disconnect();
}
}
}
}
2)krb5.conf - Kerberos Configuration File
[libdefaults]
default_tkt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts- hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
default_tgt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
permitted_enctypes = aes256-cts aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 aes128-cts rc4-hmac des3-cbc-sha1 des-cbc-md5 des-cbc-crc arcfour-hmac arcfour-hmac-md5
default_domain = CORP.XYZ.COM
[realms]
CORP.XYZ.COM = {
kdc = CORP.XYZ.COM
default_domain = CORP.XYZ.COM
}
[domain_realm]
CORP.XYZ.COM = CORP.XYZ.COM
3)login.conf -Login configuration file
custom-client {
com.sun.security.auth.module.Krb5LoginModule required
storeKey=true
useKeyTab=true
keyTab="C:/apache-tomcat-7.0.40-windows-x64/apache-tomcat-7.0.40/bin/xyztest.keytab"
principal="HTTP/[email protected]";
};
spnego-client {
com.sun.security.auth.module.Krb5LoginModule required;
};
spnego-server {
com.sun.security.auth.module.Krb5LoginModule required
storeKey=true
useKeyTab=true
keyTab="C:/apache-tomcat-7.0.40-windows-x64/apache-tomcat-7.0.40/bin/xyztest.keytab"
principal="HTTP/[email protected]";
};
4)setspn command -to register principal
setspn -s HTTP/APPSERVER1 xyztest
Checking domain DC=corp,DC=xyz,DC=com
Registering ServicePrincipalNames for CN=xyztest,CN=Users,DC=corp,DC=xyz,DC=com
HTTP/APPSERVER1
Updated object
PS C:\Windows\system32> setspn -s HTTP/APPSERVER1.corp.xyz.com xyztest
Checking domain DC=corp,DC=xyz,DC=com
Registering ServicePrincipalNames for CN=xyztest,CN=Users,DC=corp,DC=xyz,DC=com
HTTP/APPSERVER1.corp.xyz.com
Updated object
5)ktpass command : to generate keytab file
ktpass /princ HTTP/[email protected] /mapuser xyztest /pass ***** /out xyztest.keytab /crypto AES256-SHA1 /ptype KRB5_NT_PRINCIPAL
Targeting domain controller: xyzDC1.corp.xyz.com
Using legacy password setting method
ktpass : Successfully mapped HTTP/APPSERVER1 to xyztest.
At line:1 char:1
+ ktpass /princ HTTP/[email protected] /mapuser xyztest /pass *****
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Successfully ma...o xyztest.:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Key created.
Output keytab to xyztest.keytab:
Keytab version: 0x502
keysize 84 HTTP/[email protected] ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x12 (AES256-SHA1) keylength 32
(0x6e6afbbefc78946121bd7ed6657524c7409917cae1708223ce938449113d9805)
6)Apache tomcat server
7)JDK 7
8)Domain Controller - Windows Active directory
9)If I try to run kinit command to authenticate principal with keytab I get the same error Client not found in Kerberos database (6)
Command - kinit -k -t xyztest.keytab HTTP/[email protected]
Result - Exception krb_error 6 client not found in kerberos database (6)
10)HelloKDC.java : Link http://spnego.sourceforge.net/ provides HelloKDC.java to test connection to KDC. I can successfully connect to the KDC with HelloKDC.java
public final class HelloKDC {
private HelloKDC() {
// default private
}
public static void main(final String[] args) throws Exception {
// Domain (pre-authentication) account
final String username = "xyztest";
// Password for the pre-auth acct.
final String password = "!Dragonfly1!";
// Name of our krb5 config file
final String krbfile = "krb5.conf";
// Name of our login config file
final String loginfile = "login.conf";
// Name of our login module
final String module = "spnego-client";
// set some system properties
System.setProperty("java.security.krb5.conf", krbfile);
System.setProperty("java.security.auth.login.config", loginfile);
//System.setProperty("sun.security.krb5.debug", true);
// assert
HelloKDC.validate(username, password, krbfile, loginfile, module);
final CallbackHandler handler =
HelloKDC.getUsernamePasswordHandler(username, password);
final LoginContext loginContext = new LoginContext(module, handler);
// attempt to login
loginContext.login();
// output some info
System.out.println("Subject=" + loginContext.getSubject());
// logout
loginContext.logout();
System.out.println("Connection test successful.");
}
private static void validate(final String username, final String password
, final String krbfile, final String loginfile, final String moduleName)
throws FileNotFoundException, NoSuchAlgorithmException {
// confirm username was provided
if (null == username || username.isEmpty()) {
throw new IllegalArgumentException("Must provide a username");
}
// confirm password was provided
if (null == password || password.isEmpty()) {
throw new IllegalArgumentException("Must provide a password");
}
// confirm krb5.conf file exists
if (null == krbfile || krbfile.isEmpty()) {
throw new IllegalArgumentException("Must provide a krb5 file");
} else {
final File file = new File(krbfile);
if (!file.exists()) {
throw new FileNotFoundException(krbfile);
}
}
// confirm loginfile
if (null == loginfile || loginfile.isEmpty()) {
throw new IllegalArgumentException("Must provide a login file");
} else {
final File file = new File(loginfile);
if (!file.exists()) {
throw new FileNotFoundException(loginfile);
}
}
// confirm that runtime loaded the login file
final Configuration config = Configuration.getConfiguration();
// confirm that the module name exists in the file
if (null == config.getAppConfigurationEntry(moduleName)) {
throw new IllegalArgumentException("The module name "
+ moduleName + " was not found in the login file");
}
}
private static CallbackHandler getUsernamePasswordHandler(
final String username, final String password) {
final CallbackHandler handler = new CallbackHandler() {
public void handle(final Callback[] callback) {
for (int i=0; i<callback.length; i++) {
if (callback[i] instanceof NameCallback) {
final NameCallback nameCallback = (NameCallback) callback[i];
nameCallback.setName(username);
} else if (callback[i] instanceof PasswordCallback) {
final PasswordCallback passCallback = (PasswordCallback) callback[i];
passCallback.setPassword(password.toCharArray());
} else {
System.err.println("Unsupported Callback: "
+ callback[i].getClass().getName());
}
}
}
};
return handler;
}
}
Please provide me solution to resolve the error
Client not found in Kerberos database (6)
klist output
#0> Client: xyztest @ CORP.XYZ.COM
Server: krbtgt/CORP.XYZ.COM @ CORP.XYZ.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x60a10000 -> forwardable forwarded renewable pre_authent n
ame_canonicalize
Start Time: 3/8/2017 10:01:14 (local)
End Time: 3/8/2017 20:01:14 (local)
Renew Time: 3/15/2017 10:01:14 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x2 -> DELEGATION
Kdc Called: xyzDC1.corp.xyz.com
#1> Client: xyztest @ CORP.XYZ.COM
Server: krbtgt/CORP.XYZ.COM @ CORP.XYZ.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40e10000 -> forwardable renewable initial pre_authent nam
e_canonicalize
Start Time: 3/8/2017 10:01:14 (local)
End Time: 3/8/2017 20:01:14 (local)
Renew Time: 3/15/2017 10:01:14 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0x1 -> PRIMARY
Kdc Called: xyzDC1.corp.xyz.com
#2> Client: xyztest @ CORP.XYZ.COM
Server: ldap/xyzDC1.corp.xyz.com @ CORP.XYZ.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
Start Time: 3/8/2017 10:01:16 (local)
End Time: 3/8/2017 20:01:14 (local)
Renew Time: 3/15/2017 10:01:14 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0
Kdc Called: xyzDC1.corp.xyz.com
#3> Client: xyztest @ CORP.XYZ.COM
Server: LDAP/xyzDC1.corp.xyz.com/corp.xyz.com @ CORP.ADAP
TIVE.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
Start Time: 3/8/2017 10:01:15 (local)
End Time: 3/8/2017 20:01:14 (local)
Renew Time: 3/15/2017 10:01:14 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0
Kdc Called: xyzDC1.corp.xyz.com
#4> Client: xyztest @ CORP.XYZ.COM
Server: cifs/xyzDC1.corp.xyz.com @ CORP.XYZ.COM
KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
Ticket Flags 0x40a50000 -> forwardable renewable pre_authent ok_as_deleg
ate name_canonicalize
Start Time: 3/8/2017 10:01:14 (local)
End Time: 3/8/2017 20:01:14 (local)
Renew Time: 3/15/2017 10:01:14 (local)
Session Key Type: AES-256-CTS-HMAC-SHA1-96
Cache Flags: 0
Kdc Called: xyzDC1.corp.xyz.com
Keep the below things in mind when working on Kerberos Environment
For SPNEGO authentication, each server host should be mapped as HTTP/hostname for the web authentication user. For example,
setspn -s HTTP/hostname xyztest
To get Kerberos ticket using username and password
kinit principal password
To get Kerberos ticket using keytab
kinit -k -t keytab principal
You can set ticket location using environment variable krb5ccname
set krb5ccname=newticketfilelocation
To list the ticket details, change directory to java\bin and run klist
. This is because klist command is available in windows and it shows only logged in user tickets. To list the ticket got from kinit command, you should run from java\bin location
klist