diff --git a/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java b/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java index 6a9813037f..8927389d18 100644 --- a/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java +++ b/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java @@ -29,6 +29,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; import javax.inject.Singleton; @@ -116,6 +117,8 @@ public void testPreemptiveAuthPost() { public static class AuthResource { int requestCount = 0; + int queryParamsBasicRequestCount = 0; + int queryParamsDigestRequestCount = 0; @GET public String get(@Context HttpHeaders h) { @@ -205,6 +208,30 @@ public String deleteFilterWithEntity(@Context HttpHeaders h, String e) { return e; } + + @GET + @Path("queryParamsBasic") + public String getQueryParamsBasic(@Context HttpHeaders h, @Context UriInfo uriDetails) { + queryParamsBasicRequestCount++; + String value = h.getRequestHeaders().getFirst("Authorization"); + if (value == null) { + throw new WebApplicationException( + Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build()); + } + return "GET " + queryParamsBasicRequestCount; + } + + @GET + @Path("queryParamsDigest") + public String getQueryParamsDigest(@Context HttpHeaders h, @Context UriInfo uriDetails) { + queryParamsDigestRequestCount++; + String value = h.getRequestHeaders().getFirst("Authorization"); + if (value == null) { + throw new WebApplicationException( + Response.status(401).header("WWW-Authenticate", "Digest realm=\"WallyWorld\"").build()); + } + return "GET " + queryParamsDigestRequestCount; + } } @Test @@ -348,4 +375,40 @@ public void testAuthInteractivePost() { assertEquals("POST", r.request().post(Entity.text("POST"), String.class)); } + + @Test + public void testAuthGetQueryParamsBasic() { + ClientConfig cc = new ClientConfig(); + cc.connectorProvider(new ApacheConnectorProvider()); + Client client = ClientBuilder.newClient(cc); + client.register(HttpAuthenticationFeature.universal("name", "password")); + + WebTarget r = client.target(getBaseUri()).path("test/queryParamsBasic"); + assertEquals("GET 2", r.request().get(String.class)); + + r = client.target(getBaseUri()) + .path("test/queryParamsBasic") + .queryParam("param1", "value1") + .queryParam("param2", "value2"); + assertEquals("GET 3", r.request().get(String.class)); + + } + + @Test + public void testAuthGetQueryParamsDigest() { + ClientConfig cc = new ClientConfig(); + cc.connectorProvider(new ApacheConnectorProvider()); + Client client = ClientBuilder.newClient(cc); + client.register(HttpAuthenticationFeature.universal("name", "password")); + + WebTarget r = client.target(getBaseUri()).path("test/queryParamsDigest"); + assertEquals("GET 2", r.request().get(String.class)); + + r = client.target(getBaseUri()) + .path("test/queryParamsDigest") + .queryParam("param1", "value1") + .queryParam("param2", "value2"); + assertEquals("GET 3", r.request().get(String.class)); + + } } diff --git a/core-client/src/main/java/org/glassfish/jersey/client/authentication/AuthenticationUtil.java b/core-client/src/main/java/org/glassfish/jersey/client/authentication/AuthenticationUtil.java new file mode 100644 index 0000000000..c6643c0580 --- /dev/null +++ b/core-client/src/main/java/org/glassfish/jersey/client/authentication/AuthenticationUtil.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.client.authentication; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.ws.rs.client.ClientRequestContext; + +/** + * Common authentication utilities + */ +class AuthenticationUtil { + static URI getCacheKey(ClientRequestContext request) { + URI requestUri = request.getUri(); + if (requestUri.getRawQuery() != null) { + // Return a URI without the query part of the request URI + try { + return new URI( + requestUri.getScheme(), + requestUri.getAuthority(), + requestUri.getPath(), + null, + requestUri.getFragment()); + } catch (URISyntaxException e) { + // Ignore and fall through + } + } + return requestUri; + } +} diff --git a/core-client/src/main/java/org/glassfish/jersey/client/authentication/DigestAuthenticator.java b/core-client/src/main/java/org/glassfish/jersey/client/authentication/DigestAuthenticator.java index 59f75bd7f3..51515727d9 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/authentication/DigestAuthenticator.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/authentication/DigestAuthenticator.java @@ -90,7 +90,7 @@ protected boolean removeEldestEntry(final Map.Entry eldest) { * @throws IOException When error with encryption occurs. */ boolean filterRequest(final ClientRequestContext request) throws IOException { - final DigestScheme digestScheme = digestCache.get(request.getUri()); + final DigestScheme digestScheme = digestCache.get(AuthenticationUtil.getCacheKey(request)); if (digestScheme != null) { final HttpAuthenticationFilter.Credentials cred = HttpAuthenticationFilter.getCredentials(request, this.credentials, HttpAuthenticationFilter.Type.DIGEST); @@ -131,10 +131,11 @@ public boolean filterResponse(final ClientRequestContext request, final ClientRe final boolean success = HttpAuthenticationFilter.repeatRequest(request, response, createNextAuthToken(digestScheme, request, cred)); + URI cacheKey = AuthenticationUtil.getCacheKey(request); if (success) { - digestCache.put(request.getUri(), digestScheme); + digestCache.put(cacheKey, digestScheme); } else { - digestCache.remove(request.getUri()); + digestCache.remove(cacheKey); } return success; } diff --git a/core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java b/core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java index 97675c3e3b..89f64bf93e 100644 --- a/core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java +++ b/core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java @@ -25,9 +25,9 @@ import java.util.List; import java.util.Map; +import javax.annotation.Priority; import javax.ws.rs.Priorities; import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.ClientRequestContext; import javax.ws.rs.client.ClientRequestFilter; import javax.ws.rs.client.ClientResponseContext; @@ -42,8 +42,6 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import javax.annotation.Priority; - import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.internal.LocalizationMessages; @@ -247,7 +245,7 @@ public void filter(ClientRequestContext request, ClientResponseContext response) } private String getCacheKey(ClientRequestContext request) { - return request.getUri().toString() + ":" + request.getMethod(); + return AuthenticationUtil.getCacheKey(request).toString() + ":" + request.getMethod(); } private void updateCache(ClientRequestContext request, boolean success, Type operation) {