HTTPCLIENT-1779: [OSGi] support NTLM proxy authentication
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1763275 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
71d0567376
commit
6ca80b650e
|
@ -28,9 +28,12 @@ package org.apache.hc.client5.http.osgi.impl;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.CredentialsStore;
|
||||
import org.apache.hc.client5.http.auth.NTCredentials;
|
||||
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;
|
||||
|
@ -40,9 +43,17 @@ import org.apache.hc.core5.http.protocol.HttpContext;
|
|||
*/
|
||||
final class OSGiCredentialsProvider implements CredentialsStore {
|
||||
|
||||
private List<ProxyConfiguration> proxyConfigurations;
|
||||
private static final Log log = LogFactory.getLog(OSGiCredentialsProvider.class);
|
||||
|
||||
public OSGiCredentialsProvider(final List<ProxyConfiguration> proxyConfigurations) {
|
||||
private static final int HOST_AND_PORT_MATCH = 12;
|
||||
|
||||
private static final String BASIC_SCHEME_NAME = "BASIC";
|
||||
|
||||
private static final String NTLM_SCHEME_NAME = "NTLM";
|
||||
|
||||
private final List<ProxyConfiguration> proxyConfigurations;
|
||||
|
||||
OSGiCredentialsProvider(final List<ProxyConfiguration> proxyConfigurations) {
|
||||
this.proxyConfigurations = proxyConfigurations;
|
||||
}
|
||||
|
||||
|
@ -58,15 +69,17 @@ final class OSGiCredentialsProvider implements CredentialsStore {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Credentials getCredentials(final AuthScope authscope, final HttpContext context) {
|
||||
public Credentials getCredentials(final AuthScope authScope, final HttpContext context) {
|
||||
// iterate over all active proxy configurations at the moment of getting the credential
|
||||
for (final ProxyConfiguration proxyConfiguration : proxyConfigurations) {
|
||||
if (proxyConfiguration.isEnabled()) {
|
||||
final AuthScope actual = new AuthScope(proxyConfiguration.getHostname(), proxyConfiguration.getPort());
|
||||
if (authscope.match(actual) >= 12) {
|
||||
final String username = proxyConfiguration.getUsername();
|
||||
final String password = proxyConfiguration.getPassword();
|
||||
return new UsernamePasswordCredentials(username, password != null ? password.toCharArray() : null);
|
||||
for (final ProxyConfiguration config : proxyConfigurations) {
|
||||
if (config.isEnabled() && isSuitable(config, authScope)) {
|
||||
final String scheme = authScope.getScheme();
|
||||
if (BASIC_SCHEME_NAME.equals(scheme)) {
|
||||
return new UsernamePasswordCredentials(config.getUsername(), config.getPassword().toCharArray());
|
||||
} else if (NTLM_SCHEME_NAME.equals(scheme)) {
|
||||
return createNTCredentials(config);
|
||||
} else {
|
||||
log.debug("credentials requested for unsupported authentication scheme " + scheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,4 +95,24 @@ final class OSGiCredentialsProvider implements CredentialsStore {
|
|||
// do nothing, not used in this version
|
||||
}
|
||||
|
||||
// suitable configurations match at least the host and port of the AuthScope
|
||||
private boolean isSuitable(final ProxyConfiguration config, final AuthScope authScope) {
|
||||
return authScope.match(new AuthScope(config.getHostname(), config.getPort())) >= HOST_AND_PORT_MATCH;
|
||||
}
|
||||
|
||||
private static Credentials createNTCredentials(final ProxyConfiguration config) {
|
||||
final String domainAndUsername = config.getUsername();
|
||||
final String username;
|
||||
final String domain;
|
||||
final int index = domainAndUsername.indexOf("\\");
|
||||
if (index > -1) {
|
||||
username = domainAndUsername.substring(index + 1);
|
||||
domain = domainAndUsername.substring(0, index);
|
||||
} else {
|
||||
username = domainAndUsername;
|
||||
domain = null;
|
||||
}
|
||||
return new NTCredentials(username, config.getPassword().toCharArray(), null, domain);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
package org.apache.hc.client5.http.osgi.impl;
|
||||
|
||||
import org.apache.hc.client5.http.auth.AuthScope;
|
||||
import org.apache.hc.client5.http.auth.Credentials;
|
||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||
import org.apache.hc.client5.http.auth.NTCredentials;
|
||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.hc.client5.http.osgi.services.ProxyConfiguration;
|
||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class OsgiCredentialsProviderTest {
|
||||
|
||||
private static final String HOST = "proxy.example.org";
|
||||
|
||||
private static final int PORT = 8080;
|
||||
|
||||
private static final HttpContext HTTP_CONTEXT = new BasicHttpContext();
|
||||
|
||||
|
||||
private final ProxyConfiguration proxyConfigWithDomain = proxy("DOMAIN\\user", "secret");
|
||||
|
||||
@Test
|
||||
public void basicAuthentication() {
|
||||
final CredentialsProvider provider = credentialsProvider(proxy("user", "secret"));
|
||||
final Credentials credentials = provider.getCredentials(new AuthScope(HOST, PORT, null, "BASIC"), HTTP_CONTEXT);
|
||||
assertThat(credentials, instanceOf(UsernamePasswordCredentials.class));
|
||||
assertCredentials((UsernamePasswordCredentials) credentials, "user", "secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ntlmAuthenticationWithoutDomain() {
|
||||
final CredentialsProvider provider = credentialsProvider(proxy("user", "secret"));
|
||||
final Credentials credentials = provider.getCredentials(new AuthScope(HOST, PORT, null, "NTLM"), HTTP_CONTEXT);
|
||||
assertThat(credentials, instanceOf(NTCredentials.class));
|
||||
assertCredentials((NTCredentials) credentials, "user", "secret", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ntlmAuthenticationWithDomain() {
|
||||
final CredentialsProvider provider = credentialsProvider(proxy("DOMAIN\\user", "secret"));
|
||||
final Credentials credentials = provider.getCredentials(new AuthScope(HOST, PORT, null, "NTLM"), HTTP_CONTEXT);
|
||||
assertThat(credentials, instanceOf(NTCredentials.class));
|
||||
assertCredentials((NTCredentials) credentials, "user", "secret", "DOMAIN");
|
||||
}
|
||||
|
||||
private CredentialsProvider credentialsProvider(final ProxyConfiguration... proxies) {
|
||||
return new OSGiCredentialsProvider(asList(proxies));
|
||||
}
|
||||
|
||||
private void assertCredentials(final UsernamePasswordCredentials credentials, final String user, final String password) {
|
||||
assertThat("Username mismatch", credentials.getUserName(), equalTo(user));
|
||||
assertThat("Password mismatch", credentials.getPassword(), equalTo(password.toCharArray()));
|
||||
}
|
||||
|
||||
private void assertCredentials(final NTCredentials credentials, final String user, final String password, final String domain) {
|
||||
assertThat("Username mismatch", credentials.getUserName(), equalTo(user));
|
||||
assertThat("Password mismatch", credentials.getPassword(), equalTo(password.toCharArray()));
|
||||
assertThat("Domain mismatch", credentials.getDomain(), equalTo(domain));
|
||||
}
|
||||
|
||||
private ProxyConfiguration proxy(final String username, final String password) {
|
||||
final OSGiProxyConfiguration proxyConfiguration = new OSGiProxyConfiguration();
|
||||
final Hashtable<String, Object> config = new Hashtable<>();
|
||||
config.put("proxy.enabled", true);
|
||||
config.put("proxy.host", HOST);
|
||||
config.put("proxy.port", PORT);
|
||||
config.put("proxy.user", username);
|
||||
config.put("proxy.password", password);
|
||||
config.put("proxy.exceptions", new String[0]);
|
||||
proxyConfiguration.update(config);
|
||||
return proxyConfiguration;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue