Author: maartenc
Date: Mon Feb 22 22:37:54 2010
New Revision: 915099
URL: http://svn.apache.org/viewvc?rev=915099&view=rev
Log:
FIX: Authentication won't work in some situations (IVY-1168) (thanks to Sven
Walter)
Modified:
ant/ivy/core/trunk/CHANGES.txt
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/BasicURLHandler.java
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/CredentialsStore.java
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/HttpClientHandler.java
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/IvyAuthenticator.java
Modified: ant/ivy/core/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/CHANGES.txt?rev=915099&r1=915098&r2=915099&view=diff
==============================================================================
--- ant/ivy/core/trunk/CHANGES.txt (original)
+++ ant/ivy/core/trunk/CHANGES.txt Mon Feb 22 22:37:54 2010
@@ -92,6 +92,7 @@
Johan Stuyts
Jason Trump
Tjeerd Verhagen
+ Sven Walter
James P. White
Tom Widmer
John Williams
@@ -114,6 +115,7 @@
- IMPROVEMENT: Trace a message when a property file referenced from the
settings doesn't exixts (IVY-1074)
- IMPROVEMENT: use defaultconf in combination with defaultconfmapping
(IVY-1135) (thanks to Jon Schneider)
+- FIX: Authentication won't work in some situations (IVY-1168) (thanks to Sven
Walter)
- FIX: Using SFTP resolver with full pattern URL prevents use of dynamic
versions (IVY-1167) (thanks to Gregory Fernandez)
- FIX: parent.groupId is not resolved in maven 2 parser (IVY-1169) (thanks to
Achim Huegen)
- FIX: Creation of symlinks problematic in Windows with Cygwin 1.7 (IVY-1165)
Modified:
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/BasicURLHandler.java
URL:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/BasicURLHandler.java?rev=915099&r1=915098&r2=915099&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/BasicURLHandler.java
(original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/BasicURLHandler.java
Mon Feb 22 22:37:54 2010
@@ -50,18 +50,14 @@
}
}
- public BasicURLHandler() {
- Message.debug("installing " + IvyAuthenticator.INSTANCE.getClass());
// do not remove,
- // ensure
- // IvyAuthenticator
- // class loading!
- }
-
public URLInfo getURLInfo(URL url) {
return getURLInfo(url, 0);
}
public URLInfo getURLInfo(URL url, int timeout) {
+ // Install the IvyAuthenticator
+ IvyAuthenticator.install();
+
URLConnection con = null;
try {
url = normalizeToURL(url);
@@ -112,6 +108,9 @@
}
public InputStream openStream(URL url) throws IOException {
+ // Install the IvyAuthenticator
+ IvyAuthenticator.install();
+
URLConnection conn = null;
try {
url = normalizeToURL(url);
@@ -140,6 +139,9 @@
}
public void download(URL src, File dest, CopyProgressListener l) throws
IOException {
+ // Install the IvyAuthenticator
+ IvyAuthenticator.install();
+
URLConnection srcConn = null;
try {
src = normalizeToURL(src);
@@ -171,6 +173,9 @@
}
public void upload(File source, URL dest, CopyProgressListener l) throws
IOException {
+ // Install the IvyAuthenticator
+ IvyAuthenticator.install();
+
if (!"http".equals(dest.getProtocol()) &&
!"https".equals(dest.getProtocol())) {
throw new UnsupportedOperationException(
"URL repository only support HTTP PUT at the moment");
@@ -260,6 +265,4 @@
}
}
}
-
-
}
Modified:
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/CredentialsStore.java
URL:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/CredentialsStore.java?rev=915099&r1=915098&r2=915099&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/CredentialsStore.java
(original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/CredentialsStore.java
Mon Feb 22 22:37:54 2010
@@ -18,7 +18,9 @@
package org.apache.ivy.util.url;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
+import java.util.Set;
import org.apache.ivy.util.Credentials;
import org.apache.ivy.util.Message;
@@ -31,6 +33,7 @@
* A Map of Credentials objects keyed by the 'key' of the Credentials.
*/
private static final Map KEYRING = new HashMap();
+ private static final Set SECURED_HOSTS = new HashSet();
public static final CredentialsStore INSTANCE = new CredentialsStore();
@@ -44,13 +47,17 @@
Credentials c = new Credentials(realm, host, userName, passwd);
Message.debug("credentials added: " + c);
KEYRING.put(c.getKey(), c);
- // add also with host only, to be able to find credential with host
only
- // (useful for httpclient especially)
- KEYRING.put(c.getHost(), c);
+ SECURED_HOSTS.add(host);
}
public Credentials getCredentials(String realm, String host) {
- return (Credentials) KEYRING.get(Credentials.buildKey(realm, host));
+ String key = Credentials.buildKey(realm, host);
+ Message.debug("try to get credentials for: " + key);
+ return (Credentials) KEYRING.get(key);
+ }
+
+ public boolean hasCredentials(String host) {
+ return SECURED_HOSTS.contains(host);
}
}
Modified:
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/HttpClientHandler.java
URL:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/HttpClientHandler.java?rev=915099&r1=915098&r2=915099&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/HttpClientHandler.java
(original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/HttpClientHandler.java
Mon Feb 22 22:37:54 2010
@@ -29,6 +29,7 @@
import java.util.List;
import java.util.Locale;
+import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
@@ -37,14 +38,16 @@
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.AuthScheme;
import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
+import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.ivy.Ivy;
import org.apache.ivy.util.CopyProgressListener;
-import org.apache.ivy.util.Credentials;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.HostUtil;
import org.apache.ivy.util.Message;
@@ -292,13 +295,9 @@
"Apache Ivy/" + Ivy.getIvyVersion());
}
- Credentials c = getCredentials(url);
- if (c != null) {
- Message.debug("found credentials for " + url + ": " + c);
- httpClient.getState().setCredentials(
- new AuthScope(c.getHost(), AuthScope.ANY_PORT, c.getRealm()),
- new NTCredentials(c.getUserName(), c.getPasswd(),
- HostUtil.getLocalHostName(), c.getRealm()));
+ if (useAuthentication(url)) {
+ httpClient.getParams().setParameter(CredentialsProvider.PROVIDER,
+ new IvyCredentialsProvider());
}
return httpClient;
@@ -309,11 +308,7 @@
}
private boolean useAuthentication(URL url) {
- return getCredentials(url) != null;
- }
-
- private Credentials getCredentials(URL url) {
- return CredentialsStore.INSTANCE.getCredentials(null, url.getHost());
+ return CredentialsStore.INSTANCE.hasCredentials(url.getHost());
}
private boolean useProxyAuthentication() {
@@ -429,4 +424,22 @@
int getHttpClientMajorVersion();
}
+
+ private static class IvyCredentialsProvider implements CredentialsProvider
{
+
+ public Credentials getCredentials(AuthScheme scheme, String host, int
port, boolean proxy)
+ throws CredentialsNotAvailableException {
+ String realm = scheme.getRealm();
+
+ org.apache.ivy.util.Credentials c =
(org.apache.ivy.util.Credentials)
+ CredentialsStore.INSTANCE.getCredentials(realm, host);
+ if (c != null) {
+ return new NTCredentials(c.getUserName(), c.getPasswd(),
+ HostUtil.getLocalHostName(), c.getRealm());
+ }
+
+ return null;
+ }
+
+ }
}
Modified:
ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/IvyAuthenticator.java
URL:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/IvyAuthenticator.java?rev=915099&r1=915098&r2=915099&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/IvyAuthenticator.java
(original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/util/url/IvyAuthenticator.java
Mon Feb 22 22:37:54 2010
@@ -17,6 +17,7 @@
*/
package org.apache.ivy.util.url;
+import java.lang.reflect.Field;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
@@ -28,18 +29,36 @@
*/
public final class IvyAuthenticator extends Authenticator {
+ private Authenticator original;
+
/**
- * The sole instance.
+ * Private c'tor to prevent instantiation.
*/
- public static final IvyAuthenticator INSTANCE = new IvyAuthenticator();
-
+ private IvyAuthenticator(Authenticator original) {
+ this.original = original;
+ }
+
/**
- * Private c'tor to prevent instantiation. Also installs this as the
default Authenticator to
- * use by the JVM.
+ * Installs an <tt>IvyAuthenticator</tt> as default <tt>Authenticator</tt>.
+ * Call this method before opening HTTP(S) connections to enable Ivy
+ * authentication.
*/
- private IvyAuthenticator() {
- // Install this as the default Authenticator object.
- Authenticator.setDefault(this);
+ public static void install() {
+ // We will try to use the original authenticator as backup
authenticator.
+ // Since there is no getter available, so try to use some reflection
to
+ // obtain it. If that doesn't work, assume there is no original
authenticator
+ Authenticator original = null;
+
+ try {
+ Field f = Authenticator.class.getDeclaredField("theAuthenticator");
+ original = (Authenticator) f.get(null);
+ } catch (Throwable t) {
+ Message.debug("Error occured while getting the original
authenticator!");
+ }
+
+ if (!(original instanceof IvyAuthenticator)) {
+ Authenticator.setDefault(new IvyAuthenticator(original));
+ }
}
// API ******************************************************************
@@ -68,6 +87,17 @@
}
}
+ if ((result == null) && (original != null)) {
+ Authenticator.setDefault(original);
+ try {
+ result =
Authenticator.requestPasswordAuthentication(getRequestingHost(),
+ getRequestingSite(), getRequestingPort(),
getRequestingProtocol(),
+ getRequestingPrompt(), getRequestingScheme());
+ } finally {
+ Authenticator.setDefault(this);
+ }
+ }
+
return result;
}