Skip to content

Commit 0c341a3

Browse files
agherardijansupol
authored andcommitted
HttpAuthenticationFilter should choose the strongest authentication mechanism (#3877)
Signed-off-by: agherardi <[email protected]>
1 parent 63b51ba commit 0c341a3

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,25 @@ public String getFilter(@Context HttpHeaders h) {
148148
return "GET";
149149
}
150150

151+
@GET
152+
@Path("basicAndDigest")
153+
public String getBasicAndDigest(@Context HttpHeaders h) {
154+
String value = h.getRequestHeaders().getFirst("Authorization");
155+
if (value == null) {
156+
throw new WebApplicationException(
157+
Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"")
158+
.header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
159+
.entity("Forbidden").build());
160+
} else if (value.startsWith("Basic")) {
161+
throw new WebApplicationException(
162+
Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"")
163+
.header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
164+
.entity("Digest authentication expected").build());
165+
}
166+
167+
return "GET";
168+
}
169+
151170
@GET
152171
@Path("noauth")
153172
public String get() {
@@ -301,6 +320,17 @@ public void testAuthGetWithClientFilter() {
301320
assertEquals("GET", r.request().get(String.class));
302321
}
303322

323+
@Test
324+
public void testAuthGetWithBasicAndDigestFilter() {
325+
ClientConfig cc = new ClientConfig();
326+
cc.connectorProvider(new ApacheConnectorProvider());
327+
Client client = ClientBuilder.newClient(cc);
328+
client.register(HttpAuthenticationFeature.universal("name", "password"));
329+
WebTarget r = client.target(getBaseUri()).path("test/basicAndDigest");
330+
331+
assertEquals("GET", r.request().get(String.class));
332+
}
333+
304334
@Test
305335
public void testAuthGetBasicNoChallenge() {
306336
ClientConfig cc = new ClientConfig();

core-client/src/main/java/org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,21 @@ public void filter(ClientRequestContext request, ClientResponseContext response)
196196
Type result = null; // which authentication is requested: BASIC or DIGEST
197197
boolean authenticate;
198198

199+
// If the server requests both BASIC and DIGEST, prefer DIGEST since it's stronger
200+
// (see https://tools.ietf.org/html/rfc2617#section-4.6)
199201
if (response.getStatus() == Response.Status.UNAUTHORIZED.getStatusCode()) {
200-
String authString = response.getHeaders().getFirst(HttpHeaders.WWW_AUTHENTICATE);
201-
if (authString != null) {
202-
final String upperCaseAuth = authString.trim().toUpperCase();
203-
if (upperCaseAuth.startsWith("BASIC")) {
204-
result = Type.BASIC;
205-
} else if (upperCaseAuth.startsWith("DIGEST")) {
206-
result = Type.DIGEST;
207-
} else {
202+
List<String> authStrings = response.getHeaders().get(HttpHeaders.WWW_AUTHENTICATE);
203+
if (authStrings != null) {
204+
for (String authString : authStrings) {
205+
final String upperCaseAuth = authString.trim().toUpperCase();
206+
if (result == null && upperCaseAuth.startsWith("BASIC")) {
207+
result = Type.BASIC;
208+
} else if (upperCaseAuth.startsWith("DIGEST")) {
209+
result = Type.DIGEST;
210+
}
211+
}
212+
213+
if (result == null) {
208214
// unknown authentication -> this filter cannot authenticate with this method
209215
return;
210216
}

0 commit comments

Comments
 (0)