Example usage for javax.security.auth Subject getPrivateCredentials

List of usage examples for javax.security.auth Subject getPrivateCredentials

Introduction

In this page you can find the example usage for javax.security.auth Subject getPrivateCredentials.

Prototype

public Set<Object> getPrivateCredentials() 

Source Link

Document

Return the Set of private credentials held by this Subject .

Usage

From source file:nl.nn.adapterframework.util.CredentialFactory.java

protected void getCredentialsFromAlias() {
    if (!gotCredentials && StringUtils.isNotEmpty(getAlias())) {
        try {//from  w  w w .ja  va2 s. c  om
            Set principals = new HashSet();
            Set publicCredentials = new HashSet();
            Set privateCredentials = new HashSet();
            Principal p = new IbisPrincipal();
            principals.add(p);
            Subject initialSubject = new Subject(false, principals, publicCredentials, privateCredentials);
            String loginConfiguration = AppConstants.getInstance().getProperty("PrincipalMapping",
                    "DefaultPrincipalMapping");
            LoginContext lc = new LoginContext(loginConfiguration, initialSubject, this);
            lc.login();
            Subject s = lc.getSubject();
            //showSet(s.getPrincipals(),"principals");
            //showSet(s.getPublicCredentials(),"PublicCredentials");
            //showSet(s.getPrivateCredentials(),"PrivateCredentials");
            //Object pwcred=Subject.doAsPrivileged(s,new PasswordGetter(s),AccessController.getContext());
            //Object pwcred=AccessController.doPrivileged(new PasswordGetter(s));

            Object pwcred = s.getPrivateCredentials().toArray()[0];

            setUsername(ClassUtils.invokeStringGetter(pwcred, "getUserName"));
            setPassword(invokeCharArrayGetter(pwcred, "getPassword"));
            gotCredentials = true;
        } catch (Exception e) {
            if (!useFallback) {
                NoSuchElementException nsee = new NoSuchElementException(
                        "cannot obtain credentials from authentication alias [" + getAlias() + "]");
                nsee.initCause(e);
                throw nsee;
            }
            log.error("exception obtaining credentials for alias [" + getAlias() + "]", e);

            String usernameProp = "alias." + getAlias() + ".username";
            String passwordProp = "alias." + getAlias() + ".password";
            log.info("trying to solve Authentication Alias from application properties [" + usernameProp
                    + "] and [" + passwordProp + "]");
            setUsername(AppConstants.getInstance().getProperty(usernameProp, username));
            setPassword(AppConstants.getInstance().getProperty(passwordProp, password));
        }
    }
}

From source file:org.globus.axis.handler.CredentialHandler.java

public void invoke(MessageContext msgContext) throws AxisFault {
    log.debug("Enter: invoke");

    Object tmp = msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST);

    if ((tmp == null) || !(tmp instanceof HttpServletRequest)) {
        return;//from   w ww  . jav  a2  s.  c o  m
    }

    HttpServletRequest req = (HttpServletRequest) tmp;

    // if httpg is access protocol in servlet engine, axis
    // will not set the TRANS_URL property correctly.
    // this is a workaround for that problem
    String url = req.getRequestURL().toString();
    tmp = msgContext.getProperty(MessageContext.TRANS_URL);
    if (tmp == null && url != null) {
        msgContext.setProperty(MessageContext.TRANS_URL, url);
    }

    Subject subject = getSubject(msgContext);

    // USER_DN is set by both HTTPS/HTTPG valves
    tmp = req.getAttribute(GSIConstants.GSI_USER_DN);
    if (tmp != null) {
        msgContext.setProperty(GSIConstants.GSI_USER_DN, tmp);
        subject.getPrincipals().add(new GlobusPrincipal((String) tmp));
    }

    // GSI_CONTEXT is set by HTTPS valve only
    tmp = req.getAttribute(GSIConstants.GSI_CONTEXT);
    if (tmp != null) {
        msgContext.setProperty(GSIConstants.GSI_CONTEXT, tmp);
        GSSContext ctx = (GSSContext) tmp;
        try {
            if (ctx.getDelegCred() != null) {
                subject.getPrivateCredentials().add(ctx.getDelegCred());
            }
        } catch (GSSException e) {
            log.warn("Unable to obtain delegated credentials", e);
        }
    }

    // GSI_CREDENTIALS is set only by HTTPG valve
    tmp = req.getAttribute(GSIConstants.GSI_CREDENTIALS);
    if (tmp != null) {
        log.debug("Delegation performed. Setting credentials property.");
        msgContext.setProperty(GSIConstants.GSI_CREDENTIALS, tmp);
        subject.getPrivateCredentials().add(tmp);
    } else {
        log.debug("Delegation not performed. Not setting credentials property.");
    }

    // GSI_AUTH_USERNAM is set only by HTTPG Valve
    tmp = req.getAttribute(GSIConstants.GSI_AUTH_USERNAME);
    if (tmp != null) {
        msgContext.setProperty(GSIConstants.GSI_AUTH_USERNAME, tmp);
        subject.getPrincipals().add(new UserNamePrincipal((String) tmp));
    }

    log.debug("Exit: invoke");
}

