diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java b/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java index ee7fe5e39..88636dd2d 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java @@ -26,6 +26,9 @@ */ package org.apache.http.impl.auth; +import java.net.InetAddress; +import java.net.UnknownHostException; + import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -67,6 +70,7 @@ public abstract class GGSSchemeBase extends AuthSchemeBase { private final Base64 base64codec; private final boolean stripPort; + private final boolean useCanonicalHostname; /** Authentication process state */ private State state; @@ -74,15 +78,20 @@ public abstract class GGSSchemeBase extends AuthSchemeBase { /** base64 decoded challenge **/ private byte[] token; - GGSSchemeBase(final boolean stripPort) { + GGSSchemeBase(final boolean stripPort, final boolean useCanonicalHostname) { super(); this.base64codec = new Base64(0); this.stripPort = stripPort; + this.useCanonicalHostname = useCanonicalHostname; this.state = State.UNINITIATED; } + GGSSchemeBase(final boolean stripPort) { + this(stripPort, true); + } + GGSSchemeBase() { - this(false); + this(true,true); } protected GSSManager getManager() { @@ -151,10 +160,22 @@ public abstract class GGSSchemeBase extends AuthSchemeBase { host = route.getTargetHost(); } final String authServer; - if (!this.stripPort && host.getPort() > 0) { - authServer = host.toHostString(); + String hostname = host.getHostName(); + + if (this.useCanonicalHostname){ + try { + //TODO: uncomment this statement and delete the resolveCanonicalHostname, + //TODO: as soon canonical hostname resolving is implemented in the SystemDefaultDnsResolver + //final DnsResolver dnsResolver = SystemDefaultDnsResolver.INSTANCE; + //hostname = dnsResolver.resolveCanonicalHostname(host.getHostName()); + hostname = resolveCanonicalHostname(hostname); + } catch (UnknownHostException ignore){ + } + } + if (this.stripPort) { // || host.getPort()==80 || host.getPort()==443) { + authServer = hostname; } else { - authServer = host.getHostName(); + authServer = hostname + ":" + host.getPort(); } if (log.isDebugEnabled()) { @@ -215,4 +236,13 @@ public abstract class GGSSchemeBase extends AuthSchemeBase { } } + private String resolveCanonicalHostname(final String host) throws UnknownHostException { + final InetAddress in = InetAddress.getByName(host); + final String canonicalServer = in.getCanonicalHostName(); + if (in.getHostAddress().contentEquals(canonicalServer)) { + return host; + } + return canonicalServer; + } + } diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java index 1d1c7136d..0d43e5faa 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java @@ -46,12 +46,19 @@ public class KerberosScheme extends GGSSchemeBase { private static final String KERBEROS_OID = "1.2.840.113554.1.2.2"; + /** + * @since 4.4 + */ + public KerberosScheme(final boolean stripPort, final boolean useCanonicalHostname) { + super(stripPort, useCanonicalHostname); + } + public KerberosScheme(final boolean stripPort) { super(stripPort); } public KerberosScheme() { - super(false); + super(); } @Override diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.java b/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.java index cea456e30..431258e96 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.java @@ -44,28 +44,43 @@ import org.apache.http.protocol.HttpContext; public class KerberosSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final boolean stripPort; + private final boolean useCanonicalHostname; + + /** + * @since 4.4 + */ + public KerberosSchemeFactory(final boolean stripPort, final boolean useCanonicalHostname) { + super(); + this.stripPort = stripPort; + this.useCanonicalHostname = useCanonicalHostname; + } public KerberosSchemeFactory(final boolean stripPort) { super(); this.stripPort = stripPort; + this.useCanonicalHostname = true; } public KerberosSchemeFactory() { - this(false); + this(true, true); } public boolean isStripPort() { return stripPort; } + public boolean isUseCanonicalHostname() { + return useCanonicalHostname; + } + @Override public AuthScheme newInstance(final HttpParams params) { - return new KerberosScheme(this.stripPort); + return new KerberosScheme(this.stripPort, this.useCanonicalHostname); } @Override public AuthScheme create(final HttpContext context) { - return new KerberosScheme(this.stripPort); + return new KerberosScheme(this.stripPort, this.useCanonicalHostname); } } diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java index b55500727..9c659c4fc 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java @@ -47,12 +47,19 @@ public class SPNegoScheme extends GGSSchemeBase { private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; + /** + * @since 4.4 + */ + public SPNegoScheme(final boolean stripPort, final boolean useCanonicalHostname) { + super(stripPort, useCanonicalHostname); + } + public SPNegoScheme(final boolean stripPort) { super(stripPort); } public SPNegoScheme() { - super(false); + super(); } @Override diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.java b/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.java index ef6dbcb7f..42e506dfd 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.java @@ -44,28 +44,43 @@ import org.apache.http.protocol.HttpContext; public class SPNegoSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider { private final boolean stripPort; + private final boolean useCanonicalHostname; + + /** + * @since 4.4 + */ + public SPNegoSchemeFactory(final boolean stripPort, final boolean useCanonicalHostname) { + super(); + this.stripPort = stripPort; + this.useCanonicalHostname = useCanonicalHostname; + } public SPNegoSchemeFactory(final boolean stripPort) { super(); this.stripPort = stripPort; + this.useCanonicalHostname = true; } public SPNegoSchemeFactory() { - this(false); + this(true, true); } public boolean isStripPort() { return stripPort; } + public boolean isUseCanonicalHostname() { + return useCanonicalHostname; + } + @Override public AuthScheme newInstance(final HttpParams params) { - return new SPNegoScheme(this.stripPort); + return new SPNegoScheme(this.stripPort, this.useCanonicalHostname); } @Override public AuthScheme create(final HttpContext context) { - return new SPNegoScheme(this.stripPort); + return new SPNegoScheme(this.stripPort, this.useCanonicalHostname); } }