Search in sources :

Example 6 with Realm

use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.

the class ProxyUnauthorized407Interceptor method exitAfterHandling407.

public boolean exitAfterHandling407(Channel channel, NettyResponseFuture<?> future, HttpResponse response, Request request, ProxyServer proxyServer, HttpRequest httpRequest) {
    if (future.isAndSetInProxyAuth(true)) {
        LOGGER.info("Can't handle 407 as auth was already performed");
        return false;
    }
    Realm proxyRealm = future.getProxyRealm();
    if (proxyRealm == null) {
        LOGGER.debug("Can't handle 407 as there's no proxyRealm");
        return false;
    }
    List<String> proxyAuthHeaders = response.headers().getAll(PROXY_AUTHENTICATE);
    if (proxyAuthHeaders.isEmpty()) {
        LOGGER.info("Can't handle 407 as response doesn't contain Proxy-Authenticate headers");
        return false;
    }
    // FIXME what's this???
    future.setChannelState(ChannelState.NEW);
    HttpHeaders requestHeaders = new DefaultHttpHeaders().add(request.getHeaders());
    switch(proxyRealm.getScheme()) {
        case BASIC:
            if (getHeaderWithPrefix(proxyAuthHeaders, "Basic") == null) {
                LOGGER.info("Can't handle 407 with Basic realm as Proxy-Authenticate headers don't match");
                return false;
            }
            if (proxyRealm.isUsePreemptiveAuth()) {
                // FIXME do we need this, as future.getAndSetAuth
                // was tested above?
                // auth was already performed, most likely auth
                // failed
                LOGGER.info("Can't handle 407 with Basic realm as auth was preemptive and already performed");
                return false;
            }
            // FIXME do we want to update the realm, or directly
            // set the header?
            Realm newBasicRealm = realm(proxyRealm).setUsePreemptiveAuth(true).build();
            future.setProxyRealm(newBasicRealm);
            break;
        case DIGEST:
            String digestHeader = getHeaderWithPrefix(proxyAuthHeaders, "Digest");
            if (digestHeader == null) {
                LOGGER.info("Can't handle 407 with Digest realm as Proxy-Authenticate headers don't match");
                return false;
            }
            Realm newDigestRealm = realm(proxyRealm).setUri(request.getUri()).setMethodName(request.getMethod()).setUsePreemptiveAuth(true).parseProxyAuthenticateHeader(digestHeader).build();
            future.setProxyRealm(newDigestRealm);
            break;
        case NTLM:
            String ntlmHeader = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
            if (ntlmHeader == null) {
                LOGGER.info("Can't handle 407 with NTLM realm as Proxy-Authenticate headers don't match");
                return false;
            }
            ntlmProxyChallenge(ntlmHeader, requestHeaders, proxyRealm, future);
            Realm newNtlmRealm = realm(proxyRealm).setUsePreemptiveAuth(true).build();
            future.setProxyRealm(newNtlmRealm);
            break;
        case KERBEROS:
        case SPNEGO:
            if (getHeaderWithPrefix(proxyAuthHeaders, NEGOTIATE) == null) {
                LOGGER.info("Can't handle 407 with Kerberos or Spnego realm as Proxy-Authenticate headers don't match");
                return false;
            }
            try {
                kerberosProxyChallenge(proxyRealm, proxyServer, requestHeaders);
            } catch (SpnegoEngineException e) {
                // FIXME
                String ntlmHeader2 = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
                if (ntlmHeader2 != null) {
                    LOGGER.warn("Kerberos/Spnego proxy auth failed, proceeding with NTLM");
                    ntlmProxyChallenge(ntlmHeader2, requestHeaders, proxyRealm, future);
                    Realm newNtlmRealm2 = realm(proxyRealm).setScheme(AuthScheme.NTLM).setUsePreemptiveAuth(true).build();
                    future.setProxyRealm(newNtlmRealm2);
                } else {
                    requestSender.abort(channel, future, e);
                    return false;
                }
            }
            break;
        default:
            throw new IllegalStateException("Invalid Authentication scheme " + proxyRealm.getScheme());
    }
    RequestBuilder nextRequestBuilder = future.getCurrentRequest().toBuilder().setHeaders(requestHeaders);
    if (future.getCurrentRequest().getUri().isSecured()) {
        nextRequestBuilder.setMethod(CONNECT);
    }
    final Request nextRequest = nextRequestBuilder.build();
    LOGGER.debug("Sending proxy authentication to {}", request.getUri());
    if (future.isKeepAlive() && !HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
        future.setConnectAllowed(true);
        future.setReuseChannel(true);
        requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
    } else {
        channelManager.closeChannel(channel);
        requestSender.sendNextRequest(nextRequest, future);
    }
    return true;
}
Also used : RequestBuilder(org.asynchttpclient.RequestBuilder) SpnegoEngineException(org.asynchttpclient.spnego.SpnegoEngineException) Request(org.asynchttpclient.Request) Realm(org.asynchttpclient.Realm)

