Brandon
Brandon

Reputation: 25

Vert.x JWT Not enough or too many segments

I am continually getting an error when my application receives a JWT token from the front end application, which is authenticating through KeyCloak. The error I am getting is "Not enough or too many segments". As far as I can tell, the token is a valid token and should be able to be verified, but I cannot get past this very generic error. Could someone please help me see what I am doing wrong?

Here is the relevant snippet of code that is failing. Note that the same code works fine when running my test cases, which use the vert.x JWTAuth provider to generate a token:

JWTAuth authProvider = JWTAuth.create(vertx, new JWTAuthOptions(new JsonObject()
    .put("permissionsClaimKey", "realm_access/roles")
    .put("pubSecKeys", new JsonObject()
            .put("publicKey", "vcVtWG5Qcz9gTMrDPfJSWNAiXsyCyBmNIzjtfHhBDX-l60KHyFaGBGBjRNkzDysV6pr6drQR8zRD8ePo8q73KDbXlZohXkR_J-gXer8H5EyWGl7KAATmKvuiYYv89f_C6f3NYUgfyKn6wzUtlsZN1CYpGmbnfLZYUcGzwvWWkddqQUroRrsf305Z17Pioegd_JMhcdprC1caOCuJHe46bYlu4_9m_MSPvBUCqjqAUIDZpB8HT9xrwxlwKG_Er6l-7TvQ32jp0wPxitLpEUg9noAt5w2NXIX44PCSkOdtGxGpj7fhyfivi_HQEfTq3Y4N2BRWAQxXYRaHlgl08CIsLb5rgJXmh8O7506V0THyLcJZ3pTn0u_4KxedOTsEbM_07W8kNCXVQrTIn4Zkyz42geRfblAzjvScP962DzEqu28WVZXWUyJIeQA_z3UM0l-MpQFtFDHsb0inQdeBfA6IN_eRp-JZaoMKLfswUEXjEj6nytKnwOEaqdqq56uPPK1j7QorIjMyn9VztH1WbbWM_JNPNc5CDAjFxo54tvrzqKkxLNbR1lP8g5GbIBeGSRc36IXQEp2hV42i3Pu-7bPJ_E0m9vr5dePjeRotthDUR7osmhOlzqHrLq1uzUYYneK37j7lLMx7N67rkWWMBa3v0h57pVD9ufAd-BxHiQzZL2U")
            .put("type", "RS256"))));

...

versionOneAPI.route().handler(ctx -> {
    String authHeader = ctx.request().getHeader("Authorization");
    String encodedToken = authHeader.substring(authHeader.indexOf(' ')+1);
    LOGGER.debug("Got the token {}", encodedToken);
    authProvider.authenticate(new JsonObject().put("jwt", encodedToken), res -> {
        LOGGER.debug("Request received for: {}", ctx.request().path());
        if (res.succeeded()) {
            LOGGER.debug("Got the user {} from the token", res.result().principal().getString("name"));
            ctx.setUser(res.result());
            ctx.response().putHeader(CONTENT_TYPE, APPLICATION_JSON.toString());
            ctx.next();
        }
        else {
            LOGGER.error("Failed to parse token with {} segments", encodedToken.split("\\.").length, res.cause());
            ctx.response().setStatusCode(UNAUTHORIZED.code()).setStatusMessage(UNAUTHORIZED.reasonPhrase()).end();
        }
    });
});

Here is a sample from the log showing the failure:

15:22:14.930 [main] DEBUG groovyx.net.http.RESTClient - POST http://localhost:8080/rest/v1/referrals 15:22:15.069 [vert.x-eventloop-thread-0] DEBUG com.redhat.rhambassador.MainVerticle - Got the token eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJscVRYamlvRU9HbnBPenVLSllJOGs4VXFUTThSanBKOWc2bmVIb3pXVm9nIn0.eyJqdGkiOiIzODJiN2Q3OS00MTlkLTQ1ZDItYmU4NS0zY2JkZDA0YTg2ZmQiLCJleHAiOjE1MTEzNjk0NTAsIm5iZiI6MCwiaWF0IjoxNTExMzY5MTUwLCJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tL2F1dGgvcmVhbG1zL0VtcGxveWVlSURQIiwiYXVkIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSIsInN1YiI6ImUwYzc4MTY5LTMyYWUtNDQ1Yy05YWYxLWUwYmVlYjI2YTgxNCIsInR5cCI6IkJlYXJlciIsImF6cCI6Imh0dHBzOi8vZXhhbXBsZS5jb20iLCJub25jZSI6ImY4MjYzNDU5LWJlYTgtNGQzMi04ODBjLTcxNGNhMjdiMGM2NSIsImF1dGhfdGltZSI6MTUxMTM2NjY0Niwic2Vzc2lvbl9zdGF0ZSI6IjVlYTgyMTA3LTI0MWMtNGViMy04MWY3LWU4ZmMxM2E3MWQ5MSIsImFjciI6IjAiLCJjbGllbnRfc2Vzc2lvbiI6IjA1MzUxYjU4LTcyODItNDgxZS1iMjk2LTFjNDExYjUzMmI2NCIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwczovL2V4YW1wbGUuY29tIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJFbXBsb3llZSJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJsYXN0TmFtZSI6IkRvZSIsImZpcnN0TmFtZSI6IkpvaG4iLCJlbXBsb3llZVR5cGUiOiJFbXBsb3llZSIsIm5hbWUiOiJKb2huIERvZSIsInJoYXRVVUlEIjoiMTc5YmY0MTYtY2ZhNy0xMWU3LTkxNGUtNTRlZTc1OTMyOTU1IiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamRvZSIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJlbWFpbCI6Impkb2VAZXhhbXBsZS5jb20ifQ==.ZWmsuIRsXeSdE_xefG_o-vYUZR4os_87jgd-7s9BC_-w1bHJ4K3tAIH3r_SxFS1hOYRxO3wsKniePkhcgfyHKDPpvSNc-HLsx3guARDGsdRiqEgszSoJTYvU_XRVcR8FEPPDs0vIov540A9mPPqpH4MPVK-dgZHH5IaSWpceeA91wmL5dh3Z-0nK5wIeFxDw-8PfzSzrF0crTG8Mr9KwaTr9iCTYta13kxIW3WU8xHe6qSYaQEJmKpj4y6YNtwdGvmVn9B9TngSBRliz-4nDj-WcVuWahkppSnuRgEEDsxFZ5DXvnKhK5j1aaU4HSamz7qd2UsgPya7DxpBHHIhcOp0fOzVcDJl4vm_zxnX7cO5Ulm4Vsn-Q5iFMHunXwtNkmxGxQrqWz24CYWF_CxMvcHgjK9pqGeJ6S43v2jQvTPA5dL6dcEhNOd6RH3dD7PJjhXN5b0MP-McjoJXoktnvNRLim_n2Dnsn-t3ceJhJVMqoYPvRd_F51Is1Rcuy3qzNRYtoeiHAkacHIzR5UxPheYtzyo0dtxz9dtHgd-WlWFFL4GyxRb5Ex6153JAZSK4neT4gAXldnSQqqDGHt1XZaeBR4G3l5bffozPuYCR9wDwtkNMI5VK5Q9o81mXdQen0DPt4XZgtSkQOoudNduZFhOy6GIzJAbiNifqJpOyud64 15:22:15.070 [vert.x-eventloop-thread-0] DEBUG com.redhat.rhambassador.MainVerticle - Request received for: /rest/v1/referrals 15:22:15.072 [vert.x-eventloop-thread-0] ERROR com.redhat.rhambassador.MainVerticle - Failed to parse token with 3 segments java.lang.RuntimeException: Not enough or too many segments at io.vertx.ext.jwt.JWT.decode(JWT.java:321) at io.vertx.ext.auth.jwt.impl.JWTAuthProviderImpl.authenticate(JWTAuthProviderImpl.java:114) at com.redhat.rhambassador.MainVerticle.lambda$buildRoutes$7(MainVerticle.java:197) at io.vertx.ext.web.impl.RouteImpl.handleContext(RouteImpl.java:223) at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:101) at io.vertx.ext.web.impl.RoutingContextWrapper.next(RoutingContextWrapper.java:149) at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.doEnd(BodyHandlerImpl.java:209) at io.vertx.ext.web.handler.impl.BodyHandlerImpl$BHandler.end(BodyHandlerImpl.java:187) at io.vertx.ext.web.handler.impl.BodyHandlerImpl.lambda$handle$0(BodyHandlerImpl.java:68) at io.vertx.core.http.impl.HttpServerRequestImpl.handleEnd(HttpServerRequestImpl.java:418) at io.vertx.core.http.impl.ServerConnection.handleLastHttpContent(ServerConnection.java:475) at io.vertx.core.http.impl.ServerConnection.handleContent(ServerConnection.java:469) at io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:449) at io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:156) at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:705) at io.vertx.core.http.impl.HttpServerImpl$ServerHandlerWithWebSockets.handleMessage(HttpServerImpl.java:614) at io.vertx.core.net.impl.VertxHandler.lambda$channelRead$1(VertxHandler.java:150) at io.vertx.core.impl.ContextImpl.lambda$wrapTask$2(ContextImpl.java:342) at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:200) at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:148) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:284) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) at java.lang.Thread.run(Thread.java:748)

Upvotes: 0

Views: 2409

Answers (2)

Didar Burmaganov
Didar Burmaganov

Reputation: 632

Try to use vertx's jwt handler, it sets user to routing context and does authentication for you

JWTAuth jwtAuth = JWTAuth.create(vertx, new JWTAuthOptions()
        .setPermissionsClaimKey("realm_access/roles")
        .addPubSecKey(new PubSecKeyOptions()
            .setType("RS256")
            .setPublicKey("....your key"));

router.route("/api/rest/a/*").handler(JWTAuthHandler.create(jwtAuth));

Upvotes: 1

Paulo Lopes
Paulo Lopes

Reputation: 5801

The issue is that the config JSON is not correct it should be:

JWTAuth authProvider = JWTAuth.create(vertx, new JWTAuthOptions(new JsonObject()
.put("permissionsClaimKey", "realm_access/roles")
.put("pubSecKeys", new JsonArray()
   .add(new JsonObject()
      .put("publicKey", "...")
      .put("type", "RS256")))));

pubSecKeys is an array of objects. To be safer you probably should not use the JSON config but the typed one.

Upvotes: 0

Related Questions