From source file:com.nulli.openam.plugins.NeoUniversalCondition.java

private JSONObject sanitizeParams(String params, String realm, Subject subject, String resourceName,
        Map<String, Set<String>> env) throws EntitlementException {
    JSONObject jsonParams = null;/*w w  w . ja v  a  2s .c  o m*/
    boolean requestHasParams = false;
    Map<String, String> reqParamMap = new LinkedHashMap<String, String>();

    SSOToken token = (SSOToken) subject.getPrivateCredentials().iterator().next();

    if (resourceName.split("\\?").length > 1) {
        requestHasParams = true;
        String urlQuery = resourceName.split("\\?")[1];
        String[] urlParams = urlQuery.split("&");
        for (String param : urlParams) {
            int idx = param.indexOf("=");
            reqParamMap.put(param.substring(0, idx), param.substring(idx + 1));
        }
    }

    try {
        if (!params.isEmpty()) {
            jsonParams = new JSONObject(params);
            @SuppressWarnings("unchecked")
            Iterator<String> paramItr = jsonParams.keys();

            while (paramItr.hasNext()) {
                String paramKey = paramItr.next();
                String paramVal = jsonParams.get(paramKey).toString();
                if (paramVal.startsWith("__")) {
                    if (paramVal.equals("__userId")) {
                        if (!subject.getPrincipals().isEmpty()) {
                            String userId = getUserId(subject);
                            jsonParams.put(paramKey, userId);
                        } else {
                            throw new EntitlementException(EntitlementException.CONDITION_EVALUATION_FAILED,
                                    "could not find userId (required) from subject");
                        }
                    } else if (paramVal.equals("__resourceName")) {
                        jsonParams.put(paramKey, resourceName);
                    } else if (paramVal.equals("__realm")) {
                        jsonParams.put(paramKey, realm);
                    } else if (paramVal.startsWith("__env__")) {
                        String envParam = paramVal.substring(7);
                        String envParamVal = envMapStringify(envParam, env.get(envParam));
                        jsonParams.put(paramKey, envParamVal);
                    } else if (paramVal.startsWith("__token__")) {
                        String tokenProp = paramVal.substring(7);
                        String tokenPropVal = token.getProperty(tokenProp);
                        jsonParams.put(paramKey, tokenPropVal);
                    } else if (paramVal.startsWith("__token.")) {
                        String tokenMethod = paramVal.substring(6);
                        java.lang.reflect.Method method = token.getClass().getMethod(tokenMethod);
                        String methodRet = method.invoke(token).toString();
                        jsonParams.put(paramKey, methodRet);
                    } else if (paramVal.startsWith("__req__") && requestHasParams) {
                        String reqParam = paramVal.substring(7);
                        if (reqParamMap.containsKey(reqParam)) {
                            String reqParamVal = reqParamMap.get(reqParam);
                            jsonParams.put(paramKey, reqParamVal);
                        }
                    }
                }
            }

        }

    } catch (JSONException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SSOException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchMethodException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SecurityException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalArgumentException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    } catch (InvocationTargetException ex) {
        Logger.getLogger(NeoUniversalCondition.class.getName()).log(Level.SEVERE, null, ex);
    }

    return jsonParams;
}