Example 7 with Realm

use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.

the class NettyRequestSender method newNettyRequestAndResponseFuture.

private <T> NettyResponseFuture<T> newNettyRequestAndResponseFuture(final Request request, final AsyncHandler<T> asyncHandler, NettyResponseFuture<T> originalFuture, ProxyServer proxy, boolean forceConnect) {
    Realm realm = null;
    if (originalFuture != null) {
        realm = originalFuture.getRealm();
    } else {
        realm = request.getRealm();
        if (realm == null) {
            realm = config.getRealm();
        }
    }
    Realm proxyRealm = null;
    if (originalFuture != null) {
        proxyRealm = originalFuture.getProxyRealm();
    } else if (proxy != null) {
        proxyRealm = proxy.getRealm();
    }
    NettyRequest nettyRequest = requestFactory.newNettyRequest(request, forceConnect, proxy, realm, proxyRealm);
    if (originalFuture == null) {
        NettyResponseFuture<T> future = newNettyResponseFuture(request, asyncHandler, nettyRequest, proxy);
        future.setRealm(realm);
        future.setProxyRealm(proxyRealm);
        return future;
    } else {
        originalFuture.setNettyRequest(nettyRequest);
        originalFuture.setCurrentRequest(request);
        return originalFuture;
    }
}
Also used : EXPECT(io.netty.handler.codec.http.HttpHeaderNames.EXPECT) Realm(org.asynchttpclient.Realm)

Example 8 with Realm

use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.

the class ProxyUtils method createProxyServerSelector.

/**
 * Creates a proxy server instance from the given properties.
 * Currently the default http.* proxy properties are supported as well as properties specific for AHC.
 *
 * @param properties the properties to evaluate. Must not be null.
 * @return a ProxyServer instance or null, if no valid properties were set.
 * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html">Networking Properties</a>
 * @see #PROXY_HOST
 * @see #PROXY_PORT
 * @see #PROXY_NONPROXYHOSTS
 */
public static ProxyServerSelector createProxyServerSelector(Properties properties) {
    String host = properties.getProperty(PROXY_HOST);
    if (host != null) {
        int port = Integer.valueOf(properties.getProperty(PROXY_PORT, "80"));
        String principal = properties.getProperty(PROXY_USER);
        String password = properties.getProperty(PROXY_PASSWORD);
        Realm realm = null;
        if (principal != null) {
            realm = basicAuthRealm(principal, password).build();
        }
        ProxyServer.Builder proxyServer = proxyServer(host, port).setRealm(realm);
        String nonProxyHosts = properties.getProperty(PROXY_NONPROXYHOSTS);
        if (nonProxyHosts != null) {
            proxyServer.setNonProxyHosts(new ArrayList<>(Arrays.asList(nonProxyHosts.split("\\|"))));
        }
        ProxyServer proxy = proxyServer.build();
        return uri -> proxy;
    }
    return ProxyServerSelector.NO_PROXY_SELECTOR;
}
Also used : Arrays(java.util.Arrays) Dsl.basicAuthRealm(org.asynchttpclient.Dsl.basicAuthRealm) Logger(org.slf4j.Logger) Properties(java.util.Properties) Realm(org.asynchttpclient.Realm) ProxyServerSelector(org.asynchttpclient.proxy.ProxyServerSelector) Request(org.asynchttpclient.Request) LoggerFactory(org.slf4j.LoggerFactory) ProxyServer(org.asynchttpclient.proxy.ProxyServer) ArrayList(java.util.ArrayList) Dsl.proxyServer(org.asynchttpclient.Dsl.proxyServer) List(java.util.List) java.net(java.net) AsyncHttpClientConfig(org.asynchttpclient.AsyncHttpClientConfig) Dsl.basicAuthRealm(org.asynchttpclient.Dsl.basicAuthRealm) Realm(org.asynchttpclient.Realm) ProxyServer(org.asynchttpclient.proxy.ProxyServer)

Example 9 with Realm

use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.

the class Unauthorized401Interceptor method exitAfterHandling401.

