You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by fs...@apache.org on 2018/06/16 13:37:58 UTC

svn commit: r1833637 - in /jmeter/trunk: bin/ src/protocol/http/org/apache/jmeter/protocol/http/control/ src/protocol/http/org/apache/jmeter/protocol/http/sampler/ xdocs/ xdocs/usermanual/

Author: fschumacher
Date: Sat Jun 16 13:37:58 2018
New Revision: 1833637

URL: http://svn.apache.org/viewvc?rev=1833637&view=rev
Log:
Make delegation of credentials in SPNEGO possible again.

Newer versions of httpcomponents-client (at least in the 4.x branch) removed the ability to delegate
kerberos credentials via SPNEGO. This will make it possible to re-enable delegation by specifying
a system property.

Bugzilla Id: 62462
Closes #387 on github

Added:
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java   (with props)
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java   (with props)
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java   (with props)
Modified:
    jmeter/trunk/bin/jmeter.properties
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicKerberosSchemeFactory.java
    jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
    jmeter/trunk/xdocs/changes.xml
    jmeter/trunk/xdocs/usermanual/component_reference.xml
    jmeter/trunk/xdocs/usermanual/properties_reference.xml

Modified: jmeter/trunk/bin/jmeter.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/bin/jmeter.properties (original)
+++ jmeter/trunk/bin/jmeter.properties Sat Jun 16 13:37:58 2018
@@ -392,6 +392,10 @@ remote_hosts=127.0.0.1
 # for SPNEGO authentication
 #kerberos.spnego.strip_port=true
 
+# Should credentials be delegated to webservers when using
+# SPNEGO authentication
+#kerberos.spnego.delegate_cred=false
+
 #---------------------------------------------------------------------------
 # Apache HttpComponents HTTPClient configuration (HTTPClient4)
 #---------------------------------------------------------------------------
@@ -1294,4 +1298,4 @@ jmeter.reportgenerator.apdex_tolerated_t
 
 # Switch that allows using Local documentation opened in JMeter GUI
 # By default we use Online documentation opened in Browser
-#help.local=false
\ No newline at end of file
+#help.local=false

Added: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java?rev=1833637&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java (added)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java Sat Jun 16 13:37:58 2018
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.jmeter.protocol.http.control;
+
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.KerberosCredentials;
+import org.apache.http.impl.auth.KerberosScheme;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+public class DelegatingKerberosScheme extends KerberosScheme {
+    public DelegatingKerberosScheme(final boolean stripPort, final boolean useCanonicalHostName) {
+        super(stripPort, useCanonicalHostName);
+    }
+
+    @Override
+    protected byte[] generateGSSToken(
+            final byte[] input, final Oid oid, final String authServer,
+            final Credentials credentials) throws GSSException {
+        final GSSManager manager = getManager();
+        final GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
+
+        final GSSCredential gssCredential;
+        if (credentials instanceof KerberosCredentials) {
+            gssCredential = ((KerberosCredentials) credentials).getGSSCredential();
+        } else {
+            gssCredential = null;
+        }
+
+        final GSSContext gssContext = createDelegatingGSSContext(manager, oid, serverName, gssCredential);
+        try {
+            if (input != null) {
+                return gssContext.initSecContext(input, 0, input.length);
+            } else {
+                return gssContext.initSecContext(new byte[] {}, 0, 0);
+            }
+        } finally {
+            gssContext.dispose();
+        }
+    }
+
+    GSSContext createDelegatingGSSContext(final GSSManager manager, final Oid oid, final GSSName serverName,
+            final GSSCredential gssCredential) throws GSSException {
+        final GSSContext gssContext = manager.createContext(serverName.canonicalize(oid), oid, gssCredential,
+                GSSContext.DEFAULT_LIFETIME);
+        gssContext.requestMutualAuth(true);
+        gssContext.requestCredDeleg(true);
+        return gssContext;
+    }
+}