From source file:org.polymap.core.security.SpnegoFilter.java

private void complex(HttpServletResponse httpResponse, String header) throws ServletException {
    // The data following the word Negotiate is the GSS-API data to process.
    byte gssapiData[] = new byte[0];
    try {/* w  w w  .j  a  v a  2 s.c o m*/
        gssapiData = com.sun.org.apache.xml.internal.security.utils.Base64
                .decode(header.substring(10).getBytes());
    } catch (Base64DecodingException e) {
        log.error("", e);
    }

    // Guard clause to check for the unsupported NTLM authentication mechanism.
    if (isNtlmMechanism(gssapiData)) {
        log.warn("Got request for unsupported NTLM mechanism, aborting negotiation.");
        return;
    }

    /**
     * The server attempts to establish a security context. Establishment may
     * result in tokens that the server must return to the client. Tokens are
     * BASE-64 encoded GSS-API data.
     */
    GSSContext context = null;
    String outToken = null;

    try {
        GSSManager manager = GSSManager.getInstance();

        Oid spnegoOid = new Oid("1.3.6.1.5.5.2");
        GSSCredential serverCreds = manager.createCredential(null, GSSCredential.DEFAULT_LIFETIME, spnegoOid,
                GSSCredential.ACCEPT_ONLY);

        context = manager.createContext(serverCreds);

        byte tokenBytes[] = context.acceptSecContext(gssapiData, 0, gssapiData.length);
        outToken = new String(Base64.encode(tokenBytes));
    } catch (GSSException gsse) {
        gsse.printStackTrace();
        log.error("GSSException:       " + gsse.getMessage());
        log.error("GSSException major: " + gsse.getMajorString());
        log.error("GSSException minor: " + gsse.getMinorString());
        throw new ServletException(gsse);
    }

    /**
     * If the context is established, we can attempt to retrieve the name of the
     * "context initiator." In the case of the Kerberos mechanism, the context
     * initiator is the Kerberos principal of the client. Additionally, the
     * client may be delegating credentials.
     */
    if (context != null && context.isEstablished()) {
        log.debug("Context established, attempting Kerberos principal retrieval.");

        try {
            Subject subject = new Subject();
            GSSName clientGSSName = context.getSrcName();
            Principal clientPrincipal = new KerberosPrincipal(clientGSSName.toString());
            subject.getPrincipals().add(clientPrincipal);
            log.info("Got client Kerberos principal: " + clientGSSName);

            if (context.getCredDelegState()) {
                GSSCredential delegateCredential = context.getDelegCred();
                GSSName delegateGSSName = delegateCredential.getName();
                Principal delegatePrincipal = new KerberosPrincipal(delegateGSSName.toString());
                subject.getPrincipals().add(delegatePrincipal);
                subject.getPrivateCredentials().add(delegateCredential);
                log.info("Got delegated Kerberos principal: " + delegateGSSName);
            }

            // TODO
            // getSpnegoSession().setUser( clientGSSName.toString() );

            /**
             * A status code 200 status response can also carry a
             * "WWW-Authenticate" response header containing the final leg of an
             * authentication. In this case, the gssapi-data will be present.
             */
            if (outToken != null && outToken.length() > 0) {
                httpResponse.setHeader("WWW-Authenticate", "Negotiate " + outToken.getBytes());
                httpResponse.setStatus(HttpServletResponse.SC_OK);
                log.debug("Returning final authentication data to client to complete context.");
                return;
            }
        } catch (GSSException gsse) {
            log.error("GSSException:       " + gsse.getMessage());
            log.error("GSSException major: " + gsse.getMajorString());
            log.error("GSSException minor: " + gsse.getMinorString());

            httpResponse.addHeader("Client-Warning", gsse.getMessage());
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    } else {
        /**
         * Any returned code other than a success 2xx code represents an
         * authentication error. If a 401 containing a "WWW-Authenticate" header
         * with "Negotiate" and gssapi-data is returned from the server, it is a
         * continuation of the authentication request.
         */
        if (outToken != null && outToken.length() > 0) {
            httpResponse.setHeader("WWW-Authenticate", "Negotiate " + outToken.getBytes());
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            log.debug("Additional authentication processing required, returning token.");
            return;
        } else {
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            log.warn("Kerberos negotiation failed.");
        }
    }

    log.debug("Negotiation completed.");
}

From source file:org.apache.karaf.jaas.modules.krb5.Krb5LoginModuleTest.java

@Test
public void testKeytabSuccess() throws Exception {

    Map<String, Object> props = new HashMap<>();
    props.put("debug", "true");
    props.put("useKeyTab", "true");
    props.put("keyTab", createKeytab());
    props.put("principal", "hnelson@EXAMPLE.COM");
    props.put("doNotPrompt", "true");
    props.put("storeKey", "true");
    props.put("detailed.login.exception", "true");

    Subject subject = new Subject();

    Krb5LoginModule module = new Krb5LoginModule();
    module.initialize(subject, null, null, props);

    assertEquals("Precondition", 0, subject.getPrincipals().size());

    Assert.assertTrue(module.login());/*from   w  w w  . j  av a 2s . c  o  m*/
    Assert.assertTrue(module.commit());

    assertEquals(1, subject.getPrincipals().size());

    boolean foundUser = false;
    for (Principal pr : subject.getPrincipals()) {
        if (pr instanceof KerberosPrincipal) {
            assertEquals("hnelson@EXAMPLE.COM", pr.getName());
            foundUser = true;
            break;
        }
    }
    assertTrue(foundUser);

    boolean foundToken = false;
    for (Object crd : subject.getPrivateCredentials()) {
        if (crd instanceof KerberosTicket) {
            assertEquals("hnelson@EXAMPLE.COM", ((KerberosTicket) crd).getClient().getName());
            assertEquals("krbtgt/EXAMPLE.COM@EXAMPLE.COM", ((KerberosTicket) crd).getServer().getName());
            foundToken = true;
            break;
        }
    }
    assertTrue(foundToken);

    Assert.assertTrue(module.logout());

}

From source file:org.apache.karaf.jaas.modules.krb5.Krb5LoginModuleTest.java

@Test
public void testLoginSuccess() throws Exception {
    CallbackHandler cb = new CallbackHandler() {
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (Callback cb : callbacks) {
                if (cb instanceof NameCallback) {
                    ((NameCallback) cb).setName("hnelson");
                } else if (cb instanceof PasswordCallback) {
                    ((PasswordCallback) cb).setPassword("secret".toCharArray());
                }//  w  ww.j  a  v  a  2  s . c  o  m
            }
        }
    };
    Subject subject = new Subject();

    Krb5LoginModule module = new Krb5LoginModule();
    module.initialize(subject, cb, null, new HashMap<>());

    assertEquals("Precondition", 0, subject.getPrincipals().size());

    Assert.assertTrue(module.login());
    Assert.assertTrue(module.commit());

    assertEquals(1, subject.getPrincipals().size());

    boolean foundUser = false;
    for (Principal pr : subject.getPrincipals()) {
        if (pr instanceof KerberosPrincipal) {
            assertEquals("hnelson@EXAMPLE.COM", pr.getName());
            foundUser = true;
            break;
        }
    }
    assertTrue(foundUser);

    boolean foundToken = false;
    for (Object crd : subject.getPrivateCredentials()) {
        if (crd instanceof KerberosTicket) {
            assertEquals("hnelson@EXAMPLE.COM", ((KerberosTicket) crd).getClient().getName());
            assertEquals("krbtgt/EXAMPLE.COM@EXAMPLE.COM", ((KerberosTicket) crd).getServer().getName());
            foundToken = true;
            break;
        }
    }
    assertTrue(foundToken);

    Assert.assertTrue(module.logout());

}

