Realm Detection and Pathing in the JSSE (Java)
Luke Hebert
- 3 minutes read - 529 wordsIf you have ever debugged a Kerberos authentication failure in a Java application, you have likely seen the terms cRealm and sRealm in stack traces or configuration logs. Understanding what they mean and how the JVM resolves the path between them can save a lot of trial and error.
What Are cRealm and sRealm?
In the Java Kerberos implementation (the sun.security.krb5 package), every ticket request involves two realms:
- cRealm (client realm): the realm where the user’s principal is registered. This is the initiating realm.
- sRealm (service realm): the realm where the target service principal lives. This is the destination realm.
When these two realms are the same, the path is trivial. When they differ, the implementation must figure out how to traverse from one to the other.
How the Path Is Resolved
The Realm.java source in the OpenJDK codebase documents the resolution order:
- The caller’s Kerberos configuration file (
krb5.conf) is consulted first. If a[capaths]stanza defines an explicit route between the two realms, that route is used. - If no
capathsentry is found, the implementation assumes a hierarchical organization. It walks up the realm hierarchy (for example,CORP.EXAMPLE.COMtoEXAMPLE.COM) to find a common ancestor, then walks down to the target realm.
The returned list always starts with cRealm. The sRealm is not included in the list unless it is mistakenly listed as an intermediary in the configuration file.
Relevant Source Code
The Javadoc for the path-building method in Realm.java reads as follows:
/**
* Returns an array of realms that may be traversed to obtain
* a TGT from the initiating realm cRealm to the target realm
* sRealm.
* <br>
* There may be an arbitrary number of intermediate realms
* between cRealm and sRealm. The realms may be organized
* hierarchically, or the paths between them may be
* specified in the [capaths] stanza of the caller's
* Kerberos configuration file. The configuration file is consulted
* first. Then a hierarchical organization is assumed if no realms
* are found in the configuration file.
* <br>
* The returned list, if not null, contains cRealm as the first
* entry. sRealm is not included unless it is mistakenly listed
* in the configuration file as an intermediary realm.
*
* @param cRealm the initiating realm
* @param sRealm the target realm
* @returns array of realms
* @throws KrbException
*/A second method builds the full credential path:
/**
* Build a list of realms that can be traversed
* to obtain credentials from the initiating realm cRealm
* for a service in the target realm sRealm.
*
* @param cRealm the initiating realm
* @param sRealm the target realm
* @returns array of realms
* @throws KrbException
*/Practical Implications
When a Java application fails to obtain a TGT across realms, check the following:
- Confirm that
krb5.confon the client machine lists both realms and, if needed, a[capaths]entry. - Verify that the DNS SRV records for the target realm point to a reachable KDC.
- Make sure the realm names in the configuration match the case used in the principal strings.