You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2017/10/23 09:17:27 UTC

httpcomponents-client git commit: HTTPCLIENT-1873: Config option for Kerberos delegation

Repository: httpcomponents-client
Updated Branches:
  refs/heads/4.6.x ba47719c3 -> cc58de13c


HTTPCLIENT-1873: Config option for Kerberos delegation


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/cc58de13
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/cc58de13
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/cc58de13

Branch: refs/heads/4.6.x
Commit: cc58de13c5361d5ff98a839adc7b46eceb2f2bef
Parents: ba47719
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Mon Oct 23 11:16:16 2017 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Mon Oct 23 11:16:16 2017 +0200

----------------------------------------------------------------------
 .../org/apache/http/auth/KerberosConfig.java    | 158 +++++++++++++++++++
 .../apache/http/impl/auth/GGSSchemeBase.java    |  28 ++--
 .../apache/http/impl/auth/KerberosScheme.java   |   8 +
 .../http/impl/auth/KerberosSchemeFactory.java   |  32 ++--
 .../org/apache/http/impl/auth/SPNegoScheme.java |   8 +
 .../http/impl/auth/SPNegoSchemeFactory.java     |  32 ++--
 6 files changed, 237 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/auth/KerberosConfig.java
----------------------------------------------------------------------
diff --git a/httpclient/src/main/java/org/apache/http/auth/KerberosConfig.java b/httpclient/src/main/java/org/apache/http/auth/KerberosConfig.java
new file mode 100644
index 0000000..a04ff2d
--- /dev/null
+++ b/httpclient/src/main/java/org/apache/http/auth/KerberosConfig.java
@@ -0,0 +1,158 @@
+/*
+ * ====================================================================
+ * 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.http.auth;
+
+import org.apache.http.annotation.Contract;
+import org.apache.http.annotation.ThreadingBehavior;
+
+/**
+ *  Immutable class encapsulating Kerberos configuration options.
+ *
+ *  @since 4.6
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public class KerberosConfig implements Cloneable {
+
+    public enum Option {
+
+        DEFAULT,
+        ENABLE,
+        DISABLE
+
+    }
+
+    public static final KerberosConfig DEFAULT = new Builder().build();
+
+    private final Option stripPort;
+    private final Option useCanonicalHostname;
+    private final Option requestDelegCreds;
+
+    /**
+     * Intended for CDI compatibility
+    */
+    protected KerberosConfig() {
+        this(Option.DEFAULT, Option.DEFAULT, Option.DEFAULT);
+    }
+
+    KerberosConfig(
+            final Option stripPort,
+            final Option useCanonicalHostname,
+            final Option requestDelegCreds) {
+        super();
+        this.stripPort = stripPort;
+        this.useCanonicalHostname = useCanonicalHostname;
+        this.requestDelegCreds = requestDelegCreds;
+    }
+
+    public Option getStripPort() {
+        return stripPort;
+    }
+
+    public Option getUseCanonicalHostname() {
+        return useCanonicalHostname;
+    }
+
+    public Option getRequestDelegCreds() {
+        return requestDelegCreds;
+    }
+
+    @Override
+    protected KerberosConfig clone() throws CloneNotSupportedException {
+        return (KerberosConfig) super.clone();
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("[");
+        builder.append("stripPort=").append(stripPort);
+        builder.append(", useCanonicalHostname=").append(useCanonicalHostname);
+        builder.append(", requestDelegCreds=").append(requestDelegCreds);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static KerberosConfig.Builder custom() {
+        return new Builder();
+    }
+
+    public static KerberosConfig.Builder copy(final KerberosConfig config) {
+        return new Builder()
+                .setStripPort(config.getStripPort())
+                .setUseCanonicalHostname(config.getUseCanonicalHostname())
+                .setRequestDelegCreds(config.getRequestDelegCreds());
+    }
+
+    public static class Builder {
+
+        private Option stripPort;
+        private Option useCanonicalHostname;
+        private Option requestDelegCreds;
+
+        Builder() {
+            super();
+            this.stripPort = Option.DEFAULT;
+            this.useCanonicalHostname = Option.DEFAULT;
+            this.requestDelegCreds = Option.DEFAULT;
+        }
+
+        public Builder setStripPort(final Option stripPort) {
+            this.stripPort = stripPort;
+            return this;
+        }
+
+        public Builder setStripPort(final boolean stripPort) {
+            this.stripPort = stripPort ? Option.ENABLE : Option.DISABLE;
+            return this;
+        }
+
+        public Builder setUseCanonicalHostname(final Option useCanonicalHostname) {
+            this.useCanonicalHostname = useCanonicalHostname;
+            return this;
+        }
+
+        public Builder setUseCanonicalHostname(final boolean useCanonicalHostname) {
+            this.useCanonicalHostname = useCanonicalHostname ? Option.ENABLE : Option.DISABLE;
+            return this;
+        }
+
+        public Builder setRequestDelegCreds(final Option requestDelegCreds) {
+            this.requestDelegCreds = requestDelegCreds;
+            return this;
+        }
+
+        public KerberosConfig build() {
+            return new KerberosConfig(
+                    stripPort,
+                    useCanonicalHostname,
+                    requestDelegCreds);
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java
----------------------------------------------------------------------
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 1fbc86a..706cdd5 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
@@ -39,6 +39,7 @@ import org.apache.http.auth.AUTH;
 import org.apache.http.auth.AuthenticationException;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.InvalidCredentialsException;
+import org.apache.http.auth.KerberosConfig;
 import org.apache.http.auth.KerberosCredentials;
 import org.apache.http.auth.MalformedChallengeException;
 import org.apache.http.client.protocol.HttpClientContext;
@@ -69,8 +70,7 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
     private final Log log = LogFactory.getLog(getClass());
 
     private final Base64 base64codec;
-    private final boolean stripPort;
-    private final boolean useCanonicalHostname;
+    private final KerberosConfig config;
 
     /** Authentication process state */
     private State state;
@@ -78,20 +78,27 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
     /** base64 decoded challenge **/
     private byte[] token;
 
-    GGSSchemeBase(final boolean stripPort, final boolean useCanonicalHostname) {
+    GGSSchemeBase(final KerberosConfig config) {
         super();
         this.base64codec = new Base64(0);
-        this.stripPort = stripPort;
-        this.useCanonicalHostname = useCanonicalHostname;
+        this.config = config != null ? config : KerberosConfig.DEFAULT;
         this.state = State.UNINITIATED;
     }
 
+    GGSSchemeBase(final boolean stripPort, final boolean useCanonicalHostname) {
+        this(KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(useCanonicalHostname).build());
+    }
+
     GGSSchemeBase(final boolean stripPort) {
-        this(stripPort, true);
+        this(KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(true).build());
     }
 
     GGSSchemeBase() {
-        this(true,true);
+        this(KerberosConfig.DEFAULT);
     }
 
     protected GSSManager getManager() {
@@ -135,6 +142,9 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
         final GSSContext gssContext = manager.createContext(serverName.canonicalize(oid), oid, gssCredential,
                 GSSContext.DEFAULT_LIFETIME);
         gssContext.requestMutualAuth(true);
+        if (config.getRequestDelegCreds() != KerberosConfig.Option.DEFAULT) {
+            gssContext.requestCredDeleg(config.getRequestDelegCreds() == KerberosConfig.Option.ENABLE);
+        }
         return gssContext;
     }
     /**
@@ -201,7 +211,7 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
                 final String authServer;
                 String hostname = host.getHostName();
 
-                if (this.useCanonicalHostname){
+                if (config.getUseCanonicalHostname() != KerberosConfig.Option.DISABLE){
                     try {
                          //TODO: uncomment this statement and delete the resolveCanonicalHostname,
                          //TODO: as soon canonical hostname resolving is implemented in the SystemDefaultDnsResolver
@@ -211,7 +221,7 @@ public abstract class GGSSchemeBase extends AuthSchemeBase {
                     } catch (final UnknownHostException ignore){
                     }
                 }
-                if (this.stripPort) { // || host.getPort()==80 || host.getPort()==443) {
+                if (config.getStripPort() != KerberosConfig.Option.DISABLE) { // || host.getPort()==80 || host.getPort()==443) {
                     authServer = hostname;
                 } else {
                     authServer = hostname + ":" + host.getPort();

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java
----------------------------------------------------------------------
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 6cbb05b..7925f0d 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
@@ -30,6 +30,7 @@ import org.apache.http.Header;
 import org.apache.http.HttpRequest;
 import org.apache.http.auth.AuthenticationException;
 import org.apache.http.auth.Credentials;
+import org.apache.http.auth.KerberosConfig;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.Args;
 import org.ietf.jgss.GSSException;
@@ -45,6 +46,13 @@ public class KerberosScheme extends GGSSchemeBase {
     private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
 
     /**
+     * @since 4.6
+     */
+    public KerberosScheme(final KerberosConfig config) {
+        super(config);
+    }
+
+    /**
      * @since 4.4
      */
     public KerberosScheme(final boolean stripPort, final boolean useCanonicalHostname) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/impl/auth/KerberosSchemeFactory.java
----------------------------------------------------------------------
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 7096e69..5bc24b3 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
@@ -31,6 +31,7 @@ import org.apache.http.annotation.ThreadingBehavior;
 import org.apache.http.auth.AuthScheme;
 import org.apache.http.auth.AuthSchemeFactory;
 import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.KerberosConfig;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 
@@ -44,22 +45,33 @@ import org.apache.http.protocol.HttpContext;
 @SuppressWarnings("deprecation")
 public class KerberosSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider {
 
-    private final boolean stripPort;
-    private final boolean useCanonicalHostname;
+    private final KerberosConfig config;
+
+    /**
+     * @since 4.6
+     */
+    public KerberosSchemeFactory(final KerberosConfig config) {
+        super();
+        this.config = config != null ? config : KerberosConfig.DEFAULT;
+    }
 
     /**
      * @since 4.4
      */
     public KerberosSchemeFactory(final boolean stripPort, final boolean useCanonicalHostname) {
         super();
-        this.stripPort = stripPort;
-        this.useCanonicalHostname = useCanonicalHostname;
+        this.config = KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(useCanonicalHostname)
+                .build();
     }
 
     public KerberosSchemeFactory(final boolean stripPort) {
         super();
-        this.stripPort = stripPort;
-        this.useCanonicalHostname = true;
+        this.config = KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(true)
+                .build();
     }
 
     public KerberosSchemeFactory() {
@@ -67,21 +79,21 @@ public class KerberosSchemeFactory implements AuthSchemeFactory, AuthSchemeProvi
     }
 
     public boolean isStripPort() {
-        return stripPort;
+        return config.getStripPort() != KerberosConfig.Option.DISABLE;
     }
 
     public boolean isUseCanonicalHostname() {
-        return useCanonicalHostname;
+        return config.getUseCanonicalHostname() != KerberosConfig.Option.DISABLE;
     }
 
     @Override
     public AuthScheme newInstance(final HttpParams params) {
-        return new KerberosScheme(this.stripPort, this.useCanonicalHostname);
+        return new KerberosScheme(config);
     }
 
     @Override
     public AuthScheme create(final HttpContext context) {
-        return new KerberosScheme(this.stripPort, this.useCanonicalHostname);
+        return new KerberosScheme(config);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java
----------------------------------------------------------------------
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 46ebeb8..b03a49c 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
@@ -30,6 +30,7 @@ import org.apache.http.Header;
 import org.apache.http.HttpRequest;
 import org.apache.http.auth.AuthenticationException;
 import org.apache.http.auth.Credentials;
+import org.apache.http.auth.KerberosConfig;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.Args;
 import org.ietf.jgss.GSSException;
@@ -46,6 +47,13 @@ public class SPNegoScheme extends GGSSchemeBase {
     private static final String SPNEGO_OID = "1.3.6.1.5.5.2";
 
     /**
+     * @since 4.6
+     */
+    public SPNegoScheme(final KerberosConfig config) {
+        super(config);
+    }
+
+    /**
      * @since 4.4
      */
     public SPNegoScheme(final boolean stripPort, final boolean useCanonicalHostname) {

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/cc58de13/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoSchemeFactory.java
----------------------------------------------------------------------
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 fa09a2b..822a951 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
@@ -31,6 +31,7 @@ import org.apache.http.annotation.ThreadingBehavior;
 import org.apache.http.auth.AuthScheme;
 import org.apache.http.auth.AuthSchemeFactory;
 import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.auth.KerberosConfig;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
 
@@ -44,22 +45,33 @@ import org.apache.http.protocol.HttpContext;
 @SuppressWarnings("deprecation")
 public class SPNegoSchemeFactory implements AuthSchemeFactory, AuthSchemeProvider {
 
-    private final boolean stripPort;
-    private final boolean useCanonicalHostname;
+    private final KerberosConfig config;
+
+    /**
+     * @since 4.6
+     */
+    public SPNegoSchemeFactory(final KerberosConfig config) {
+        super();
+        this.config = config != null ? config : KerberosConfig.DEFAULT;
+    }
 
     /**
      * @since 4.4
      */
     public SPNegoSchemeFactory(final boolean stripPort, final boolean useCanonicalHostname) {
         super();
-        this.stripPort = stripPort;
-        this.useCanonicalHostname = useCanonicalHostname;
+        this.config = KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(useCanonicalHostname)
+                .build();
     }
 
     public SPNegoSchemeFactory(final boolean stripPort) {
         super();
-        this.stripPort = stripPort;
-        this.useCanonicalHostname = true;
+        this.config = KerberosConfig.custom()
+                .setStripPort(stripPort)
+                .setUseCanonicalHostname(true)
+                .build();
     }
 
     public SPNegoSchemeFactory() {
@@ -67,21 +79,21 @@ public class SPNegoSchemeFactory implements AuthSchemeFactory, AuthSchemeProvide
     }
 
     public boolean isStripPort() {
-        return stripPort;
+        return config.getStripPort() != KerberosConfig.Option.DISABLE;
     }
 
     public boolean isUseCanonicalHostname() {
-        return useCanonicalHostname;
+        return config.getUseCanonicalHostname() != KerberosConfig.Option.DISABLE;
     }
 
     @Override
     public AuthScheme newInstance(final HttpParams params) {
-        return new SPNegoScheme(this.stripPort, this.useCanonicalHostname);
+        return new KerberosScheme(config);
     }
 
     @Override
     public AuthScheme create(final HttpContext context) {
-        return new SPNegoScheme(this.stripPort, this.useCanonicalHostname);
+        return new KerberosScheme(config);
     }
 
 }