From source file:org.apache.karaf.jaas.modules.ldap.GSSAPILdapLoginModuleTest.java

@Test
public void testSuccess() throws Exception {

    Properties options = ldapLoginModuleOptions();
    GSSAPILdapLoginModule module = new GSSAPILdapLoginModule();

    CallbackHandler cb = new CallbackHandler() {
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (Callback cb : callbacks) {
                if (cb instanceof NameCallback) {
                    ((NameCallback) cb).setName("hnelson");
                } else if (cb instanceof PasswordCallback) {
                    ((PasswordCallback) cb).setPassword("secret".toCharArray());
                }/*from   w  ww  . j  a  v a  2  s  . c om*/
            }
        }
    };
    Subject subject = new Subject();
    module.initialize(subject, cb, null, options);

    assertEquals("Precondition", 0, subject.getPrincipals().size());
    assertTrue(module.login());
    assertTrue(module.commit());

    assertEquals(3, subject.getPrincipals().size());

    boolean foundKrb5User = false;
    boolean foundUser = false;
    boolean foundRole = false;
    boolean foundTicket = false;

    for (Principal pr : subject.getPrincipals()) {
        if (pr instanceof KerberosPrincipal) {
            assertEquals("hnelson@EXAMPLE.COM", pr.getName());
            foundKrb5User = true;
        } else if (pr instanceof UserPrincipal) {
            assertEquals("hnelson", pr.getName());
            foundUser = true;
        } else if (pr instanceof RolePrincipal) {
            assertEquals("admin", pr.getName());
            foundRole = true;
        }
    }
    for (Object crd : subject.getPrivateCredentials()) {
        if (crd instanceof KerberosTicket) {
            assertEquals("hnelson@EXAMPLE.COM", ((KerberosTicket) crd).getClient().getName());
            assertEquals("krbtgt/EXAMPLE.COM@EXAMPLE.COM", ((KerberosTicket) crd).getServer().getName());
            foundTicket = true;
            break;
        }
    }

    assertTrue("Principals should contains kerberos user", foundKrb5User);
    assertTrue("Principals should contains ldap user", foundUser);
    assertTrue("Principals should contains ldap role", foundRole);
    assertTrue("PricatePrincipals should contains kerberos ticket", foundTicket);

    assertTrue(module.logout());
    assertEquals("Principals should be gone as the user has logged out", 0, subject.getPrincipals().size());
}

