Kerberos authentication

2,316 views
Skip to first unread message

Maxime

unread,
Jun 16, 2017, 6:28:21 AM6/16/17
to Gatling User Group
Hello,

I'm trying to simulate a kerberos authentification.

The server return a normal 401 with the "WWW-Authenticate: Negotiate" header.

During the generation of the kerberos token, I get the following exception:
org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)

Here is my scenario
package packagename.iam


import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.http.util.HttpHelper
import org.asynchttpclient.Realm.AuthScheme


class
SSO
extends Simulation {


 
System.setProperty("java.security.krb5.conf","/etc/krb5.conf");
// System.setProperty("java.security.krb5.realm","ADNAME.AD.domain.com")
// System.setProperty("java.security.krb5.kdc","domain.com");


 val httpProtocol
= http
 
.baseURL("https://integration.domain.com")
 
.inferHtmlResources()
 
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
 
.acceptEncodingHeader("gzip, deflate")
 
.acceptLanguageHeader("en-US,en;q=0.5")
 
.userAgentHeader("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0")
 
.extraInfoExtractor(extraInfo => List(extraInfo.response.body.string))
 
.authRealm(HttpHelper.buildRealm("userid", "passwd", AuthScheme.KERBEROS, false, None, None))
   
.disableWarmUp


 val headers_0
= Map("Upgrade-Insecure-Requests" -> "1")


 val scn
= scenario("SSO")
 
.exec(http("request_0")
   
.get("/iam/accueil/")
   
.headers(headers_0))


 setUp
(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}



I try to understand what is wrong by analysing the SpnegoEngine.generateToken method. It looks like something is missing, so I check the cached ticket with klist:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: userid@ADNAME.AD.domain.com


Valid starting       Expires              Service principal
16/06/2017 11:02:59  16/06/2017 21:02:59  krbtgt/ADNAME.AD.domain.com@ADNAME.AD.domain.com
 renew
until 17/06/2017 11:02:55
16/06/2017 11:03:04  16/06/2017 21:02:59  HTTP/integration.domain.com@
 renew
until 17/06/2017 11:02:55
16/06/2017 11:03:04  16/06/2017 21:02:59  HTTP/integration.domain.com@ADNAME.AD.domain.com
 renew
until 17/06/2017 11:02:55



I run the scenario with the debug logs activate.
12:09:44.467 [INFO ] a.e.s.Slf4jLogger - Slf4jLogger started
packagename
.iam.SSO is the only simulation, executing it.
Select simulation id (default is 'sso'). Accepted characters are a-z, A-Z, 0-9, - and _


Select run description (optional)


12:09:47.770 [INFO ] i.g.c.s.w.ConsoleDataWriter - Initializing
12:09:47.770 [INFO ] i.g.c.s.w.LogFileDataWriter - Initializing
12:09:47.773 [INFO ] i.g.c.s.w.ConsoleDataWriter - Initialized
12:09:47.782 [INFO ] i.g.c.s.w.LogFileDataWriter - Initialized
12:09:47.800 [DEBUG] i.n.c.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 16
12:09:47.809 [DEBUG] i.n.u.i.PlatformDependent - -Dio.netty.noUnsafe: false
12:09:47.810 [DEBUG] i.n.u.i.PlatformDependent0 - java.nio.Buffer.address: available
12:09:47.811 [DEBUG] i.n.u.i.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
12:09:47.811 [DEBUG] i.n.u.i.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
12:09:47.811 [DEBUG] i.n.u.i.PlatformDependent0 - direct buffer constructor: available
12:09:47.812 [DEBUG] i.n.u.i.PlatformDependent0 - java.nio.Bits.unaligned: available, true
12:09:47.812 [DEBUG] i.n.u.i.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
12:09:47.812 [DEBUG] i.n.u.i.Cleaner0 - java.nio.ByteBuffer.cleaner(): available
12:09:47.813 [DEBUG] i.n.u.i.PlatformDependent - Java version: 8
12:09:47.813 [DEBUG] i.n.u.i.PlatformDependent - sun.misc.Unsafe: available
12:09:47.813 [DEBUG] i.n.u.i.PlatformDependent - -Dio.netty.noJavassist: false
12:09:47.862 [DEBUG] i.n.u.i.PlatformDependent - Javassist: available
12:09:47.862 [DEBUG] i.n.u.i.PlatformDependent - -Dio.netty.tmpdir: /tmp (java.io.tmpdir)
12:09:47.863 [DEBUG] i.n.u.i.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
12:09:47.863 [DEBUG] i.n.u.i.PlatformDependent - -Dio.netty.noPreferDirect: false
12:09:47.863 [DEBUG] i.n.u.i.PlatformDependent - io.netty.maxDirectMemory: 3711959040 bytes
12:09:47.872 [DEBUG] i.n.c.n.NioEventLoop - -Dio.netty.noKeySetOptimization: false
12:09:47.874 [DEBUG] i.n.c.n.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
12:09:47.876 [DEBUG] i.n.u.i.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
12:09:47.883 [DEBUG] i.n.u.ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
12:09:47.883 [DEBUG] i.n.u.ResourceLeakDetector - -Dio.netty.leakDetection.maxRecords: 4
12:09:47.883 [DEBUG] i.n.u.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@6b98a075
12:09:47.885 [DEBUG] i.n.u.i.ThreadLocalRandom - -Dio.netty.initialSeedUniquifier: 0x85fefd9596d3e950 (took 0 ms)
12:09:47.897 [DEBUG] i.n.h.s.JdkSslContext - Default protocols (JDK): [TLSv1.2, TLSv1.1, TLSv1]
12:09:47.898 [DEBUG] i.n.h.s.JdkSslContext - Default cipher suites (JDK): [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA]
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 16
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 16
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192
12:09:47.933 [DEBUG] i.n.b.PooledByteBufAllocator - -Dio.netty.allocator.useCacheForAllThreads: true
12:09:47.940 [DEBUG] i.n.b.ByteBufUtil - -Dio.netty.allocator.type: pooled
12:09:47.940 [DEBUG] i.n.b.ByteBufUtil - -Dio.netty.threadLocalDirectBufferSize: 65536
12:09:47.940 [DEBUG] i.n.b.ByteBufUtil - -Dio.netty.maxThreadLocalCharBufferSize: 200000
12:09:48.119 [INFO ] i.g.h.a.HttpEngine - Start warm up
12:09:48.146 [INFO ] i.g.h.a.HttpEngine - Warm up done
Simulation packagename.iam.SSO started...
12:09:48.268 [DEBUG] i.g.h.a.s.HttpTx$ - Sending request=request_0 uri=https:/
/integration.domain.com/iam/accueil/: scenario=SSO, userId=1
12:09:48.322 [DEBUG] i.g.c.c.i.Injector - Start user #1
12:09:48.328 [DEBUG] i.g.c.c.i.Injector - Injecting 1 users, continue=false
12:09:48.329 [INFO ] i.g.c.c.Controller - InjectionStopped expectedCount=1
12:09:48.333 [DEBUG] i.n.b.AbstractByteBuf - -Dio.netty.buffer.bytebuf.checkAccessible: true
12:09:48.333 [DEBUG] i.n.u.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@5f8133eb
12:09:48.337 [DEBUG] i.n.u.i.JavassistTypeParameterMatcherGenerator - Generated: io.netty.util.internal.__matchers__.io.netty.handler.codec.http.HttpObjectMatcher
12:09:48.365 [DEBUG] i.n.u.Recycler - -Dio.netty.recycler.maxCapacity.default: 32768
12:09:48.365 [DEBUG] i.n.u.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
12:09:48.365 [DEBUG] i.n.u.Recycler - -Dio.netty.recycler.linkCapacity: 16
12:09:48.365 [DEBUG] i.n.u.Recycler - -Dio.netty.recycler.ratio: 8
12:09:48.378 [DEBUG] o.a.n.s.InsecureTrustManagerFactory - Accepting a server certificate: CN=integration.domain.com, OU=SERVER, O=Canton de Vaud, C=CH
12:09:48.434 [DEBUG] o.a.n.c.NettyConnectListener - Using new Channel '[id: 0x82f72d6c, L:/10.247.161.251:41598 - R:integration.domain.com/10.120.192.100:443]' for 'GET' to '/iam/accueil/'
12:09:48.438 [DEBUG] i.n.h.s.SslHandler - [id: 0x82f72d6c, L:/10.247.161.251:41598 - R:integration.domain.com/10.120.192.100:443] HANDSHAKEN: TLS_RSA_WITH_AES_128_CBC_SHA
12:09:48.460 [DEBUG] o.a.n.h.HttpHandler -


Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: EmptyByteBufBE)
GET
/iam/accueil/ HTTP/1.1
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0
Host: integration.domain.com


