1

It's possible to get a service ticket for the client (remote user) in the server side in order to use that ticket to authenticate against another backend?

Scenario: User (IE) ==> AppServer (Websphere, under Linux) ==> Backend (webservice)

  • We have SPNEGO auth running and working in the AppServer
  • The AD user that runs the AppServer has the rights to do the delegation

Thanks in advance

=====================

UPDATE

@Michael-O So ... this should be the step by step??

1) Login the AppServer User (the one with rights to do the delegation)

2) Execute a privileged action in his name

3) Set up a context between this user and the remote backend

4) initSecContext using the REMOTE USER SERVICE TICKET

5) As result of the context initialization, we should have the service ticket for the remote user to acces the remote backend

private static String getToken(byte[] remoteUserServiceTicket) {
    String token = null;
    byte[] serviceTicket = null;
    try {

        krb5Oid = new Oid("1.2.840.113554.1.2.2");

        LoginContext loginCtx = new LoginContext("Krb5Login", new LoginCallbackHandler("APPSERVERUSER", "APPSERVERPASSWORD"));
        loginCtx.login();
        Subject subject = loginCtx.getSubject();
        serviceTicket = Subject.doAs(subject, new PrivilegedAction<byte[]>(){
            public byte[] run() {
                try {
                    byte[] delegatedTokenForTheRemoteUser = new byte[0];
                    GSSManager manager = GSSManager.getInstance();
                    GSSName webServerUserName = manager.createName("APPSERVERUSER@MYDOMAIN", GSSName.NT_USER_NAME);
                    GSSCredential webServerCred = manager.createCredential(webServerUserName, 8 * 3600, krb5Oid,
                        GSSCredential.INITIATE_ONLY);
                    GSSName backendName = manager.createName("HTTP/mybackend@MYDOMAIN", null);
                    GSSContext context = manager.createContext(backendName, krb5Oid, webServerCred,
                        GSSContext.DEFAULT_LIFETIME);
                    delegatedTokenForTheRemoteUser = context.initSecContext(remoteUserServiceTicket, 0, remoteUserServiceTicket.length);
                    return delegatedTokenForTheRemoteUser;

                } catch (GSSException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });
    } catch (Exception e) {
        //exception handling omitted
    }       

    token = Base64.encode(serviceTicket);
    return token;
}
Alejandro Caride
  • 241
  • 3
  • 13
  • 1
    This can be made work several ways. You have to clarify first whether the authenticator on WebSphere will store [`GSSContext#getDelegCred()`](https://docs.oracle.com/javase/7/docs/api/org/ietf/jgss/GSSContext.html#getDelegCred%28%29). If so, the rest is quite easy. – Michael-O May 12 '16 at 20:38
  • Thanks for your answer! That's the tricky part.. I cant understand where that credentials are stored, neither how to obtain it. I tried using GSSManager#createCredential() for the client name but it doesn't worked – Alejandro Caride May 12 '16 at 23:34
  • `createCredential` won't help you. If the WebSphere module does not store the credential, talk to IBM first. You may resort to you can only use S4U extensions. See [`ExtendedGSSCredential#impersonate()`](https://docs.oracle.com/javase/8/docs/jre/api/security/jgss/spec/com/sun/security/jgss/ExtendedGSSCredential.html#impersonate-org.ietf.jgss.GSSName-). – Michael-O May 13 '16 at 08:43
  • @Michael-O Thanks again. I can't use that solution because i'm using an older version of jdk (1.6 ibm). I think i need to figure it out what module is the Websphere using to perform the client login. Is that right? – Alejandro Caride May 13 '16 at 15:11
  • correct. Either recent Java from Oracle, because the extended credential is an Oracle class or pray for a sane implementation of the authentication module. – Michael-O May 13 '16 at 19:21
  • @Michael-O I'm stil struggling with this issue. Please, could you correct me if i'm wrong?. In order to get a service ticket for the remote user i need to get (in the server side) the service ticket that was used by the user to access the webserver. Then initSecContext using that token to request a service ticket to the remote backend? Thanks in advance – Alejandro Caride Jun 09 '16 at 19:28
  • @Michael-O I really appreciate your help. I've updated the question following the above process – Alejandro Caride Jun 09 '16 at 20:53
  • @AlejanroCaride, the entire code is wrong from the ground up. You did not really understand how credential delegation works and how context establishment works. – Michael-O Jun 10 '16 at 07:26
  • @Michael-O That's why i'm asking for help, this is really important for me. Sorry if i'm making you to waste your time. I understand the theory but do not understand how the code should be. Please help me :( – Alejandro Caride Jun 10 '16 at 10:57
  • I already told you that the authenticator module has to store the credential in the request principal. Did you check that? You didn't. If the module doesn't do this, I cannot help you. Is the module open source? It should similar to [this](http://tomcatspnegoad.sourceforge.net/xref/net/sf/michaelo/tomcat/realm/ActiveDirectoryRealm.html#L256). – Michael-O Jun 10 '16 at 12:15

0 Answers0