From source file:net.java.jaspicoil.MSPacSpnegoServerAuthModule.java

private KerberosKey[] getSubjectKeys(Subject subject) {
    final List<KerberosKey> serverKeys = new ArrayList<KerberosKey>();

    final Set<Object> serverPrivateCredentials = subject.getPrivateCredentials();
    for (final Object credential : serverPrivateCredentials) {
        if (credential instanceof KerberosKey) {
            serverKeys.add((KerberosKey) credential);
        }/*from  ww  w .  ja v  a  2s.  co  m*/
    }

    return serverKeys.toArray(new KerberosKey[0]);
}

From source file:org.apache.hadoop.hive.shims.Hadoop23Shims.java

@Override
public UserGroupInformation cloneUgi(UserGroupInformation baseUgi) throws IOException {
    // Based on UserGroupInformation::createProxyUser.
    // TODO: use a proper method after we can depend on HADOOP-13081.
    if (getSubjectMethod == null) {
        throw new IOException("The UGI method was not found: " + ugiCloneError);
    }/*from ww  w.  j a v a2s.c  om*/
    try {
        Subject origSubject = (Subject) getSubjectMethod.invoke(baseUgi);

        Subject subject = new Subject(false, origSubject.getPrincipals(),
                cloneCredentials(origSubject.getPublicCredentials()),
                cloneCredentials(origSubject.getPrivateCredentials()));
        return ugiCtor.newInstance(subject);
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
        throw new IOException(e);
    }
}

From source file:com.example.ManualSpnegoNegotiateServlet.java

