- All imports
1
2
3
4
5
6
7
8
9
10
import org.apache.xmlbeans.impl.util.Base64;
import org.ietf.jgss.*;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.PrivilegedAction;
- Code to generate temporary keytab file
1
2
3
4
5
6
7
8
9
10
11
private File generateKrb5Conf() throws IOException {
final File temporaryKrb5Conf = File.createTempFile("krb5.conf", null);
final PrintStream printStream = new PrintStream(new FileOutputStream(temporaryKrb5Conf));
printStream.print(String.format(
"[libdefaults]\n" +
"default_realm = YOUR_ORG_DOMAIN"
));
printStream.close();
temporaryKrb5Conf.deleteOnExit();
return temporaryKrb5Conf;
}
- Code to generate temporary jass login file
1
2
3
4
5
6
7
8
9
10
11
private File generateJaasConf() throws IOException {
final File jaasConfFile = File.createTempFile("jaas.conf", null);
final PrintStream printStream = new PrintStream(new FileOutputStream(jaasConfFile));
// KRB5
printStream.print(String.format("Krb5LoginContext { com.sun.security.auth.module.Krb5LoginModule required refreshKrb5Config=true useTicketCache=true debug=true ; };"));
//For SQLServer Kerberos Login
//printStream.print(String.format("SQLSERVER { com.sun.security.auth.module.Krb5LoginModule required refreshKrb5Config=true useTicketCache=true debug=true ; };"));
printStream.close();
jaasConfFile.deleteOnExit();
return jaasConfFile;
}
- Code to configure Kerberos system parameters
1
2
3
4
5
6
7
private void configureKerberosSystemParameters() throws IOException {
System.setProperty("java.security.krb5.conf", generateKrb5Conf().getAbsolutePath());
System.setProperty("java.security.auth.login.config", generateJaasConf().getAbsolutePath());
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("sun.security.jgss.debug", "true");
}
- Code to pass credentials
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import javax.security.auth.callback.*;
import java.io.IOException;
public class CredentialsCallbackHandler implements CallbackHandler {
private final String username = "USER_NAME";
private final String password = "PASSWORD";
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback nameCallback = (NameCallback) callback;
nameCallback.setName(username);
} else if (callback instanceof PasswordCallback) {
PasswordCallback passwordCallback = (PasswordCallback) callback;
passwordCallback.setPassword(password.toCharArray());
} else throw new UnsupportedCallbackException(callback, "Unrecognised callback");
}
}
}
- Code to get kerberos ticket
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public class KerberosTicket implements PrivilegedAction {
private final String serverName;
private String ticket;
private String userPrincipal;
private KerberosTicket(final String serverName) {
this.serverName = serverName;
}
public Object run() {
try {
this.ticket = loginAndGetTicketDetailsAsString();
} catch (Exception e) {
e.printStackTrace();
this.ticket = "";
}
return this.ticket;
}
private String loginAndGetTicketDetailsAsString() throws GSSException {
final Oid krb5PrincipalNameOid = new Oid("1.2.840.113554.1.2.2.1");
final GSSManager manager = GSSManager.getInstance();
final GSSName clientName = manager.createName(userPrincipal, krb5PrincipalNameOid);
final Oid Krb5_v5_oid = new Oid("1.2.840.113554.1.2.2");
final int ticketValidFor = 8 * 3600;
final GSSCredential clientCred = manager.createCredential(clientName,
ticketValidFor,
Krb5_v5_oid,
GSSCredential.INITIATE_ONLY);
final GSSContext context = manager.createContext(manager.createName(serverName, krb5PrincipalNameOid),
Krb5_v5_oid,
clientCred,
GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true);
context.requestConf(false);
context.requestInteg(true);
try {
final byte[] retrieveToken = context.initSecContext(new byte[0], 0, 0);
return generateOutputString(context, retrieveToken);
} finally {
context.dispose();
}
}
private String generateOutputString(GSSContext context, byte[] retrieveToken) throws GSSException {
StringBuilder stringBuilder = new StringBuilder("Context Source Name is ")
.append("[")
.append(context.getSrcName())
.append("]")
.append(System.lineSeparator())
.append("Context Target Name is ")
.append("[")
.append(context.getTargName())
.append("]")
.append(System.lineSeparator())
.append("Token is ")
.append("[")
.append(new Base64().encode(retrieveToken))
.append("]");
return stringBuilder.toString();
}
public String getTicketDetails() throws LoginException, IOException {
final Subject subject = new Subject();
final LoginContext loginContext = new LoginContext("Krb5LoginContext", subject, new CredentialsCallbackHandler());
loginContext.login();
if (subject.getPrincipals().size() == 1) {
this.userPrincipal = subject.getPrincipals().stream().findFirst().get().getName();
Subject.doAsPrivileged(loginContext.getSubject(), this, null);
return ticket;
} else {
throw new AssertionError("Either zero or multiple principals found: " + subject.getPrincipals());
}
}
}
- Call the above code to test that ticket is obtained
1
2
configureKerberosSystemParameters();
System.out.println(new KerberosTicket("SERVER Name").getTicketDetails());