public void run() {
   try {
     Subject server = subjectFactory.getSubjectForHost(getHostName(exchange));
     // The AcceptSecurityContext takes over responsibility for setting the result.
     Subject.doAs(server, new AcceptSecurityContext(result, exchange, challenge));
   } catch (GeneralSecurityException e) {
     e.printStackTrace();
     result.setResult(new AuthenticationResult(null, AuthenticationOutcome.NOT_AUTHENTICATED));
   } catch (PrivilegedActionException e) {
     e.printStackTrace();
     result.setResult(new AuthenticationResult(null, AuthenticationOutcome.NOT_AUTHENTICATED));
   }
 }
  @Override
  public IoFuture<AuthenticationResult> authenticate(HttpServerExchange exchange) {
    ConcreteIoFuture<AuthenticationResult> result = new ConcreteIoFuture<AuthenticationResult>();
    HttpServerConnection connection = exchange.getConnection();
    NegotiationContext negContext = connection.getAttachment(NegotiationContext.ATTACHMENT_KEY);
    if (negContext != null) {
      exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
      if (negContext.isEstablished()) {
        result.setResult(
            new AuthenticationResult(
                negContext.getPrincipal(), AuthenticationOutcome.AUTHENTICATED));
      }
    }

    Deque<String> authHeaders = exchange.getRequestHeaders().get(AUTHORIZATION);
    if (authHeaders != null) {
      for (String current : authHeaders) {
        if (current.startsWith(NEGOTIATE_PREFIX)) {
          String base64Challenge = current.substring(NEGOTIATE_PREFIX.length());
          try {
            ByteBuffer challenge = FlexBase64.decode(base64Challenge);
            dispatch(exchange, new GSSAPIRunnable(result, exchange, challenge));
            // The request has now potentially been dispatched to a different worker thread, the run
            // method
            // within GSSAPIRunnable is now responsible for ensuring the request continues.
            return result;
          } catch (IOException e) {
          }

          // By this point we had a header we should have been able to verify but for some reason
          // it was not correctly structured.
          result.setResult(new AuthenticationResult(null, AuthenticationOutcome.NOT_AUTHENTICATED));
          return result;
        }
      }
    }

    // No suitable header was found so authentication was not even attempted.
    result.setResult(new AuthenticationResult(null, AuthenticationOutcome.NOT_ATTEMPTED));
    return result;
  }
    public Void run() throws GSSException {
      NegotiationContext negContext = exchange.getAttachment(NegotiationContext.ATTACHMENT_KEY);
      if (negContext == null) {
        negContext = new NegotiationContext();
        exchange.putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
        // Also cache it on the connection for future calls.
        exchange.getConnection().putAttachment(NegotiationContext.ATTACHMENT_KEY, negContext);
      }

      GSSContext gssContext = negContext.getGssContext();
      if (gssContext == null) {
        GSSManager manager = GSSManager.getInstance();
        gssContext = manager.createContext((GSSCredential) null);

        negContext.setGssContext(gssContext);
      }

      byte[] respToken =
          gssContext.acceptSecContext(
              challenge.array(), challenge.arrayOffset(), challenge.limit());
      negContext.setResponseToken(respToken);

      if (negContext.isEstablished()) {
        result.setResult(
            new AuthenticationResult(
                negContext.getPrincipal(), AuthenticationOutcome.AUTHENTICATED));
      } else {
        // This isn't a failure but as the context is not established another round trip with the
        // client is needed.
        result.setResult(
            new AuthenticationResult(
                negContext.getPrincipal(), AuthenticationOutcome.NOT_AUTHENTICATED));
      }

      return null;
    }