From c1d655775f31229b8dfeecbc17f8c6b183578187 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Fri, 3 May 2013 18:28:30 +0200 Subject: [PATCH] 407135 - Unauthorized response causes retry loop. Fixed by adding a conversation flag to check if the authentication has been tried, and forward the 401 if the flag is found. --- .../client/AuthenticationProtocolHandler.java | 13 ++++++++++++- .../client/HttpClientAuthenticationTest.java | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java index 7b66d6f2b45..7adcb80a995 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java @@ -40,6 +40,7 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler public static final int DEFAULT_MAX_CONTENT_LENGTH = 4096; public static final Logger LOG = Log.getLogger(AuthenticationProtocolHandler.class); private static final Pattern AUTHENTICATE_PATTERN = Pattern.compile("([^\\s]+)\\s+realm=\"([^\"]+)\"(.*)", Pattern.CASE_INSENSITIVE); + private static final String AUTHENTICATION_ATTRIBUTE = AuthenticationProtocolHandler.class.getName() + ".authentication"; private final HttpClient client; private final int maxContentLength; @@ -90,6 +91,15 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler return; } + HttpConversation conversation = client.getConversation(request.getConversationID(), false); + if (conversation.getAttribute(AUTHENTICATION_ATTRIBUTE) != null) + { + // We have already tried to authenticate, but we failed again + LOG.debug("Bad credentials for {}", request); + forwardSuccessComplete(request, response); + return; + } + HttpHeader header = getAuthenticateHeader(); List headerInfos = parseAuthenticateHeader(response, header); if (headerInfos.isEmpty()) @@ -118,7 +128,6 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler return; } - HttpConversation conversation = client.getConversation(request.getConversationID(), false); final Authentication.Result authnResult = authentication.authenticate(request, response, headerInfo, conversation); LOG.debug("Authentication result {}", authnResult); if (authnResult == null) @@ -127,6 +136,8 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler return; } + conversation.setAttribute(AUTHENTICATION_ATTRIBUTE, true); + Request newRequest = client.copyRequest(request, request.getURI()); authnResult.apply(newRequest); newRequest.onResponseSuccess(new Response.SuccessListener() diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java index 80c3d0b9308..6f6d7054857 100644 --- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java @@ -304,4 +304,20 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest Assert.assertEquals(401, response.getStatus()); Assert.assertTrue(requests.get().await(5, TimeUnit.SECONDS)); } + + @Test + public void test_BasicAuthentication_WithWrongPassword() throws Exception + { + startBasic(new EmptyServerHandler()); + + AuthenticationStore authenticationStore = client.getAuthenticationStore(); + URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort()); + BasicAuthentication authentication = new BasicAuthentication(uri, realm, "basic", "wrong"); + authenticationStore.addAuthentication(authentication); + + Request request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure"); + ContentResponse response = request.timeout(555, TimeUnit.SECONDS).send(); + Assert.assertNotNull(response); + Assert.assertEquals(401, response.getStatus()); + } }