public byte[] requestServiceTicket(Subject clientSubject, String servicePrincipalName) {
   // For some reason SPNs in the format HTTP/servicehost.domain end up as
   // HTTP/servicehost.domain/hostname. SPNs defined as [email protected] work fine.
   servicePrincipalName = servicePrincipalName.replace('/', '@');
   try {
     Oid krb5Oid = new Oid("1.2.840.113554.1.2.2");
     GSSManager manager = GSSManager.getInstance();
     GSSName serverName =
         manager.createName(servicePrincipalName, GSSName.NT_HOSTBASED_SERVICE, krb5Oid);
     final GSSContext context =
         manager.createContext(serverName, krb5Oid, null, GSSContext.DEFAULT_LIFETIME);
     byte[] serviceTicket =
         Subject.doAs(
             clientSubject,
             new PrivilegedAction<byte[]>() {
               public byte[] run() {
                 byte[] token = new byte[0];
                 // This is a one pass context initialisation.
                 try {
                   context.requestMutualAuth(false);
                   context.requestCredDeleg(false);
                   return context.initSecContext(token, 0, token.length);
                 } catch (GSSException e) {
                   e.printStackTrace();
                   return null;
                 }
               }
             });
     return serviceTicket;
   } catch (GSSException e) {
     e.printStackTrace();
     return null;
   }
 }
 /**
  * Closes the session. If any {@link GSSContext} is present in the session then it is closed.
  *
  * @param message the error message
  */
 @Override
 protected void closeSession(String message) {
   GSSContext ctx = (GSSContext) getSession().getAttribute(GSS_CONTEXT);
   if (ctx != null) {
     try {
       ctx.dispose();
     } catch (GSSException e) {
       e.printStackTrace();
       super.closeSession(message, e);
       return;
     }
   }
   super.closeSession(message);
 }