public boolean exitAfterHandling401(final Channel channel, final NettyResponseFuture<?> future, HttpResponse response, final Request request, Realm realm, HttpRequest httpRequest) {
    if (realm == null) {
        LOGGER.debug("Can't handle 401 as there's no realm");
        return false;
    }
    if (future.isAndSetInAuth(true)) {
        LOGGER.info("Can't handle 401 as auth was already performed");
        return false;
    }
    List<String> wwwAuthHeaders = response.headers().getAll(WWW_AUTHENTICATE);
    if (wwwAuthHeaders.isEmpty()) {
        LOGGER.info("Can't handle 401 as response doesn't contain WWW-Authenticate headers");
        return false;
    }
    // FIXME what's this???
    future.setChannelState(ChannelState.NEW);
    HttpHeaders requestHeaders = new DefaultHttpHeaders().add(request.getHeaders());
    switch(realm.getScheme()) {
        case BASIC:
            if (getHeaderWithPrefix(wwwAuthHeaders, "Basic") == null) {
                LOGGER.info("Can't handle 401 with Basic realm as WWW-Authenticate headers don't match");
                return false;
            }
            if (realm.isUsePreemptiveAuth()) {
                // FIXME do we need this, as future.getAndSetAuth
                // was tested above?
                // auth was already performed, most likely auth
                // failed
                LOGGER.info("Can't handle 401 with Basic realm as auth was preemptive and already performed");
                return false;
            }
            // FIXME do we want to update the realm, or directly
            // set the header?
            Realm newBasicRealm = realm(realm).setUsePreemptiveAuth(true).build();
            future.setRealm(newBasicRealm);
            break;
        case DIGEST:
            String digestHeader = getHeaderWithPrefix(wwwAuthHeaders, "Digest");
            if (digestHeader == null) {
                LOGGER.info("Can't handle 401 with Digest realm as WWW-Authenticate headers don't match");
                return false;
            }
            Realm newDigestRealm = realm(realm).setUri(request.getUri()).setMethodName(request.getMethod()).setUsePreemptiveAuth(true).parseWWWAuthenticateHeader(digestHeader).build();
            future.setRealm(newDigestRealm);
            break;
        case NTLM:
            String ntlmHeader = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
            if (ntlmHeader == null) {
                LOGGER.info("Can't handle 401 with NTLM realm as WWW-Authenticate headers don't match");
                return false;
            }
            ntlmChallenge(ntlmHeader, requestHeaders, realm, future);
            Realm newNtlmRealm = realm(realm).setUsePreemptiveAuth(true).build();
            future.setRealm(newNtlmRealm);
            break;
        case KERBEROS:
        case SPNEGO:
            if (getHeaderWithPrefix(wwwAuthHeaders, NEGOTIATE) == null) {
                LOGGER.info("Can't handle 401 with Kerberos or Spnego realm as WWW-Authenticate headers don't match");
                return false;
            }
            try {
                kerberosChallenge(realm, request, requestHeaders);
            } catch (SpnegoEngineException e) {
                // FIXME
                String ntlmHeader2 = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
                if (ntlmHeader2 != null) {
                    LOGGER.warn("Kerberos/Spnego auth failed, proceeding with NTLM");
                    ntlmChallenge(ntlmHeader2, requestHeaders, realm, future);
                    Realm newNtlmRealm2 = realm(realm).setScheme(AuthScheme.NTLM).setUsePreemptiveAuth(true).build();
                    future.setRealm(newNtlmRealm2);
                } else {
                    requestSender.abort(channel, future, e);
                    return false;
                }
            }
            break;
        default:
            throw new IllegalStateException("Invalid Authentication scheme " + realm.getScheme());
    }
    final Request nextRequest = future.getCurrentRequest().toBuilder().setHeaders(requestHeaders).build();
    LOGGER.debug("Sending authentication to {}", request.getUri());
    if (future.isKeepAlive() && !HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
        future.setReuseChannel(true);
        requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
    } else {
        channelManager.closeChannel(channel);
        requestSender.sendNextRequest(nextRequest, future);
    }
    return true;
}
Also used : SpnegoEngineException(org.asynchttpclient.spnego.SpnegoEngineException) Request(org.asynchttpclient.Request) Realm(org.asynchttpclient.Realm)

Aggregations

Realm (org.asynchttpclient.Realm)9 Request (org.asynchttpclient.Request)6 SpnegoEngineException (org.asynchttpclient.spnego.SpnegoEngineException)4 DefaultHttpHeaders (io.netty.handler.codec.http.DefaultHttpHeaders)3 HttpHeaders (io.netty.handler.codec.http.HttpHeaders)3 HttpRequest (io.netty.handler.codec.http.HttpRequest)3 RequestBuilder (org.asynchttpclient.RequestBuilder)3 List (java.util.List)2 ProxyServer (org.asynchttpclient.proxy.ProxyServer)2 Bootstrap (io.netty.bootstrap.Bootstrap)1 EXPECT (io.netty.handler.codec.http.HttpHeaderNames.EXPECT)1 java.net (java.net)1 InetSocketAddress (java.net.InetSocketAddress)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Properties (java.util.Properties)1 AsyncHttpClientConfig (org.asynchttpclient.AsyncHttpClientConfig)1 DefaultAsyncHttpClientConfig (org.asynchttpclient.DefaultAsyncHttpClientConfig)1 Dsl.basicAuthRealm (org.asynchttpclient.Dsl.basicAuthRealm)1