/**
 * Use of Kerberos is wrapped in an HTTP auth-scheme of "Negotiate" [RFC 4559].
 *
 * The auth-params exchanged use data formats defined for use with the GSS-API [RFC 2743]. In particular, they follow the formats set for the SPNEGO [RFC 4178] and
 * Kerberos [RFC 4121] mechanisms for GSSAPI. The "Negotiate" auth-scheme calls for the use of SPNEGO GSSAPI tokens that the specific mechanism type specifies.
 *
 * The current implementation of this protocol is limited to the use of SPNEGO with the Kerberos protocol.
 *
 * @param request/*from  w w  w  . ja v  a2s.  com*/
 * @param response
 * @throws ServletException
 *
 * @return true upon successful authentication, false otherwise
 */
protected boolean attemptNegotiation(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, UnsupportedEncodingException, IOException {
    log.debug("Attempting negotiation.");

    String header = request.getHeader("Authorization");

    /**
     * Guard clause to check for Negotiate header.
     *
     * If the server receives a request for an access-protected object, and if an acceptable Authorization header has not been sent, the server responds with a "401
     * Unauthorized" status code, and a "WWW-Authenticate:" header as per the framework described in [RFC 2616]. The initial WWW-Authenticate header will not carry
     * any gssapi-data.
     */
    if (header == null || header.length() < 10 || !header.startsWith("Negotiate ")) {
        response.setHeader("WWW-Authenticate", "Negotiate");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        log.debug("Proper authorization header not found, returning challenge.");
        return false;
    }

    /**
     * A client may initiate a connection to the server with an "Authorization" header containing the initial token for the server. This form will bypass the initial
     * 401 error from the server when the client knows that the server will accept the Negotiate HTTP authentication type.
     */
    log.debug("Authorization header found, continuing negotiation.");

    /**
     * The data following the word Negotiate is the GSS-API data to process.
     */
    byte gssapiData[] = Base64.decode(header.substring(10));

    log.debug("GSS API data: " + Arrays.toString(gssapiData));

    /**
     * Guard clause to check for the unsupported NTLM authentication mechanism.
     */
    if (isNtlmMechanism(gssapiData)) {
        log.warn("Got request for unsupported NTLM mechanism, aborting negotiation.");
        return false;
    }

    /**
     * The server attempts to establish a security context. Establishment may result in tokens that the server must return to the client. Tokens are BASE-64 encoded
     * GSS-API data.
     */
    GSSContext gssContext = null;
    LoginContext loginContext = null;
    String outToken = null;

    try {
        final String domainUsername = "Zeus";
        final String domainUserPassword = "Z3usP@55";
        final CallbackHandler handler = SpnegoProvider.getUsernamePasswordHandler(domainUsername,
                domainUserPassword);

        loginContext = new LoginContext("spnego-server", handler);
        loginContext.login();
        Subject subject = loginContext.getSubject();

        Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); // for spnego answers
        Oid kerbv5Oid = new Oid("1.2.840.113554.1.2.2"); // for chromium (they send a kerbv5 token instead of spnego)
        final Oid[] oids = new Oid[] { spnegoOid, kerbv5Oid };

        final GSSManager manager = GSSManager.getInstance();
        final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
            public GSSCredential run() throws GSSException {
                return manager.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, oids,
                        GSSCredential.ACCEPT_ONLY);
            }
        };

        GSSCredential serverCreds = Subject.doAs(subject, action);

        log.debug("Mechs: " + Arrays.toString(serverCreds.getMechs()));

        gssContext = manager.createContext(serverCreds);

        log.debug("Context created. " + gssContext);

        byte tokenBytes[] = gssContext.acceptSecContext(gssapiData, 0, gssapiData.length);
        outToken = Base64.encode(tokenBytes);
    } catch (PrivilegedActionException ex) {
        log.error("", ex);
    } catch (LoginException ex) {
        log.error("", ex);
    } catch (GSSException gsse) {
        gsse.printStackTrace();
        log.error("GSSException:       " + gsse.getMessage());
        log.error("GSSException major: " + gsse.getMajorString());
        log.error("GSSException minor: " + gsse.getMinorString());
        throw new ServletException(gsse);
    }

    /**
     * If the context is established, we can attempt to retrieve the name of the "context initiator." In the case of the Kerberos mechanism, the context initiator is
     * the Kerberos principal of the client. Additionally, the client may be delegating credentials.
     */
    if (gssContext != null && gssContext.isEstablished()) {
        log.debug("Context established, attempting Kerberos principal retrieval.");

        try {
            Subject subject = new Subject();
            GSSName clientGSSName = gssContext.getSrcName();
            KerberosPrincipal clientPrincipal = new KerberosPrincipal(clientGSSName.toString());
            subject.getPrincipals().add(clientPrincipal);
            log.info("Got client Kerberos principal: " + clientGSSName);
            response.getWriter().println("Hello, " + clientPrincipal);

            /**
             * Retrieve LogonInfo (for example, GroupSIDs) from the PAC Authorization Data
             * from a Kerberos Ticket that was issued by Active Directory.
             */
            byte[] kerberosTokenData = gssapiData;
            try {
                SpnegoToken token = SpnegoToken.parse(gssapiData);
                kerberosTokenData = token.getMechanismToken();
            } catch (DecodingException dex) {
                // Chromium bug: sends a Kerberos response instead of an spnego response with a Kerberos mechanism
            } catch (Exception ex) {
                log.error("", ex);
            }

            try {
                Object[] keyObjs = IteratorUtils
                        .toArray(loginContext.getSubject().getPrivateCredentials(KerberosKey.class).iterator());
                KerberosKey[] keys = new KerberosKey[keyObjs.length];
                System.arraycopy(keyObjs, 0, keys, 0, keyObjs.length);

                KerberosToken token = new KerberosToken(kerberosTokenData, keys);
                log.info("Authorizations: ");
                for (KerberosAuthData authData : token.getTicket().getEncData().getUserAuthorizations()) {
                    if (authData instanceof KerberosPacAuthData) {
                        PacSid[] groupSIDs = ((KerberosPacAuthData) authData).getPac().getLogonInfo()
                                .getGroupSids();
                        log.info("GroupSids: " + Arrays.toString(groupSIDs));
                        response.getWriter().println("Found group SIDs: " + Arrays.toString(groupSIDs));
                    } else {
                        log.info("AuthData without PAC: " + authData.toString());
                    }
                }
            } catch (Exception ex) {
                log.error("", ex);
            }

            if (gssContext.getCredDelegState()) {
                GSSCredential delegateCredential = gssContext.getDelegCred();
                GSSName delegateGSSName = delegateCredential.getName();
                Principal delegatePrincipal = new KerberosPrincipal(delegateGSSName.toString());
                subject.getPrincipals().add(delegatePrincipal);
                subject.getPrivateCredentials().add(delegateCredential);
                log.info("Got delegated Kerberos principal: " + delegateGSSName);
            }

            /**
             * A status code 200 status response can also carry a "WWW-Authenticate" response header containing the final leg of an authentication. In this case, the
             * gssapi-data will be present.
             */
            if (outToken != null && outToken.length() > 0) {
                response.setHeader("WWW-Authenticate", "Negotiate " + outToken.getBytes());
                response.setStatus(HttpServletResponse.SC_OK);
                log.debug("Returning final authentication data to client to complete context.");
                log.debug("Negotiation completed.");
                return true;
            }
        } catch (GSSException gsse) {
            log.error("GSSException:       " + gsse.getMessage());
            log.error("GSSException major: " + gsse.getMajorString());
            log.error("GSSException minor: " + gsse.getMinorString());

            response.addHeader("Client-Warning", gsse.getMessage());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    } else {
        /**
         * Any returned code other than a success 2xx code represents an authentication error. If a 401 containing a "WWW-Authenticate" header with "Negotiate" and
         * gssapi-data is returned from the server, it is a continuation of the authentication request.
         */
        if (outToken != null && outToken.length() > 0) {
            response.setHeader("WWW-Authenticate", "Negotiate " + outToken.getBytes());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            log.debug("Additional authentication processing required, returning token.");
            return false;
        } else {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            log.warn("Kerberos negotiation failed.");
        }
    }

    log.debug("Negotiation completed.");

    return true;
}