Response DefaultHttpResponse(decodeResult: success, version: HTTP/1.1)
HTTP/1.1 401 Unauthorized
Set-Cookie: rpihttp=rp2i-front; path=/
Date: Fri, 16 Jun 2017 10:09:48 GMT
Server: Apache
WWW-Authenticate: Negotiate
Content-Length: 129
Connection: close
Content-Type: text/html; charset=iso-8859-1


12:09:48.463 [DEBUG] o.a.s.SpnegoEngine - init integration.domain.com
Java config name: /etc/krb5.conf
Loaded from Java config
Search Subject for SPNEGO INIT cred (<<DEF>>, sun.security.jgss.spnego.SpNegoCredElement)
No Subject
Search Subject for Kerberos V5 INIT cred (<<DEF>>, sun.security.jgss.krb5.Krb5InitCredential)
No Subject
12:09:48.472 [ERROR] o.a.s.SpnegoEngine - generateToken
org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
 at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147)
 at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
 at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:187)
 at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at sun.security.jgss.spnego.SpNegoContext.GSS_initSecContext(SpNegoContext.java:882)
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:317)
 ... 48 common frames omitted
Wrapped by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:454)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at org.asynchttpclient.spnego.SpnegoEngine.generateToken(SpnegoEngine.java:141)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.kerberosChallenge(Unauthorized401Interceptor.java:218)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.exitAfterHandling401(Unauthorized401Interceptor.java:147)
 at org.asynchttpclient.netty.handler.intercept.Interceptors.exitAfterIntercept(Interceptors.java:77)
 at org.asynchttpclient.netty.handler.HttpHandler.handleHttpResponse(HttpHandler.java:130)
 at org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:184)
 at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:76)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1228)
 at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1039)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
 at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
 at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:643)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:566)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
 at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
 at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
 at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
 at java.lang.Thread.run(Thread.java:748)
