private Realm kerberosChallenge(
      List<String> proxyAuth,
      Request request,
      ProxyServer proxyServer,
      FluentCaseInsensitiveStringsMap headers,
      Realm realm,
      NettyResponseFuture<?> future)
      throws NTLMEngineException {

    URI uri = request.getURI();
    String host =
        request.getVirtualHost() == null
            ? AsyncHttpProviderUtils.getHost(uri)
            : request.getVirtualHost();
    String server = proxyServer == null ? host : proxyServer.getHost();
    try {
      String challengeHeader = SpnegoEngine.instance().generateToken(server);
      headers.remove(HttpHeaders.Names.AUTHORIZATION);
      headers.add(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challengeHeader);

      return newRealmBuilder(realm) //
          .setUri(uri.getRawPath()) //
          .setMethodName(request.getMethod()) //
          .setScheme(Realm.AuthScheme.KERBEROS) //
          .build();

    } catch (Throwable throwable) {
      if (isNTLM(proxyAuth)) {
        return ntlmChallenge(proxyAuth, request, proxyServer, headers, realm, future);
      }
      channels.abort(future, throwable);
      return null;
    }
  }
  public static String perConnectionAuthorizationHeader(
      Request request, ProxyServer proxyServer, Realm realm) {
    String authorizationHeader = null;

    if (realm != null && realm.getUsePreemptiveAuth()) {
      switch (realm.getScheme()) {
        case NTLM:
          String msg = NtlmEngine.INSTANCE.generateType1Msg();
          authorizationHeader = "NTLM " + msg;
          break;
        case KERBEROS:
        case SPNEGO:
          String host;
          if (proxyServer != null) host = proxyServer.getHost();
          else if (request.getVirtualHost() != null) host = request.getVirtualHost();
          else host = request.getUri().getHost();

          authorizationHeader = "Negotiate " + SpnegoEngine.instance().generateToken(host);
          break;
        default:
          break;
      }
    }

    return authorizationHeader;
  }
  private void kerberosProxyChallenge(
      Channel channel, //
      List<String> proxyAuth, //
      Request request, //
      ProxyServer proxyServer, //
      Realm proxyRealm, //
      HttpHeaders headers, //
      NettyResponseFuture<?> future)
      throws SpnegoEngineException {

    String challengeHeader = SpnegoEngine.instance().generateToken(proxyServer.getHost());
    headers.set(HttpHeaders.Names.PROXY_AUTHORIZATION, "Negotiate " + challengeHeader);
  }
  private void kerberosChallenge(
      Channel channel, //
      List<String> authHeaders, //
      Request request, //
      HttpHeaders headers, //
      Realm realm, //
      NettyResponseFuture<?> future)
      throws SpnegoEngineException {

    Uri uri = request.getUri();
    String host = request.getVirtualHost() == null ? uri.getHost() : request.getVirtualHost();
    String challengeHeader = SpnegoEngine.instance().generateToken(host);
    headers.set(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challengeHeader);
  }