java - Does JMeter fully support NTLM Authentication? -


i struggling make jmeter work ntlm authentication. @ beginning provided url , credential. when tested credential in firefox , in chrome received authentication popup , upon providing credential authenticated. had created test plan following configuration:

  • http authorization manager
  • http request default
  • http request

i didn't know requirement of domain ntlm authentication schema. jmeter failing authenticate , returning http 401 error.

then tried bad boy record test script. when had entered url in bad boy received windows authentication popup , given credential didn't work in bad boy.

so tried ie , received same windows authentication popup , credential didn't worked. asked domain , upon providing domain in ie domain\username successful authenticate user.

i tried same jmeter , have provided domain in http authorization manager. unfortunately didn't work in jmeter. following test plan. have replaced original url, domain , credential aliases.

<?xml version="1.0" encoding="utf-8"?> <jmetertestplan version="1.2" properties="2.8" jmeter="2.13 r1665067">   <hashtree>     <testplan guiclass="testplangui" testclass="testplan" testname="test plan" enabled="true">       <stringprop name="testplan.comments"></stringprop>       <boolprop name="testplan.functional_mode">false</boolprop>       <boolprop name="testplan.serialize_threadgroups">false</boolprop>       <elementprop name="testplan.user_defined_variables" elementtype="arguments" guiclass="argumentspanel" testclass="arguments" testname="user defined variables" enabled="true">         <collectionprop name="arguments.arguments"/>       </elementprop>       <stringprop name="testplan.user_define_classpath"></stringprop>     </testplan>     <hashtree>       <threadgroup guiclass="threadgroupgui" testclass="threadgroup" testname="thread group" enabled="true">         <stringprop name="threadgroup.on_sample_error">continue</stringprop>         <elementprop name="threadgroup.main_controller" elementtype="loopcontroller" guiclass="loopcontrolpanel" testclass="loopcontroller" testname="loop controller" enabled="true">           <boolprop name="loopcontroller.continue_forever">false</boolprop>           <stringprop name="loopcontroller.loops">1</stringprop>         </elementprop>         <stringprop name="threadgroup.num_threads">1</stringprop>         <stringprop name="threadgroup.ramp_time">1</stringprop>         <longprop name="threadgroup.start_time">1429694411000</longprop>         <longprop name="threadgroup.end_time">1429694411000</longprop>         <boolprop name="threadgroup.scheduler">false</boolprop>         <stringprop name="threadgroup.duration"></stringprop>         <stringprop name="threadgroup.delay"></stringprop>       </threadgroup>       <hashtree>         <authmanager guiclass="authpanel" testclass="authmanager" testname="http authorization manager" enabled="true">           <collectionprop name="authmanager.auth_list">             <elementprop name="" elementtype="authorization">               <stringprop name="authorization.url">https://my_domain</stringprop>               <stringprop name="authorization.username">username</stringprop>               <stringprop name="authorization.password">password</stringprop>               <stringprop name="authorization.domain">ntlm_domain</stringprop>               <stringprop name="authorization.realm"></stringprop>             </elementprop>           </collectionprop>         </authmanager>         <hashtree/>         <configtestelement guiclass="httpdefaultsgui" testclass="configtestelement" testname="http request defaults" enabled="true">           <elementprop name="httpsampler.arguments" elementtype="arguments" guiclass="httpargumentspanel" testclass="arguments" testname="user defined variables" enabled="true">             <collectionprop name="arguments.arguments"/>           </elementprop>           <stringprop name="httpsampler.domain">my_domain</stringprop>           <stringprop name="httpsampler.port"></stringprop>           <stringprop name="httpsampler.connect_timeout"></stringprop>           <stringprop name="httpsampler.response_timeout"></stringprop>           <stringprop name="httpsampler.protocol">https</stringprop>           <stringprop name="httpsampler.contentencoding"></stringprop>           <stringprop name="httpsampler.path"></stringprop>           <stringprop name="httpsampler.implementation">httpclient4</stringprop>           <stringprop name="httpsampler.concurrentpool">4</stringprop>         </configtestelement>         <hashtree/>         <httpsamplerproxy guiclass="httptestsamplegui" testclass="httpsamplerproxy" testname="http request" enabled="true">           <elementprop name="httpsampler.arguments" elementtype="arguments" guiclass="httpargumentspanel" testclass="arguments" testname="user defined variables" enabled="true">             <collectionprop name="arguments.arguments"/>           </elementprop>           <stringprop name="httpsampler.domain"></stringprop>           <stringprop name="httpsampler.port"></stringprop>           <stringprop name="httpsampler.connect_timeout"></stringprop>           <stringprop name="httpsampler.response_timeout"></stringprop>           <stringprop name="httpsampler.protocol">https</stringprop>           <stringprop name="httpsampler.contentencoding"></stringprop>           <stringprop name="httpsampler.path">/</stringprop>           <stringprop name="httpsampler.method">get</stringprop>           <boolprop name="httpsampler.follow_redirects">false</boolprop>           <boolprop name="httpsampler.auto_redirects">true</boolprop>           <boolprop name="httpsampler.use_keepalive">true</boolprop>           <boolprop name="httpsampler.do_multipart_post">false</boolprop>           <stringprop name="httpsampler.implementation">httpclient4</stringprop>           <boolprop name="httpsampler.monitor">false</boolprop>           <stringprop name="httpsampler.embedded_url_re"></stringprop>         </httpsamplerproxy>         <hashtree/>       </hashtree>     </hashtree>   </hashtree> </jmetertestplan> 

i getting frustrated make jmeter work. have tried both implementation of httpclient3.1 & 4; none of them have worked. have downloaded source code see if there can dig with.

these 2 classes deals http implementation of jmeter:

  • org.apache.jmeter.protocol.http.sampler.httphc4impl (for httpclient4)
  • org.apache.jmeter.protocol.http.sampler.httphc3impl (for httpclient3.1)

i didn't find wrong.

i tried authentication via java code. following implementation of authentication using common-httpclient-3.1:

import java.io.ioexception;  import org.apache.commons.httpclient.credentials; import org.apache.commons.httpclient.httpclient; import org.apache.commons.httpclient.httpexception; import org.apache.commons.httpclient.httpmethod; import org.apache.commons.httpclient.httpstate; import org.apache.commons.httpclient.ntcredentials; import org.apache.commons.httpclient.auth.authscope; import org.apache.commons.httpclient.methods.getmethod;  public class ntlmauthenticationhttpclient {      public static void main(string[] args) throws httpexception, ioexception {         httpclient client = new httpclient();         credentials credentials = new ntcredentials("username", "password", "", "ntlm_domain");         httpstate state = client.getstate();         state.setcredentials(authscope.any, credentials);          string domain = "my_domain";         string protocol = "https";          httpmethod method = new getmethod(protocol + "://" + domain);         method.setdoauthentication(true);         int status = client.executemethod(method);         system.out.println(status);     } } 

this piece of code once or twice had returned http 401 , of time got http 200.

following implementation using httpclient-4.4.1:

import java.io.ioexception;  import jcifs.ntlmssp.ntlmflags; import jcifs.ntlmssp.type1message; import jcifs.ntlmssp.type2message; import jcifs.ntlmssp.type3message; import jcifs.util.base64;  import org.apache.http.httphost; import org.apache.http.httpresponse; import org.apache.http.auth.authscheme; import org.apache.http.auth.authschemeprovider; import org.apache.http.auth.authscope; import org.apache.http.auth.ntcredentials; import org.apache.http.client.clientprotocolexception; import org.apache.http.client.credentialsprovider; import org.apache.http.client.config.authschemes; import org.apache.http.client.methods.httpget; import org.apache.http.config.registry; import org.apache.http.config.registrybuilder; import org.apache.http.impl.auth.basicschemefactory; import org.apache.http.impl.auth.digestschemefactory; import org.apache.http.impl.auth.kerberosschemefactory; import org.apache.http.impl.auth.ntlmengine; import org.apache.http.impl.auth.ntlmengineexception; import org.apache.http.impl.auth.ntlmscheme; import org.apache.http.impl.auth.spnegoschemefactory; import org.apache.http.impl.client.closeablehttpclient; import org.apache.http.impl.client.httpclients; import org.apache.http.impl.client.systemdefaultcredentialsprovider; import org.apache.http.protocol.httpcontext;  public class ntlmauthenticationhttpcomponent {      public static void main(string[] args) throws clientprotocolexception,             ioexception {         registry<authschemeprovider> authschemeregistry = registrybuilder                 .<authschemeprovider> create()                 .register(authschemes.ntlm, new authschemeprovider() {                      public authscheme create(httpcontext context) {                         return new ntlmscheme(new jcifsengine());                     }                 }).register(authschemes.basic, new basicschemefactory())                 .register(authschemes.digest, new digestschemefactory())                 .register(authschemes.spnego, new spnegoschemefactory())                 .register(authschemes.kerberos, new kerberosschemefactory())                 .build();          string domain = "my_domain";         string protocol = "https";          httphost targethost = new httphost(domain, 443, protocol);          credentialsprovider credentialsprovider = new systemdefaultcredentialsprovider();         credentialsprovider.setcredentials(                 new authscope(targethost.gethostname(), targethost.getport()),                 new ntcredentials("username", "password", null, "ntlm_domain"));          closeablehttpclient client = httpclients.custom()                 .setdefaultauthschemeregistry(authschemeregistry)                 .setdefaultcredentialsprovider(credentialsprovider).build();          httpget httpget = new httpget(protocol + "//" + domain);          httpresponse response = client.execute(httpget);         system.out.println(response.getstatusline().getstatuscode());     }      private static final class jcifsengine implements ntlmengine {          private static final int type_1_flags =                  ntlmflags.ntlmssp_negotiate_56 |                  ntlmflags.ntlmssp_negotiate_128 |                  ntlmflags.ntlmssp_negotiate_ntlm2 |                  ntlmflags.ntlmssp_negotiate_always_sign |                  ntlmflags.ntlmssp_request_target;          public string generatetype1msg(final string domain, final string workstation)                 throws ntlmengineexception {             final type1message type1message = new type1message(type_1_flags, domain, workstation);             return base64.encode(type1message.tobytearray());         }          public string generatetype3msg(final string username, final string password,                 final string domain, final string workstation, final string challenge)                 throws ntlmengineexception {             type2message type2message;             try {                 type2message = new type2message(base64.decode(challenge));             } catch (final ioexception exception) {                 throw new ntlmengineexception("invalid ntlm type 2 message", exception);             }             final int type2flags = type2message.getflags();             final int type3flags = type2flags                     & (0xffffffff ^ (ntlmflags.ntlmssp_target_type_domain | ntlmflags.ntlmssp_target_type_server));             final type3message type3message = new type3message(type2message, password, domain,                     username, workstation, type3flags);             return base64.encode(type3message.tobytearray());         }     } } 