12:09:48.473 [DEBUG] o.a.n.c.ChannelManager - Closing Channel [id: 0x82f72d6c, L:/10.247.161.251:41598 - R:integration.domain.com/10.120.192.100:443]
12:09:48.476 [DEBUG] o.a.n.r.NettyRequestSender - Aborting Future NettyResponseFuture{currentRetry=0,
 isDone=0,
 isCancelled=0,
 asyncHandler=io.gatling.http.ahc.AsyncHandler@1b4bd593,
 nettyRequest=org.asynchttpclient.netty.request.NettyRequest@71e71e9e,
 future=java.util.concurrent.CompletableFuture@3e5d1047[Not completed],
 uri=https://integration.domain.com/iam/accueil/,
 keepAlive=false,
 redirectCount=0,
 timeoutsHolder=org.asynchttpclient.netty.timeout.TimeoutsHolder@6a56961e,
 inAuth=1,
 statusReceived=0,
 touch=1497607788460}


12:09:48.476 [DEBUG] o.a.n.r.NettyRequestSender - No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
 at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147)
 at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
 at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:187)
 at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at sun.security.jgss.spnego.SpNegoContext.GSS_initSecContext(SpNegoContext.java:882)
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:317)
 ... 48 common frames omitted
Wrapped by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:454)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at org.asynchttpclient.spnego.SpnegoEngine.generateToken(SpnegoEngine.java:141)
 ... 45 common frames omitted
