class SpnegoAuthenticator extends AbstractAuthenticationBackend {

    public String authenticateUser(String authorizationHeader) {
        if (logins.isEmpty()) {
            initLogin();
        }

        if (! authorizationHeader.startsWith("Negotiate ")) {
            throw Status.UNAUTHENTICATED.withDescription("Use \"authorization: Negotiate <token>\" metadata to authenticate").asRuntimeException();
        }

        String spnegoToken = authorizationHeader.split("\\s")[1];

        String authenticatedUser = null;

        for (Subject login : logins) {
            authenticatedUser = Subject.doAs(login, (PrivilegedAction<String>) () -> {
                try {
                    GSSManager manager = GSSManager.getInstance();
                    Oid spnegoOid = new Oid("1.3.6.1.5.5.2");
                    GSSCredential serverCredential = manager.createCredential(null,
                        GSSCredential.DEFAULT_LIFETIME,
                        spnegoOid,
                        GSSCredential.ACCEPT_ONLY);
                    GSSContext context = manager.createContext(serverCredential);
                    byte[] tokenBytes = Base64.getDecoder().decode(spnegoToken.getBytes());
                    context.acceptSecContext(tokenBytes, 0, tokenBytes.length);
                    return context.getSrcName().toString();
                } catch (GSSException e) {
                    return null;
                }
            });
            if (authenticatedUser != null) {
                return authenticatedUser;
            }
        }

        throw Status.UNAUTHENTICATED.withDescription("SPNEGO authentication failed").asRuntimeException();
    }

}