10
votes

I am trying to use S4U2Proxy introduced in Java 8. Unfortunately I was not successfull in finding those many examples. My requirement is the client would send its certificate. I should then delegate (using kerberos) his request, connect to KDC, get the TGT, get the service ticket to contact another server on user's behalf and then finally contact the actual service by providing the service ticket. If java 8 does not provide a clean approach, can you pls point me to other utilities which might solve my requirement.

Subject.doAs(subject, new PrivilegedAction<Object>() {
        @Override
        public Object run() {
            GSSManager manager = GSSManager.getInstance();
            GSSCredential self  = null;
            try {
                GSSName selfUser = manager.createName("serviceWhoWantstoImpersonate", GSSName.NT_USER_NAME);
                Oid krb5Oid = new Oid( "1.2.840.113554.1.2.2");
                self = manager.createCredential(selfUser.canonicalize(krb5Oid), GSSCredential.DEFAULT_LIFETIME, krb5Oid, GSSCredential.INITIATE_ONLY);
                GSSName user = manager.createName(clientName, GSSName.NT_USER_NAME);
                GSSCredential impCred = ((ExtendedGSSCredential) self).impersonate(user);
            } catch (GSSException e) {
                e.printStackTrace();
            }

            return null;
        }
    });

Obviously there will be questions about how the SPN has been set in the KDC? Whether that service account is authorized for delegation? Has the right SPN been assigned to that service account? When the user "monkey" denies all sort of delegation? etc etc. Right now I feel I have made the right settings in KDC. My problem is the above is occurs even before it hits the KDC. Any valid inputs will help.

EDIT: After some reasearch, I was able to perform the S4u2self and s4u2proxy using java 8. Surpised that atleast one example should have been provided by Oracle documentation. Anyhow, I am now moving to next stage. Now another scenario that I have to handle is cross-domain kerberos certificate delegation. From the java 8 documentation that I have seen so far, it infers that currently cross-realm is not supported. Is it still true?

1
Anyone has any sort of solution?Nischit
Is it possible to get an answer with a code snippet ?Yves Martin
I've summarized all the necessary details here: stackoverflow.com/a/57377671/1471779Bhushan Karmarkar

1 Answers

2
votes

I have built a complete standalone demonstration application for Kerberos SFU extensions features in Java 8: https://github.com/ymartin59/java-kerberos-sfudemo

Here is the short code snippet that allows to generate a SPNEGO token with TGS ticket for an impersonated user:

GSSManager manager = GSSManager.getInstance();
GSSName userName = manager.createName("targetUser", GSSName.NT_USER_NAME);
GSSCredential impersonatedUserCreds =
  ((ExtendedGSSCredential)serviceCredentials).impersonate(userName);

final Oid KRB5_PRINCIPAL_OID = new Oid("1.2.840.113554.1.2.2.1");
GSSName servicePrincipal =
  manager.createName("HTTP/webservice-host.domain.ltd", KRB5_PRINCIPAL_OID);
ExtendedGSSContext extendedContext =
  (ExtendedGSSContext) manager.createContext(servicePrincipal,
                                             new Oid("1.3.6.1.5.5.2"),
                                             impersonatedUserCreds,
                                             GSSContext.DEFAULT_LIFETIME);
final byte[] token = extendedContext.initSecContext(new byte[0], 0, 0);

Beware extendedContext is not established yet. Multiple rounds with server may be required.

Java 8 Kerberos code does not support cross-realm impersonation yet: refer to JDK-8005819

The Java service account may be hosted in one realm and this code can target a service in another realm as far as this realm is explicitely appended to SPN, like HTTP/[email protected]

The same way for users known in other realm, you should append it to login name in method createName("[email protected]", GSSName.NT_USER_NAME)