Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public Executor auth(final String host, final Credentials creds) {

public Executor authPreemptive(final HttpHost host) {
if (this.credentialsStore != null) {
final Credentials credentials = this.credentialsStore.getCredentials(new AuthScope(host));
final Credentials credentials = this.credentialsStore.getCredentials(new AuthScope(host), null);
if (credentials == null) {
final BasicScheme basicScheme = new BasicScheme();
basicScheme.initPreemptive(credentials);
Expand All @@ -165,7 +165,7 @@ public Executor authPreemptive(final String host) {

public Executor authPreemptiveProxy(final HttpHost proxy) {
if (this.credentialsStore != null) {
final Credentials credentials = this.credentialsStore.getCredentials(new AuthScope(proxy));
final Credentials credentials = this.credentialsStore.getCredentials(new AuthScope(proxy), null);
if (credentials == null) {
final BasicScheme basicScheme = new BasicScheme();
basicScheme.initPreemptive(credentials);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.hc.client5.http.auth.CredentialsStore;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.osgi.services.ProxyConfiguration;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

Expand Down Expand Up @@ -64,7 +65,7 @@ public void setCredentials(final AuthScope authscope, final Credentials credenti
* {@inheritDoc}
*/
@Override
public Credentials getCredentials(final AuthScope authscope) {
public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
// iterate over all active proxy configurations at the moment of getting the credential
for (final ServiceRegistration<ProxyConfiguration> registration : registeredConfigurations.values()) {
final ProxyConfiguration proxyConfiguration = bundleContext.getService(registration.getReference());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
*/
package org.apache.hc.client5.http.auth;

import org.apache.hc.core5.http.protocol.HttpContext;

/**
* Provider of authentication credentials.
* <p>
Expand All @@ -42,8 +44,10 @@ public interface CredentialsProvider {
* if available.
*
* @param authscope the {@link AuthScope authentication scope}
* @param context the {@link HttpContext http context}
* @return the credentials
* @since 5.0
*/
Credentials getCredentials(AuthScope authscope);
Credentials getCredentials(AuthScope authscope, HttpContext context);

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public interface CredentialsStore extends CredentialsProvider {
* @param credentials the authentication {@link Credentials credentials}
* for the given scope.
*
* @see #getCredentials(AuthScope)
* @see #getCredentials(AuthScope, HttpContext)
*/
void setCredentials(AuthScope authscope, Credentials credentials);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ public boolean isResponseReady(
Args.notNull(host, "Auth host");
Args.notNull(credentialsProvider, "CredentialsProvider");

final Credentials credentials = credentialsProvider.getCredentials(new AuthScope(host, getRealm(), getName()));
final Credentials credentials =
credentialsProvider.getCredentials(new AuthScope(host, getRealm(), getName()), context);
if (credentials != null) {
this.username = credentials.getUserPrincipal().getName();
this.password = credentials.getPassword();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ public boolean isResponseReady(
Args.notNull(host, "Auth host");
Args.notNull(credentialsProvider, "CredentialsProvider");

final Credentials credentials = credentialsProvider.getCredentials(new AuthScope(host, getRealm(), getName()));
final Credentials credentials =
credentialsProvider.getCredentials(new AuthScope(host, getRealm(), getName()), context);
if (credentials != null) {
this.username = credentials.getUserPrincipal().getName();
this.password = credentials.getPassword();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ public boolean isResponseReady(
Args.notNull(host, "Auth host");
Args.notNull(credentialsProvider, "CredentialsProvider");

final Credentials credentials = credentialsProvider.getCredentials(new AuthScope(host, null, getName()));
final Credentials credentials =
credentialsProvider.getCredentials(new AuthScope(host, null, getName()), context);
if (credentials instanceof KerberosCredentials) {
this.gssCredential = ((KerberosCredentials) credentials).getGSSCredential();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ public boolean isResponseReady(
Args.notNull(host, "Auth host");
Args.notNull(credentialsProvider, "CredentialsProvider");

final Credentials credentials = credentialsProvider.getCredentials(new AuthScope(host, null, getName()));
final Credentials credentials =
credentialsProvider.getCredentials(new AuthScope(host, null, getName()), context);
if (credentials instanceof NTCredentials) {
this.credentials = (NTCredentials) credentials;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
package org.apache.hc.client5.http.impl.auth;

import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -41,6 +43,9 @@
import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
import org.apache.hc.core5.annotation.ThreadSafe;
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.HttpCoreContext;
import org.apache.hc.core5.util.Args;

/**
Expand Down Expand Up @@ -88,35 +93,55 @@ public void setCredentials(final AuthScope authscope, final Credentials credenti

private static PasswordAuthentication getSystemCreds(
final AuthScope authscope,
final Authenticator.RequestorType requestorType) {
final Authenticator.RequestorType requestorType,
final HttpContext context) {
final String hostname = authscope.getHost();
final int port = authscope.getPort();
final HttpHost origin = authscope.getOrigin();
final String protocol = origin != null ? origin.getSchemeName() :
(port == 443 ? "https" : "http");

final URL targetHostURL = getTargetHostURL(context);
// use null addr, because the authentication fails if it does not exactly match the expected realm's host
return Authenticator.requestPasswordAuthentication(
hostname,
null,
port,
protocol,
null,
authscope.getRealm(),
translateScheme(authscope.getScheme()),
null,
targetHostURL,
requestorType);
}

private static URL getTargetHostURL(final HttpContext context) {
if (context == null) {
// Fluent case.
return null;
}

final HttpRequest httpRequest = (HttpRequest)context.getAttribute(HttpCoreContext.HTTP_REQUEST);
final String uri = httpRequest.getRequestLine().getUri();
try {
return new URL(uri);
} catch (final MalformedURLException e) {
throw new IllegalStateException("Unexpected request url format: " + uri, e);
}
}

@Override
public Credentials getCredentials(final AuthScope authscope) {
public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
Args.notNull(authscope, "Auth scope");
final Credentials localcreds = internal.getCredentials(authscope);
final Credentials localcreds = internal.getCredentials(authscope, context);
if (localcreds != null) {
return localcreds;
}
final String host = authscope.getHost();
if (host != null) {
PasswordAuthentication systemcreds = getSystemCreds(authscope, Authenticator.RequestorType.SERVER);
PasswordAuthentication systemcreds =
getSystemCreds(authscope, Authenticator.RequestorType.SERVER, context);
if (systemcreds == null) {
systemcreds = getSystemCreds(authscope, Authenticator.RequestorType.PROXY);
systemcreds = getSystemCreds(authscope, Authenticator.RequestorType.PROXY, context);
}
if (systemcreds == null) {
final String proxyHost = System.getProperty("http.proxyHost");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,12 @@ protected HttpHost determineProxy(
}
final InetSocketAddress isa = (InetSocketAddress) p.address();
// assume default scheme (http)
result = new HttpHost(getHost(isa), isa.getPort());
result = new HttpHost(isa.getAddress(), isa.getHostString(), isa.getPort(), null);
}

return result;
}

private String getHost(final InetSocketAddress isa) {

//@@@ Will this work with literal IPv6 addresses, or do we
//@@@ need to wrap these in [] for the string representation?
//@@@ Having it in this method at least allows for easy workarounds.
return isa.isUnresolved() ?
isa.getHostName() : isa.getAddress().getHostAddress();

}

private Proxy chooseProxy(final List<Proxy> proxies) {
Proxy result = null;
// check the list for one we can use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.CredentialsStore;
import org.apache.hc.core5.annotation.ThreadSafe;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.apache.hc.core5.util.Args;

/**
Expand Down Expand Up @@ -94,7 +95,8 @@ private static Credentials matchCredentials(
}

@Override
public Credentials getCredentials(final AuthScope authscope) {
public Credentials getCredentials(final AuthScope authscope,
final HttpContext httpContext) {
Args.notNull(authscope, "Authentication scope");
return matchCredentials(this.credMap, authscope);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,30 @@ public void testBasicCredentialsProviderCredentials() {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
state.setCredentials(SCOPE1, CREDS1);
state.setCredentials(SCOPE2, CREDS2);
Assert.assertEquals(CREDS1, state.getCredentials(SCOPE1));
Assert.assertEquals(CREDS2, state.getCredentials(SCOPE2));
Assert.assertEquals(CREDS1, state.getCredentials(SCOPE1, null));
Assert.assertEquals(CREDS2, state.getCredentials(SCOPE2, null));
}

@Test
public void testBasicCredentialsProviderNoCredentials() {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
Assert.assertEquals(null, state.getCredentials(BOGUS));
Assert.assertEquals(null, state.getCredentials(BOGUS, null));
}

@Test
public void testBasicCredentialsProviderDefaultCredentials() {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
state.setCredentials(AuthScope.ANY, CREDS1);
state.setCredentials(SCOPE2, CREDS2);
Assert.assertEquals(CREDS1, state.getCredentials(BOGUS));
Assert.assertEquals(CREDS1, state.getCredentials(BOGUS, null));
}

@Test
public void testDefaultCredentials() throws Exception {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
final Credentials expected = new UsernamePasswordCredentials("name", "pass".toCharArray());
state.setCredentials(AuthScope.ANY, expected);
final Credentials got = state.getCredentials(DEFSCOPE);
final Credentials got = state.getCredentials(DEFSCOPE, null);
Assert.assertEquals(got, expected);
}

Expand All @@ -90,7 +90,7 @@ public void testRealmCredentials() throws Exception {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
final Credentials expected = new UsernamePasswordCredentials("name", "pass".toCharArray());
state.setCredentials(DEFSCOPE, expected);
final Credentials got = state.getCredentials(DEFSCOPE);
final Credentials got = state.getCredentials(DEFSCOPE, null);
Assert.assertEquals(expected, got);
}

Expand All @@ -100,7 +100,7 @@ public void testHostCredentials() throws Exception {
final Credentials expected = new UsernamePasswordCredentials("name", "pass".toCharArray());
state.setCredentials(
new AuthScope("host", AuthScope.ANY_PORT, AuthScope.ANY_REALM), expected);
final Credentials got = state.getCredentials(DEFSCOPE);
final Credentials got = state.getCredentials(DEFSCOPE, null);
Assert.assertEquals(expected, got);
}

Expand All @@ -111,7 +111,7 @@ public void testWrongHostCredentials() throws Exception {
state.setCredentials(
new AuthScope("host1", AuthScope.ANY_PORT, "realm"), expected);
final Credentials got = state.getCredentials(
new AuthScope("host2", AuthScope.ANY_PORT, "realm"));
new AuthScope("host2", AuthScope.ANY_PORT, "realm"), null);
Assert.assertNotSame(expected, got);
}

Expand All @@ -122,7 +122,7 @@ public void testWrongRealmCredentials() throws Exception {
state.setCredentials(
new AuthScope("host", AuthScope.ANY_PORT, "realm1"), cred);
final Credentials got = state.getCredentials(
new AuthScope("host", AuthScope.ANY_PORT, "realm2"));
new AuthScope("host", AuthScope.ANY_PORT, "realm2"), null);
Assert.assertNotSame(cred, got);
}

Expand All @@ -132,7 +132,7 @@ public void testMixedCaseHostname() throws Exception {
final BasicCredentialsProvider state = new BasicCredentialsProvider();
final Credentials expected = new UsernamePasswordCredentials("name", "pass".toCharArray());
state.setCredentials(new AuthScope(httpHost), expected);
final Credentials got = state.getCredentials(DEFSCOPE);
final Credentials got = state.getCredentials(DEFSCOPE, null);
Assert.assertEquals(expected, got);
}

Expand All @@ -152,17 +152,17 @@ public void testCredentialsMatching() {
state.setCredentials(scope3, creds3);

Credentials got = state.getCredentials(
new AuthScope("someotherhost", 80, "someotherrealm", "basic"));
new AuthScope("someotherhost", 80, "someotherrealm", "basic"), null);
Credentials expected = creds1;
Assert.assertEquals(expected, got);

got = state.getCredentials(
new AuthScope("someotherhost", 80, "somerealm", "basic"));
new AuthScope("someotherhost", 80, "somerealm", "basic"), null);
expected = creds2;
Assert.assertEquals(expected, got);

got = state.getCredentials(
new AuthScope("somehost", 80, "someotherrealm", "basic"));
new AuthScope("somehost", 80, "someotherrealm", "basic"), null);
expected = creds3;
Assert.assertEquals(expected, got);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@ public void testAuthentication() throws Exception {
response.addHeader(new BasicHeader(HttpHeaders.WWW_AUTHENTICATE, "whatever realm=\"realm1\", stuff=\"1234\""));

final Credentials credentials = new UsernamePasswordCredentials("user", "pass".toCharArray());
Mockito.when(this.credentialsProvider.getCredentials(Mockito.<AuthScope>any())).thenReturn(credentials);
Mockito.when(this.credentialsProvider.getCredentials(Mockito.<AuthScope>any(),
Mockito.<HttpContext>any())).thenReturn(credentials);

final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();

Assert.assertTrue(this.httpAuthenticator.prepareAuthResponse(
host, ChallengeType.TARGET, response, authStrategy, this.authExchange, this.context));
Assert.assertTrue(this.httpAuthenticator.prepareAuthResponse(host, ChallengeType.TARGET, response, authStrategy,
this.authExchange, this.context));
Assert.assertEquals(AuthExchange.State.CHALLENGED, this.authExchange.getState());

final Queue<AuthScheme> options = this.authExchange.getAuthOptions();
Expand All @@ -182,17 +183,19 @@ public void testAuthentication() throws Exception {
@Test
public void testAuthenticationCredentialsForBasic() throws Exception {
final HttpHost host = new HttpHost("somehost", 80);
final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
final HttpResponse response =
new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
response.addHeader(new BasicHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"test\""));
response.addHeader(new BasicHeader(HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"realm1\", nonce=\"1234\""));

final Credentials credentials = new UsernamePasswordCredentials("user", "pass".toCharArray());
Mockito.when(this.credentialsProvider.getCredentials(new AuthScope(host, "test", "basic"))).thenReturn(credentials);
Mockito.when(this.credentialsProvider.getCredentials(Mockito.eq(new AuthScope(host, "test", "basic")),
Mockito.<HttpContext>any())).thenReturn(credentials);

final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();

Assert.assertTrue(this.httpAuthenticator.prepareAuthResponse(
host, ChallengeType.TARGET, response, authStrategy, this.authExchange, this.context));
Assert.assertTrue(this.httpAuthenticator.prepareAuthResponse(host, ChallengeType.TARGET, response, authStrategy,
this.authExchange, this.context));
Assert.assertEquals(AuthExchange.State.CHALLENGED, this.authExchange.getState());

final Queue<AuthScheme> options = this.authExchange.getAuthOptions();
Expand Down Expand Up @@ -322,7 +325,8 @@ public void testAuthenticationNoMatchingChallenge() throws Exception {
response.addHeader(new BasicHeader(HttpHeaders.WWW_AUTHENTICATE, "whatever realm=\"realm1\", stuff=\"1234\""));

final Credentials credentials = new UsernamePasswordCredentials("user", "pass".toCharArray());
Mockito.when(this.credentialsProvider.getCredentials(new AuthScope(host, "realm1", "digest"))).thenReturn(credentials);
Mockito.when(this.credentialsProvider.getCredentials(Mockito.eq(new AuthScope(host, "realm1", "digest")),
Mockito.<HttpContext>any())).thenReturn(credentials);

final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy();

Expand Down
Loading