Wrapped by: org.asynchttpclient.spnego.SpnegoEngineException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
 at org.asynchttpclient.spnego.SpnegoEngine.generateToken(SpnegoEngine.java:164)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.kerberosChallenge(Unauthorized401Interceptor.java:218)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.exitAfterHandling401(Unauthorized401Interceptor.java:147)
 at org.asynchttpclient.netty.handler.intercept.Interceptors.exitAfterIntercept(Interceptors.java:77)
 at org.asynchttpclient.netty.handler.HttpHandler.handleHttpResponse(HttpHandler.java:130)
 at org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:184)
 at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:76)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1228)
 at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1039)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
 at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
 at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:643)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:566)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
 at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
 at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
 at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
 at java.lang.Thread.run(Thread.java:748)
12:09:48.486 [DEBUG] i.g.h.a.AsyncHandler - Request 'request_0' failed for user 1
org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)
 at sun.security.jgss.krb5.Krb5InitCredential.getInstance(Krb5InitCredential.java:147)
 at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.java:122)
 at sun.security.jgss.krb5.Krb5MechFactory.getMechanismContext(Krb5MechFactory.java:187)
 at sun.security.jgss.GSSManagerImpl.getMechanismContext(GSSManagerImpl.java:224)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:212)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at sun.security.jgss.spnego.SpNegoContext.GSS_initSecContext(SpNegoContext.java:882)
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:317)
 ... 48 common frames omitted
Wrapped by: org.ietf.jgss.GSSException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
 at sun.security.jgss.spnego.SpNegoContext.initSecContext(SpNegoContext.java:454)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:248)
 at sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:179)
 at org.asynchttpclient.spnego.SpnegoEngine.generateToken(SpnegoEngine.java:141)
 ... 45 common frames omitted
Wrapped by: org.asynchttpclient.spnego.SpnegoEngineException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
 at org.asynchttpclient.spnego.SpnegoEngine.generateToken(SpnegoEngine.java:164)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.kerberosChallenge(Unauthorized401Interceptor.java:218)
 at org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor.exitAfterHandling401(Unauthorized401Interceptor.java:147)
 at org.asynchttpclient.netty.handler.intercept.Interceptors.exitAfterIntercept(Interceptors.java:77)
 at org.asynchttpclient.netty.handler.HttpHandler.handleHttpResponse(HttpHandler.java:130)
 at org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:184)
 at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:76)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:435)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
 at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:250)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1228)
 at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1039)
 at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411)
 at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:336)
 at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1294)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:357)
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:343)
 at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:911)
 at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
 at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:643)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:566)
 at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:480)
 at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:442)
 at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
 at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
 at java.lang.Thread.run(Thread.java:748)
12:09:48.488 [WARN ] i.g.h.a.ResponseProcessor - Request 'request_0' failed: o.a.s.SpnegoEngineException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
12:09:48.495 [DEBUG] i.g.h.a.ResponseProcessor -
>>>>>>>>>>>>>>>>>>>>>>>>>>
Request:
request_0: KO o.a.s.SpnegoEngineException: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
=========================
Session:
Session(SSO,1,Map(gatling.http.cache.dns -> io.gatling.http.resolver.ShuffleJdkNameResolver@2e20d91c),1497607788232,0,KO,List(),io.gatling.core.protocol.ProtocolComponentsRegistry$$Lambda$160/1177101170@33adcdd2)
=========================
HTTP request:
GET https://integration.domain.com/iam/accueil/
headers=
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/
*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0
Host: integration.domain.com
realm
=Realm{principal='userid', scheme=KERBEROS, realmName='null', nonce='null', algorithm='null', response='null', qop='null', nc='00000001', cnonce='null', uri='null', methodName='GET', useAbsoluteURI='false', omitQuery='false'}
=========================
HTTP response
:


<<<<<<<<<<<<<<<<<<<<<<<<<
12:09:48.498 [DEBUG] i.g.c.a.Exit - End user #1
12:09:48.499 [DEBUG] i.g.c.c.Controller - End user #1
12:09:48.499 [INFO ] i.g.c.c.Controller - All users are stopped
12:09:48.502 [DEBUG] o.a.n.h.HttpHandler - Channel Closed: [id: 0x82f72d6c, L:/10.247.161.251:41598 ! R:integration.domain.com/10.120.192.100:443] with attribute INSTANCE