this returning http 401 unauthorized error. code taked http components site, using jcifs.

i unable find cause unauthorization. jmeter or httpclient supports ntlm authentication fully? having doubt after reading note above site:

ntlm proprietary authentication scheme developed microsoft , optimized windows operating system.

until year 2008 there no official, publicly available, complete documentation of protocol. unofficial 3rd party protocol descriptions existed result of reverse-engineering efforts. not known whether protocol based on reverse-engineering complete or correct.

microsoft published ms-nlmp , ms-ntht specifications in february 2008 part of interoperability principles initiative.

httpclient of version 4.1 supported ntlmv1, ntlmv2, , ntlm2sessionresponse authentication protocols, based on reverse engineering approach. of version 4.2.3, httpclient supports more correct implementation, based in large part on microsoft's own specifications. expected correct number of problems, since microsoft (as of windows server 2008 r2) began using new implementation of protocols. new microsoft implementation has led authentication failures in cases of older reverse-engineered client implementations of ntlm.

the new httpclient ntlm implementation known have been tried against @ least following systems:

  • windows server 2000 , server 2003 systems, configured use lm , ntlmv1 authentication
  • windows server 2003 systems, configured use ntlmv2 authentication
  • windows server 2008 r2 systems, configured use ntlm2sessionresponse authentication

if current httpclient ntlm implementation should prove problematic in environment, we'd hear it.

in browser when browing url have used authentication asking credential navigating home page. there intermediate page returns http 302 redirection.

any suggestion big me.

update:

in jmeter following result getting response header:

thread name: thread group 1-1 sample start: 2015-04-26 14:26:39 ist load time: 3837 connect time: 2716 latency: 3837 size in bytes: 940 headers size in bytes: 940 body size in bytes: 0 sample count: 1 error count: 1 response code: 401 response message: unauthorized  response headers: http/1.1 401 unauthorized cache-control: max-age=0 content-type: text/plain date: sun, 26 apr 2015 08:56:42 gmt expires: sun, 26 apr 2015 08:56:43 gmt server: apache-coyote/1.1 set-cookie: jsessionid=0d39812daecaed077e7a9001864874a9.schbapxu1044_sep; expires=sun, 26-apr-2015 16:56:42 gmt; path=/; secure; httponly set-cookie: dtcookie=2929007d72e613d13bf40f8241ec4b9f|x2rlzmf1bhr8mq; path=/; domain=.my_domain_part2 set-cookie: awselb=c5c5577906943f772312365ac913fbe510ffa9a080fc6fd7778cb3f66b01593d16e110291976d6d7d50fbfb1db51745a84041319d726b0f898fae4520dc36e25bb9ae95fbcb14d902fbc9b5903e8bcb6e32414584f;path=/;expires=sun, 26-apr-2015 16:56:42 gmt;secure;httponly vary: accept-encoding via: 1.1 my_domain_part1.my_domain_part2 www-authenticate: ntlm x-content-type-options: nosniff x-dynatrace-js-agent: true x-frame-options: sameorigin x-xss-protection: 1 content-length: 0 connection: keep-alive   httpsampleresult fields: contenttype: text/plain dataencoding: null 

it given provide username, password and domain in http authorization manager

see windows authentication apache jmeter guide detailed explanation , configuration details.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -