Configure Multiple Principals in Krb5LoginModule (Complete Java Kerberos Guide + Spring Boot, Hadoop & JDBC Examples)

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.

This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back