================================================================================
2017-06-16 12:09:48                                           0s elapsed
---- Requests ------------------------------------------------------------------
> Global                                                   (OK=0      KO=1     )
> request_0                                                (OK=0      KO=1     )
---- Errors --------------------------------------------------------------------
> o.a.s.SpnegoEngineException: No valid credentials provided (Me      1 (100.0%)
chanism level
: No valid credentials provided (Mechanism level:...

I'm wondering if the Realm object is correct, realName is null.

I check the /etc/krb5.conf and it seems ok. When I manually reproduce the scenario with Firefox everything is ok.

I'm using gatling 2.2.5.

Please let me know if I can provide more logs.

Best regards,
Maxime

Maxime

unread,
Jun 19, 2017, 10:02:59 AM6/19/17
to Gatling User Group
Hi all,

I have some news.

Adding the -Djavax.security.auth.useSubjectCredsOnly=false option solved the following exception:
GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)

Then, I had a new exception:
unsupported key type found the default TGT: 18
This one was solved by installing the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy File". My bad, I thought it was already installed.

So now, I have the following situation: Kerberos authentication is ok, but I can only authenticate with the user who is in the ticket cache, which I can check with the klist command.

I think it should be possible to do an authentication with the user / password specified in the realm
.authRealm(HttpHelper.buildRealm("userid", "passwd", AuthScheme.KERBEROS, false, None, None))

Any idea?

Best regards,
Maxime

Stéphane LANDELLE

unread,
Jun 22, 2017, 10:50:26 AM6/22/17
to gat...@googlegroups.com
Hey there,

Sorry, for some reason, your messages ended up in my spams.

Kerberos support is something very hard to investigate without a testing environment at hand.
Sadly, organizations with such entreprisey authentication mechanism are not very keen on sharing with/granting access to people from the outside.
I'm afraid you'll have to investigate yourself, and hopefully contribute back. Or maybe contract with us so we can investigate in your environment.

Regards,


Stéphane Landelle
GatlingCorp CEO


--
You received this message because you are subscribed to the Google Groups "Gatling User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gatling+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Maxime

unread,
Jun 23, 2017, 8:00:58 AM6/23/17
to Gatling User Group
Hello Stéphane,

Thanks for your answer. I totally understand that you can't reproduce the scenario. That's why I'm investigating as much as I can. Currently, I'm running the scenario in remote debug.

The kerberos authentication is ok if there already a valid ticket, for example with the following command:
$ kinit userid1
Password for userid1@DOMAIN.AD.COM:
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: userid1@DOMAIN.AD.COM


Valid starting       Expires              Service principal
23/06/2017 10:56:12  23/06/2017 20:56:12  krbtgt/DOMAIN.AD.COM@DOMAIN.AD.COM
 renew
until 24/06/2017 10:56:09

In this situation the authentication is ok. I can provide the debug log.
If there is no ticket in the cache the username and the password are prompted.

What I'm trying to do is to use the userid and password parameters of HttpHelper.buildRealm

Credentials are well set in  org.asynchttpclient.Realm

After that the kerberosChallenge method of org.asynchttpclient.netty.handler.intercept.Unauthorized401Interceptor is called, everything looks fine.

I'm trying to understand if it's normal to create a GSSContextImpl with GSSCredential object which is null.
Second option, I have seen that there is several option for the KRb5Module : https://docs.oracle.com/javase/7/docs/jre/api/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html
I tried different combination without success.

I'm sure I'm pretty close to have a valid configuration. 

Please, let me know if you have any idea. I will be happy to share the result with the community.

Best regards,
Maxime

To unsubscribe from this group and stop receiving emails from it, send an email to gatling+u...@googlegroups.com.

Stéphane LANDELLE

unread,
Jun 23, 2017, 8:06:43 AM6/23/17
to gat...@googlegroups.com
Hi Maxime,

Thanks a lot for sharing.
Frankly, I haven't touch this piece of code in AHC for ages, and I was never able to run it myself against a real environment, just unit tests with mocks.
If you end up finding a solution, I'll gladly review any PR you'd submit against AHC or Gatling, but I'm afraid I can't do more than that.

Good luck!

Stéphane Landelle
GatlingCorp CEO


To unsubscribe from this group and stop receiving emails from it, send an email to gatling+unsubscribe@googlegroups.com.

Ashish Kumar

unread,
Jul 27, 2017, 2:44:37 PM7/27/17
to Gatling User Group
Hi Maxime ,
are You able to solve the above problem?

Actually Iam also facing the same problem, Can you Please Helpme out?

Thanks,
Ashish Kumar

Maxime

unread,
Aug 18, 2017, 10:51:49 AM8/18/17
to Gatling User Group
Hello,

Finally I manage to do a Kerberos authentication with AHC and then with Gatling. 

As I explained in my message of the 19th June, the scenario works fine if there were already a valid ticket cache. I discover that it was also possible to enter the login password in the console.

First I do a simple java main to test the Kerberos authentication from this example: https://stackoverflow.com/questions/22774602/jaas-kerberos-authentication-fails-for-user-with-international-characters
It's a good example to validate the Kerberos configuration and to create a custom  CallbackHandler
Creating a custom CallbackHandler is the key to solve this problem.

It took a long time to understand how to use the custom CallbackHandler with the async http client. 
It's possible to define the callback handler with the following settings
Security.setProperty("auth.login.defaultCallbackHandler", KerberosClientCallbackHandler.class.getName());
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");

Finally, I reported these changes in my scenario, the syntax is quite the same
Security.setProperty("auth.login.defaultCallbackHandler", classOf[KerberosClientCallbackHandler].getName)

// Usefull properties if the /etc/krb5.conf file is not set
System.setProperty("java.security.krb5.realm","MYREALM.COM")
System.setProperty("java.security.krb5.kdc","MYREALM.COM")

//cf. https://docs.oracle.com/javase/8/docs/technotes/guides/security/jgss/single-signon.html
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false")

@Ashish, I hope it will help you.

@Stéphane, I still have some interrogations. The username and password parameters for the buildRealm method are not used :
HttpHelper.buildRealm("to...@MYREALM.COM", "titi", AuthScheme.KERBEROS, false, None, None)

Is it common parameters for all the type of authentication that are only used for Basic or Digest authentication?

Best Regards,
Maxime

Ashish Kumar

unread,
Aug 19, 2017, 1:38:09 AM8/19/17
to Gatling User Group
Hi Maxime ,

Thanks for sharing the solution ,Can you please share the KerberosClientCallbackHandler code or scala file.

Thanks,
Ashish Kumar
...

Maxime

unread,
Aug 23, 2017, 3:46:53 AM8/23/17
to Gatling User Group
Hello,

Here is my class KerberosClientCallbackHandler.

import javax.security.auth.callback.*;
import java.io.IOException;

public class KerberosClientCallbackHandler  implements CallbackHandler {

   
private User user = new User("user", "password");

   
public KerberosClientCallbackHandler() {
       
   
}

   
@Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
       
for (Callback callback : callbacks) {
           
if (callback instanceof NameCallback) {
               
NameCallback ncb = (NameCallback) callback;
                ncb
.setName(user.getUsername());
           
} else if (callback instanceof PasswordCallback) {
               
PasswordCallback pwcb = (PasswordCallback) callback;
                pwcb
.setPassword(user.getPassword().toCharArray());
           
} else {
               
throw new UnsupportedCallbackException(callback, "We got a " + callback.getClass().getCanonicalName()
                       
+ ", but only NameCallback and PasswordCallback is supported");
           
}
       
}
   
}
}



@Stéphane, any idea about the purpose of the username and password parameters for the buildRealm method ?

Regards,
Maxime

Pawel Kuras

unread,
Jan 31, 2018, 12:30:19 PM1/31/18
to Gatling User Group
@Maxime, what does your gatling simulation look like.  I created a KerberosClientCallBackHandler (Java class) just like the one you posted, and had no issues logging in using just it.

And in the Simulation I added the following 2 lines

  Security.setProperty("auth.login.defaultCallbackHandler", classOf[KerberosClientCallbackHandler].getName)
  System.setProperty("javax.security.auth.useSubjectCredsOnly", "false")
but am having no luck hitting a page using the simulation.
Reply all
Reply to author
Forward
0 new messages