Propchange: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingKerberosScheme.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java?rev=1833637&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java (added)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java Sat Jun 16 13:37:58 2018
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.jmeter.protocol.http.control;
+
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.KerberosCredentials;
+import org.apache.http.impl.auth.SPNegoScheme;
+import org.ietf.jgss.GSSContext;
+import org.ietf.jgss.GSSCredential;
+import org.ietf.jgss.GSSException;
+import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
+import org.ietf.jgss.Oid;
+
+public class DelegatingSPNegoScheme extends SPNegoScheme {
+    public DelegatingSPNegoScheme(final boolean stripPort, final boolean useCanonicalHostName) {
+        super(stripPort, useCanonicalHostName);
+    }
+
+    @Override
+    protected byte[] generateGSSToken(
+            final byte[] input, final Oid oid, final String authServer,
+            final Credentials credentials) throws GSSException {
+        final GSSManager manager = getManager();
+        final GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE);
+
+        final GSSCredential gssCredential;
+        if (credentials instanceof KerberosCredentials) {
+            gssCredential = ((KerberosCredentials) credentials).getGSSCredential();
+        } else {
+            gssCredential = null;
+        }
+
+        final GSSContext gssContext = createDelegatingGSSContext(manager, oid, serverName, gssCredential);
+        try {
+            if (input != null) {
+                return gssContext.initSecContext(input, 0, input.length);
+            } else {
+                return gssContext.initSecContext(new byte[] {}, 0, 0);
+            }
+        } finally {
+            gssContext.dispose();
+        }
+    }
+
+    GSSContext createDelegatingGSSContext(final GSSManager manager, final Oid oid, final GSSName serverName,
+            final GSSCredential gssCredential) throws GSSException {
+        final GSSContext gssContext = manager.createContext(serverName.canonicalize(oid), oid, gssCredential,
+                GSSContext.DEFAULT_LIFETIME);
+        gssContext.requestMutualAuth(true);
+        gssContext.requestCredDeleg(true);
+        return gssContext;
+    }
+}

Propchange: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DelegatingSPNegoScheme.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicKerberosSchemeFactory.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicKerberosSchemeFactory.java?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicKerberosSchemeFactory.java (original)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicKerberosSchemeFactory.java Sat Jun 16 13:37:58 2018
@@ -22,6 +22,10 @@ import org.apache.http.auth.AuthScheme;
 import org.apache.http.impl.auth.KerberosScheme;
 import org.apache.http.impl.auth.KerberosSchemeFactory;
 import org.apache.http.protocol.HttpContext;
