protected AuthenticationHandlerExecutionResult doInternalAuthentication(final List<Authentication> authentications,
                             final SpnegoCredential spnegoCredential, final Service service) throws Throwable {
        var principal = (java.security.Principal) null;
        var nextToken = (byte[]) null;
        val it = authentications.iterator();
        while (nextToken == null && it.hasNext()) {
            try {
                val authentication = it.next();
                authentication.reset();
                LOGGER.debug("Processing SPNEGO authentication");
                authentication.process(spnegoCredential.getInitToken());
                principal = authentication.getPrincipal();
                LOGGER.debug("Authenticated SPNEGO principal [{}]. Retrieving the next token for authentication...",
                    Optional.ofNullable(principal).map(java.security.Principal::getName).orElse(null));
                nextToken = authentication.getNextToken();
            } catch (final AuthenticationException e) {
                LOGGER.debug("Processing SPNEGO authentication failed with exception", e);
                throw new FailedLoginException(e.getMessage());
            }
        }

        if (nextToken != null) {
            LOGGER.debug("Setting nextToken in credential");
            spnegoCredential.setNextToken(nextToken);
        } else {
            LOGGER.debug("nextToken is null");
        }
        var success = false;
        if (principal != null) {
            if (spnegoCredential.isNtlm()) {
                LOGGER.debug("NTLM Credential is valid for user [{}]", principal.getName());
            } else {
                LOGGER.debug("Kerberos Credential is valid for user [{}]", principal.getName());
            }
            spnegoCredential.setPrincipal(getPrincipal(principal.getName(), spnegoCredential.isNtlm()));
            success = true;
        }
        if (!success) {
            throw new FailedLoginException("Principal is null, the processing of the SPNEGO Token failed");
        }
        return new DefaultAuthenticationHandlerExecutionResult(this, spnegoCredential, spnegoCredential.getPrincipal());
    }
Implementation of an AuthenticationHandler for SPNEGO supports. This Handler
support both NTLM and Kerberos. NTLM is disabled by default.

@author Arnaud Lesueur
@author Marc-Antoine Garrigue
@author Scott Battaglia
@author Marvin S. Addison
@since 3.1
support/cas-server-support-spnego/src/main/java/org/apereo/cas/support/spnego/authentication/handler/support/JcifsSpnegoAuthenticationHandler.java