Kerberos authentication plays a vital role in securing enterprise Java applications. Whether you integrate with Hadoop, secure JDBC connections, or build Spring Boot microservices, you’ll eventually need to authenticate the application using a Kerberos principal.
But what if your application must authenticate using multiple Kerberos identities?
For example:
- a service principal for reading files from HDFS
- another principal for connecting to a secured database
- multiple principals stored inside a shared keytab
This article explains how to configure multiple principals safely and correctly using com.sun.security.auth.module.Krb5LoginModule. It also includes practical examples for Spring Boot, Hadoop, and Kerberized JDBC connections.
Can Krb5LoginModule Support Multiple Principals?
No — not directly in a single JAAS entry.
JAAS options are stored in a key–value map, so specifying:
principal="A"
principal="B"
results in only the last value being used.
✔ Correct method
Create multiple JAAS entries or multiple LoginContext instances, one per principal.
1. Using Multiple JAAS Entries (Recommended)
jaas.conf:
ServiceOne {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/app.keytab"
storeKey=true
doNotPrompt=true
principal="service1@EXAMPLE.COM";
};
ServiceTwo {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/etc/security/keytabs/app.keytab"
storeKey=true
doNotPrompt=true
principal="service2@EXAMPLE.COM";
};
Usage:
LoginContext ctx1 = new LoginContext("ServiceOne");
ctx1.login();
LoginContext ctx2 = new LoginContext("ServiceTwo");
ctx2.login();
2. Programmatic JAAS Configuration
Map<String, String> options1 = Map.of(
"principal", "service1@EXAMPLE.COM",
"useKeyTab", "true",
"doNotPrompt", "true",
"storeKey", "true",
"keyTab", "/etc/security/keytabs/app.keytab"
);
Map<String, String> options2 = Map.of(
"principal", "service2@EXAMPLE.COM",
"useKeyTab", "true",
"doNotPrompt", "true",
"storeKey", "true",
"keyTab", "/etc/security/keytabs/app.keytab"
);
AppConfigurationEntry entry1 = new AppConfigurationEntry(
"com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options1
);
AppConfigurationEntry entry2 = new AppConfigurationEntry(
"com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
options2
);
3. Spring Boot Kerberos Example
Spring Boot apps often need a service principal to authenticate against Kerberized APIs, HDFS, Kafka, or internal services.
Create jaas.conf:
SpringService {
com.sun.security.auth.module.Krb5LoginModule required
principal="springservice@EXAMPLE.COM"
useKeyTab=true
keyTab="/etc/security/keytabs/spring.keytab"
storeKey=true
doNotPrompt=true;
};
Configure Spring Boot:
# application.yml
kerberos:
jaas: /etc/security/jaas.conf
principal: springservice@EXAMPLE.COM
debug: false
Load the context manually:
@PostConstruct
public void kerberosLogin() throws Exception {
System.setProperty("java.security.auth.login.config", "/etc/security/jaas.conf");
LoginContext lc = new LoginContext("SpringService");
lc.login();
Subject subject = lc.getSubject();
// use Subject.doAs(...) to perform Kerberized actions
}
Run a Kerberos-authenticated operation:
Subject.doAs(
subject,
(PrivilegedExceptionAction<Void>) () -> {
// any Kerberized API call
return null;
}
);
4. Hadoop Kerberos Example (HDFS / YARN / Hive / HBase)
Hadoop uses Kerberos extensively.
Authenticate as a principal stored in your keytab:
System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
System.setProperty("java.security.auth.login.config", "/etc/security/jaas.conf");
Configuration conf = new Configuration();
conf.set("hadoop.security.authentication", "kerberos");
UserGroupInformation.setConfiguration(conf);
UserGroupInformation.loginUserFromKeytab(
"hdfsservice@EXAMPLE.COM",
"/etc/security/keytabs/hdfs.keytab"
);
FileSystem fs = FileSystem.get(conf);
fs.listStatus(new Path("/"));
If you need multiple principals (e.g., HDFS + Hive), authenticate separately by switching UGI contexts:
UserGroupInformation ugi1 = UserGroupInformation
.loginUserFromKeytabAndReturnUGI("hdfs@EXAMPLE.COM", "/path/hdfs.keytab");
UserGroupInformation ugi2 = UserGroupInformation
.loginUserFromKeytabAndReturnUGI("hive@EXAMPLE.COM", "/path/hive.keytab");
ugi1.doAs((PrivilegedExceptionAction<Void>) () -> {
// HDFS operations
return null;
});
ugi2.doAs((PrivilegedExceptionAction<Void>) () -> {
// Hive operations
return null;
});
5. JDBC Kerberos Example (PostgreSQL / SQL Server / Oracle / Hive)
Most JDBC drivers support Kerberos via JAAS and GSSAPI.
Example: PostgreSQL with Kerberos
jaas.conf:
PgService {
com.sun.security.auth.module.Krb5LoginModule required
principal="pgdb@EXAMPLE.COM"
useKeyTab=true
keyTab="/etc/security/keytabs/pg.keytab"
storeKey=true
doNotPrompt=true;
};
Java code:
System.setProperty("java.security.auth.login.config", "/etc/security/jaas.conf");
LoginContext ctx = new LoginContext("PgService");
ctx.login();
Subject.doAs(
ctx.getSubject(),
(PrivilegedExceptionAction<Void>) () -> {
String url = "jdbc:postgresql://db.example.com/mydb?gssEncMode=prefer";
try (Connection conn = DriverManager.getConnection(url)) {
PreparedStatement ps = conn.prepareStatement("SELECT now()");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1));
}
}
return null;
}
);
Multiple JDBC principals?
Same rule applies: use different JAAS entries and different subjects.
6. Checking Keytab for Multiple Principals
Many keytabs contain several identities:
klist -k /etc/security/keytabs/app.keytab
Example output:
1 service1@EXAMPLE.COM
2 service2@EXAMPLE.COM
3 HTTP/api.example.com@EXAMPLE.COM
Your app may authenticate as any of them — but one at a time per JAAS login.
Conclusion
Krb5LoginModule is flexible but strict:
✔ One principal per JAAS login entry
✔ Multiple principals → multiple JAAS entries
✔ Works seamlessly with Spring Boot, Hadoop, and JDBC
This approach ensures secure, clean, and predictable Kerberos authentication across your Java stack.
If your application needs multi-identity authentication, using several JAAS entries and switching principals via LoginContext or UGI is the industry-standard solution.

