private boolean needAuthentication(
            final AuthExchange targetAuthExchange,
            final AuthExchange proxyAuthExchange,
            final HttpHost proxy,
            final HttpHost target,
            final String pathPrefix,
            final HttpResponse response,
            final HttpClientContext context) throws AuthenticationException, MalformedChallengeException {
                final RequestConfig config = context.getRequestConfigOrDefault();
        if (config.isAuthenticationEnabled()) {
            final boolean targetAuthRequested = authenticator.isChallenged(
                    target, ChallengeType.TARGET, response, targetAuthExchange, context);
            final boolean targetMutualAuthRequired = authenticator.isChallengeExpected(targetAuthExchange);

            if (authCacheKeeper != null) {
                if (targetAuthRequested) {
                    authCacheKeeper.updateOnChallenge(target, pathPrefix, targetAuthExchange, context);
                } else {
                    authCacheKeeper.updateOnNoChallenge(target, pathPrefix, targetAuthExchange, context);
                }
            }

            final boolean proxyAuthRequested = authenticator.isChallenged(
                    proxy, ChallengeType.PROXY, response, proxyAuthExchange, context);
            final boolean proxyMutualAuthRequired = authenticator.isChallengeExpected(proxyAuthExchange);

            if (authCacheKeeper != null) {
                if (proxyAuthRequested) {
                    authCacheKeeper.updateOnChallenge(proxy, null, proxyAuthExchange, context);
                } else {
                    authCacheKeeper.updateOnNoChallenge(proxy, null, proxyAuthExchange, context);
                }
            }

            if (targetAuthRequested || targetMutualAuthRequired) {
                final boolean updated = authenticator.handleResponse(target, ChallengeType.TARGET, response,
                        targetAuthStrategy, targetAuthExchange, context);

                if (authCacheKeeper != null) {
                    authCacheKeeper.updateOnResponse(target, pathPrefix, targetAuthExchange, context);
                }

                return updated;
            }
            if (proxyAuthRequested || proxyMutualAuthRequired) {
                final boolean updated = authenticator.handleResponse(proxy, ChallengeType.PROXY, response,
                        proxyAuthStrategy, proxyAuthExchange, context);

                if (authCacheKeeper != null) {
                    authCacheKeeper.updateOnResponse(proxy, null, proxyAuthExchange, context);
                }

                return updated;
            }
        }
        return false;
    }
Request execution handler in the classic request execution chain
that is responsible for implementation of HTTP specification requirements.
<p>
Further responsibilities such as communication with the opposite
endpoint is delegated to the next executor in the request execution
chain.
</p>

@since 4.3
httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ProtocolExec.java