Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id D3BFE200B8B for ; Tue, 4 Oct 2016 15:02:34 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id D255A160AC9; Tue, 4 Oct 2016 13:02:34 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id BBA43160AC5 for ; Tue, 4 Oct 2016 15:02:33 +0200 (CEST) Received: (qmail 91601 invoked by uid 500); 4 Oct 2016 13:02:32 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 91591 invoked by uid 99); 4 Oct 2016 13:02:32 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 04 Oct 2016 13:02:32 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 1745EC0DCC for ; Tue, 4 Oct 2016 13:02:32 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -1.199 X-Spam-Level: X-Spam-Status: No, score=-1.199 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-2.999] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id FU6Eoy2Bdis7 for ; Tue, 4 Oct 2016 13:02:29 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with ESMTP id 2899D5F393 for ; Tue, 4 Oct 2016 13:02:29 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 6E4C5E0069 for ; Tue, 4 Oct 2016 13:02:28 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 44C163A0141 for ; Tue, 4 Oct 2016 13:02:27 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1763275 - in /httpcomponents/httpclient/trunk/httpclient5-osgi/src: main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java Date: Tue, 04 Oct 2016 13:02:27 -0000 To: commits@hc.apache.org From: jsedding@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20161004130228.44C163A0141@svn01-us-west.apache.org> archived-at: Tue, 04 Oct 2016 13:02:35 -0000 Author: jsedding Date: Tue Oct 4 13:02:26 2016 New Revision: 1763275 URL: http://svn.apache.org/viewvc?rev=1763275&view=rev Log: HTTPCLIENT-1779: [OSGi] support NTLM proxy authentication Added: httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java (with props) Modified: httpcomponents/httpclient/trunk/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java Modified: httpcomponents/httpclient/trunk/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java?rev=1763275&r1=1763274&r2=1763275&view=diff ============================================================================== --- httpcomponents/httpclient/trunk/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java (original) +++ httpcomponents/httpclient/trunk/httpclient5-osgi/src/main/java/org/apache/hc/client5/http/osgi/impl/OSGiCredentialsProvider.java Tue Oct 4 13:02:26 2016 @@ -28,9 +28,12 @@ package org.apache.hc.client5.http.osgi. 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 */ final class OSGiCredentialsProvider implements CredentialsStore { - private List proxyConfigurations; + private static final Log log = LogFactory.getLog(OSGiCredentialsProvider.class); - public OSGiCredentialsProvider(final List 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 proxyConfigurations; + + OSGiCredentialsProvider(final List proxyConfigurations) { this.proxyConfigurations = proxyConfigurations; } @@ -58,15 +69,17 @@ final class OSGiCredentialsProvider impl * {@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 impl // 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); + } + } Added: httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java?rev=1763275&view=auto ============================================================================== --- httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java (added) +++ httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java Tue Oct 4 13:02:26 2016 @@ -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 + * . + * + */ +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 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; + } +} Propchange: httpcomponents/httpclient/trunk/httpclient5-osgi/src/test/java/org/apache/hc/client5/http/osgi/impl/OsgiCredentialsProviderTest.java ------------------------------------------------------------------------------ svn:eol-style = native