Corrected resolution of the target host in DefaultUserTokenHandler

This commit is contained in:
Oleg Kalnichevski 2021-09-26 15:51:23 +02:00
parent fb0c073783
commit 4dd7cefbde
4 changed files with 46 additions and 15 deletions

View File

@ -29,6 +29,7 @@
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpContext;
/** /**
@ -60,4 +61,22 @@ public interface UserTokenHandler {
*/ */
Object getUserToken(HttpRoute route, HttpContext context); Object getUserToken(HttpRoute route, HttpContext context);
/**
* The token object returned by this method is expected to uniquely
* identify the current user if the context is user specific or to be
* {@code null} if it is not.
*
* @param route HTTP route
* @param request HTTP request
* @param context the execution context
*
* @return user token that uniquely identifies the user or
* {@code null} if the context is not user specific.
*
* @since 5.2
*/
default Object getUserToken(HttpRoute route, HttpRequest request, HttpContext context) {
return getUserToken(route, context);
}
} }

View File

@ -37,6 +37,8 @@
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.annotation.Contract; import org.apache.hc.core5.annotation.Contract;
import org.apache.hc.core5.annotation.ThreadingBehavior; import org.apache.hc.core5.annotation.ThreadingBehavior;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpContext;
/** /**
@ -61,28 +63,38 @@ public class DefaultUserTokenHandler implements UserTokenHandler {
@Override @Override
public Object getUserToken(final HttpRoute route, final HttpContext context) { public Object getUserToken(final HttpRoute route, final HttpContext context) {
return getUserToken(route, null, context);
}
@Override
public Object getUserToken(final HttpRoute route, final HttpRequest request, final HttpContext context) {
final HttpClientContext clientContext = HttpClientContext.adapt(context); final HttpClientContext clientContext = HttpClientContext.adapt(context);
Principal userPrincipal = null; final HttpHost target = request != null ? new HttpHost(request.getScheme(), request.getAuthority()) : route.getTargetHost();
final AuthExchange targetAuthExchange = clientContext.getAuthExchange(route.getTargetHost()); final AuthExchange targetAuthExchange = clientContext.getAuthExchange(target);
if (targetAuthExchange != null) { if (targetAuthExchange != null) {
userPrincipal = getAuthPrincipal(targetAuthExchange); final Principal authPrincipal = getAuthPrincipal(targetAuthExchange);
if (userPrincipal == null && route.getProxyHost() != null) { if (authPrincipal != null) {
final AuthExchange proxyAuthExchange = clientContext.getAuthExchange(route.getProxyHost()); return authPrincipal;
userPrincipal = getAuthPrincipal(proxyAuthExchange);
} }
} }
final HttpHost proxy = route.getProxyHost();
if (userPrincipal == null) { if (proxy != null) {
final SSLSession sslSession = clientContext.getSSLSession(); final AuthExchange proxyAuthExchange = clientContext.getAuthExchange(proxy);
if (sslSession != null) { if (proxyAuthExchange != null) {
userPrincipal = sslSession.getLocalPrincipal(); final Principal authPrincipal = getAuthPrincipal(proxyAuthExchange);
if (authPrincipal != null) {
return authPrincipal;
}
} }
} }
final SSLSession sslSession = clientContext.getSSLSession();
return userPrincipal; if (sslSession != null) {
return sslSession.getLocalPrincipal();
}
return null;
} }
private static Principal getAuthPrincipal(final AuthExchange authExchange) { private static Principal getAuthPrincipal(final AuthExchange authExchange) {

View File

@ -196,7 +196,7 @@ public void consumeResponse(
final TimeValue keepAliveDuration = keepAliveStrategy.getKeepAliveDuration(response, clientContext); final TimeValue keepAliveDuration = keepAliveStrategy.getKeepAliveDuration(response, clientContext);
Object userToken = clientContext.getUserToken(); Object userToken = clientContext.getUserToken();
if (userToken == null) { if (userToken == null) {
userToken = userTokenHandler.getUserToken(route, clientContext); userToken = userTokenHandler.getUserToken(route, request, clientContext);
clientContext.setAttribute(HttpClientContext.USER_TOKEN, userToken); clientContext.setAttribute(HttpClientContext.USER_TOKEN, userToken);
} }
execRuntime.markConnectionReusable(userToken, keepAliveDuration); execRuntime.markConnectionReusable(userToken, keepAliveDuration);

View File

@ -106,7 +106,7 @@ public ClassicHttpResponse execute(
Object userToken = context.getUserToken(); Object userToken = context.getUserToken();
if (userToken == null) { if (userToken == null) {
userToken = userTokenHandler.getUserToken(route, context); userToken = userTokenHandler.getUserToken(route, request, context);
context.setAttribute(HttpClientContext.USER_TOKEN, userToken); context.setAttribute(HttpClientContext.USER_TOKEN, userToken);
} }