diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/SystemDefaultCredentialsProvider.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/SystemDefaultCredentialsProvider.java index 4812e11a12..bbae36a139 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/SystemDefaultCredentialsProvider.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/SystemDefaultCredentialsProvider.java @@ -34,6 +34,7 @@ import java.net.URL; import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.ChallengeType; import org.apache.hc.client5.http.auth.Credentials; import org.apache.hc.client5.http.auth.CredentialsStore; import org.apache.hc.client5.http.auth.UsernamePasswordCredentials; @@ -106,13 +107,18 @@ public Credentials getCredentials(final AuthScope authScope, final HttpContext c if (host != null) { final HttpClientContext clientContext = context != null ? HttpClientContext.cast(context) : null; final String protocol = authScope.getProtocol() != null ? authScope.getProtocol() : (authScope.getPort() == 443 ? URIScheme.HTTPS.id : URIScheme.HTTP.id); - final PasswordAuthentication serverCreds = getSystemCreds(protocol, authScope, Authenticator.RequestorType.SERVER, clientContext); - if (serverCreds != null) { - return new UsernamePasswordCredentials(serverCreds.getUserName(), serverCreds.getPassword()); + final ChallengeType challengeType = authScope.getChallengeType(); + if (challengeType != ChallengeType.PROXY) { + final PasswordAuthentication serverCreds = getSystemCreds(protocol, authScope, Authenticator.RequestorType.SERVER, clientContext); + if (serverCreds != null) { + return new UsernamePasswordCredentials(serverCreds.getUserName(), serverCreds.getPassword()); + } } - final PasswordAuthentication proxyCreds = getSystemCreds(protocol, authScope, Authenticator.RequestorType.PROXY, clientContext); - if (proxyCreds != null) { - return new UsernamePasswordCredentials(proxyCreds.getUserName(), proxyCreds.getPassword()); + if (challengeType != ChallengeType.TARGET) { + final PasswordAuthentication proxyCreds = getSystemCreds(protocol, authScope, Authenticator.RequestorType.PROXY, clientContext); + if (proxyCreds != null) { + return new UsernamePasswordCredentials(proxyCreds.getUserName(), proxyCreds.getPassword()); + } } } return null; diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java index ce71b055bd..8924ee9a2f 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/auth/TestSystemDefaultCredentialsProvider.java @@ -34,6 +34,7 @@ import java.util.Locale; import org.apache.hc.client5.http.auth.AuthScope; +import org.apache.hc.client5.http.auth.ChallengeType; import org.apache.hc.client5.http.auth.Credentials; import org.apache.hc.client5.http.auth.StandardAuthScheme; import org.apache.hc.client5.http.classic.methods.HttpGet; @@ -129,6 +130,66 @@ void testSystemCredentialsProviderNoContext() { Assertions.assertEquals(AUTH1.getUserName(), receivedCredentials.getUserPrincipal().getName()); } + @Test + void testSystemCredentialsProviderNoProxyCredentialsForTarget() { + + final AuthenticatorDelegate authenticatorDelegate = installProxyAuthenticator(AUTH1); + + final AuthScope authScope = new AuthScope(TARGET_SCHEME1, TARGET_HOST1, TARGET_PORT1, PROMPT1, + StandardAuthScheme.BASIC, ChallengeType.TARGET); + + final Credentials receivedCredentials = + new SystemDefaultCredentialsProvider().getCredentials(authScope, HttpClientContext.create()); + + Mockito.verify(authenticatorDelegate, Mockito.never()).getPasswordAuthentication(ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.anyInt(), ArgumentMatchers.any(), ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.eq(RequestorType.PROXY)); + Assertions.assertNull(receivedCredentials); + } + + @Test + void testSystemCredentialsProviderProxyCredentialsForProxy() { + + final AuthenticatorDelegate authenticatorDelegate = installProxyAuthenticator(AUTH1); + + final AuthScope authScope = new AuthScope(PROXY_PROTOCOL1, PROXY_HOST1, PROXY_PORT1, PROMPT1, + StandardAuthScheme.BASIC, ChallengeType.PROXY); + + final Credentials receivedCredentials = + new SystemDefaultCredentialsProvider().getCredentials(authScope, HttpClientContext.create()); + + Mockito.verify(authenticatorDelegate, Mockito.never()).getPasswordAuthentication(ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.anyInt(), ArgumentMatchers.any(), ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.eq(RequestorType.SERVER)); + Assertions.assertNotNull(receivedCredentials); + Assertions.assertEquals(AUTH1.getUserName(), receivedCredentials.getUserPrincipal().getName()); + } + + @Test + void testSystemCredentialsProviderProxyCredentialsForUntypedScope() { + + installProxyAuthenticator(AUTH1); + + final AuthScope authScope = new AuthScope(PROXY_PROTOCOL1, PROXY_HOST1, PROXY_PORT1, PROMPT1, StandardAuthScheme.BASIC); + + final Credentials receivedCredentials = + new SystemDefaultCredentialsProvider().getCredentials(authScope, HttpClientContext.create()); + + Assertions.assertNotNull(receivedCredentials); + Assertions.assertEquals(AUTH1.getUserName(), receivedCredentials.getUserPrincipal().getName()); + } + + private AuthenticatorDelegate installProxyAuthenticator(final PasswordAuthentication proxyAuthentication) { + final AuthenticatorDelegate authenticatorDelegate = Mockito.mock(AuthenticatorDelegate.class); + Mockito.when(authenticatorDelegate.getPasswordAuthentication(ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.anyInt(), + ArgumentMatchers.any(), ArgumentMatchers.any(), + ArgumentMatchers.any(), ArgumentMatchers.any(), + ArgumentMatchers.eq(RequestorType.PROXY))).thenReturn(proxyAuthentication); + Authenticator.setDefault(new DelegatedAuthenticator(authenticatorDelegate)); + return authenticatorDelegate; + } + private AuthenticatorDelegate installAuthenticator(final PasswordAuthentication returedAuthentication) { final AuthenticatorDelegate authenticatorDelegate = Mockito.mock(AuthenticatorDelegate.class); Mockito.when(authenticatorDelegate.getPasswordAuthentication(ArgumentMatchers.anyString(),