+import org.apache.jmeter.util.JMeterUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Extends {@link KerberosSchemeFactory} to provide ability to customize stripPort
@@ -30,6 +34,9 @@ import org.apache.http.protocol.HttpCont
  */
 public class DynamicKerberosSchemeFactory extends KerberosSchemeFactory {
     static final String CONTEXT_ATTRIBUTE_STRIP_PORT = "__jmeter.K_SP__";
+    static final String CONTEXT_ATTRIBUTE_DELEGATE_CRED = "__jmeter.K_DT__";
+    static final boolean DELEGATE_CRED = JMeterUtils.getPropDefault("kerberos.spnego.delegate_cred", false);
+    private static final Logger log = LoggerFactory.getLogger(DynamicKerberosSchemeFactory.class);
 
     /**
      * Constructor for DynamicKerberosSchemeFactory
@@ -43,8 +50,19 @@ public class DynamicKerberosSchemeFactor
 
     @Override
     public AuthScheme create(final HttpContext context) {
-        Boolean localStripPort = (Boolean) context.getAttribute(CONTEXT_ATTRIBUTE_STRIP_PORT);
-        Boolean stripPort = localStripPort != null ? localStripPort : isStripPort();
+        boolean stripPort = isEnabled(context.getAttribute(CONTEXT_ATTRIBUTE_STRIP_PORT), isStripPort());
+        if (isEnabled(context.getAttribute(CONTEXT_ATTRIBUTE_DELEGATE_CRED), DELEGATE_CRED)) {
+            log.debug("Use DelegatingKerberosScheme");
+            return new DelegatingKerberosScheme(stripPort, isStripPort());
+        }
+        log.debug("Use KerberosScheme");
         return new KerberosScheme(stripPort, isUseCanonicalHostname());
     }
+
+    private boolean isEnabled(Object contextAttribute, boolean defaultValue) {
+        if (contextAttribute instanceof Boolean) {
+            return ((Boolean) contextAttribute).booleanValue();
+        }
+        return defaultValue;
+    }
 }

Added: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java?rev=1833637&view=auto
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java (added)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java Sat Jun 16 13:37:58 2018
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+
+package org.apache.jmeter.protocol.http.control;
+
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.impl.auth.SPNegoScheme;
+import org.apache.http.impl.auth.SPNegoSchemeFactory;
+import org.apache.http.protocol.HttpContext;
+import org.apache.jmeter.util.JMeterUtils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extends {@link SPNegoSchemeFactory} to provide ability to customize stripPort
+ * setting in {@link SPNegoScheme} based on {@link HttpContext}
+ * @since 4.1
+ */
+public class DynamicSPNegoSchemeFactory extends SPNegoSchemeFactory {
+    static final String CONTEXT_ATTRIBUTE_STRIP_PORT = "__jmeter.K_SP__";
+    static final String CONTEXT_ATTRIBUTE_DELEGATE_CRED = "__jmeter.K_DT__";
+    static final boolean DELEGATE_CRED = JMeterUtils.getPropDefault("kerberos.spnego.delegate_cred", false);
+    private static final Logger log = LoggerFactory.getLogger(DynamicSPNegoSchemeFactory.class);
+
+    /**
+     * Constructor for DynamicSPNegoSchemeFactory
+     * @param stripPort flag, whether port should be stripped from SPN
+     * @param useCanonicalHostname flag, whether SPN should use the canonical hostname
+     * @since 4.0
+     */
+    public DynamicSPNegoSchemeFactory(final boolean stripPort, final boolean useCanonicalHostname) {
+        super(stripPort, useCanonicalHostname);
+    }
+
+    @Override
+    public AuthScheme create(final HttpContext context) {
+        boolean stripPort = isEnabled(context.getAttribute(CONTEXT_ATTRIBUTE_STRIP_PORT), isStripPort());
+        if (isEnabled(context.getAttribute(CONTEXT_ATTRIBUTE_DELEGATE_CRED), DELEGATE_CRED)) {
+            log.debug("Use DelegatingSPNegoScheme");
+            return new DelegatingSPNegoScheme(stripPort, isStripPort());
+        }
+        log.debug("Use SPNegoScheme");
+        return new SPNegoScheme(stripPort, isUseCanonicalHostname());
+    }
+
+    private boolean isEnabled(Object contextAttribute, boolean defaultValue) {
+        if (contextAttribute instanceof Boolean) {
+            return ((Boolean) contextAttribute).booleanValue();
+        }
+        return defaultValue;
+    }
+}

Propchange: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/control/DynamicSPNegoSchemeFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java (original)
+++ jmeter/trunk/src/protocol/http/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java Sat Jun 16 13:37:58 2018
@@ -110,7 +110,6 @@ import org.apache.http.impl.auth.DigestS
 import org.apache.http.impl.auth.DigestSchemeFactory;
 import org.apache.http.impl.auth.KerberosScheme;
 import org.apache.http.impl.auth.NTLMSchemeFactory;
-import org.apache.http.impl.auth.SPNegoSchemeFactory;
 import org.apache.http.impl.client.BasicAuthCache;
 import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -142,6 +141,7 @@ import org.apache.jmeter.protocol.http.c
 import org.apache.jmeter.protocol.http.control.CacheManager;
 import org.apache.jmeter.protocol.http.control.CookieManager;
 import org.apache.jmeter.protocol.http.control.DynamicKerberosSchemeFactory;
+import org.apache.jmeter.protocol.http.control.DynamicSPNegoSchemeFactory;
 import org.apache.jmeter.protocol.http.control.HeaderManager;
 import org.apache.jmeter.protocol.http.sampler.hc.LaxDeflateInputStream;
 import org.apache.jmeter.protocol.http.sampler.hc.LazyLayeredConnectionSocketFactory;
@@ -1030,7 +1030,8 @@ public class HTTPHC4Impl extends HTTPHCA
                         .register(AuthSchemes.BASIC, new BasicSchemeFactory())
                         .register(AuthSchemes.DIGEST, new DigestSchemeFactory())
                         .register(AuthSchemes.NTLM, new NTLMSchemeFactory())
-                        .register(AuthSchemes.SPNEGO, new SPNegoSchemeFactory())
+                        .register(AuthSchemes.SPNEGO, new DynamicSPNegoSchemeFactory(
+                                AuthManager.STRIP_PORT, AuthManager.USE_CANONICAL_HOST_NAME))
                         .register(AuthSchemes.KERBEROS, new DynamicKerberosSchemeFactory(
                                 AuthManager.STRIP_PORT, AuthManager.USE_CANONICAL_HOST_NAME))
                         .build();

Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sat Jun 16 13:37:58 2018
@@ -173,6 +173,7 @@ this behaviour, set <code>httpclient.res
     <li><bug>61058</bug>HTTP Request : Add option <code>httpclient4.deflate_relax_mode</code> to avoid "Unexpected end of ZLIB input stream" when deflating what seems to be invalid streams. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
     <li><bug>43612</bug>HTTP PUT does not honor request parameters. Implemented by Artem Fedorov (artem.fedorov at blazemeter.com) and contributed by BlazeMeter Ltd.</li>
     <li><bug>60190</bug>Content-Type is added for POST unconditionally. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
+    <li><bug>62462</bug><pr>387</pr>Make delegation of credentials in SPNEGO possible again.</li>
 </ul>
 
 <h3>Other Samplers</h3>

Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/component_reference.xml Sat Jun 16 13:37:58 2018
@@ -3644,6 +3644,9 @@ Look at the two sample configuration fil
 for references to more documentation, and tweak them to match your Kerberos configuration.
 </p>
 <p>
+Delegation of credentials is disabled by default for SPNEGO. If you want to enable it, you can do so by setting the property <code>kerberos.spnego.delegate_cred</code> to <code>true</code>.
+</p>
+<p>
 When generating a SPN for Kerberos SPNEGO authentication IE and Firefox will omit the port number
 from the URL. Chrome has an option (<code>--enable-auth-negotiate-port</code>) to include the port
 number if it differs from the standard ones (<code>80</code> and <code>443</code>). That behavior

Modified: jmeter/trunk/xdocs/usermanual/properties_reference.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/properties_reference.xml?rev=1833637&r1=1833636&r2=1833637&view=diff
==============================================================================
--- jmeter/trunk/xdocs/usermanual/properties_reference.xml (original)
+++ jmeter/trunk/xdocs/usermanual/properties_reference.xml Sat Jun 16 13:37:58 2018
@@ -463,6 +463,10 @@ JMETER-SERVER</source>
     Should port be stripped from urls before constructing SPNs for SPNEGO authentication.
     Defaults to: <code>true</code>
 </property>
+<property name="kerberos.spnego.delegate_cred">
+    Should SPNEGO authentication should use delegation of credentials.
+    Defaults to: <code>false</code>
+</property>
 </properties>
 </section>
 <section name="&sect-num;.12 Apache HttpClient logging examples" anchor="httpclient_logging_examples">