Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChainAuthHandler.any() doesn't work well with multiple JWTAuthHandlers #2691

Open
ayhanap opened this issue Dec 16, 2024 · 0 comments
Open
Assignees
Labels
Milestone

Comments

@ayhanap
Copy link

ayhanap commented Dec 16, 2024

Version

>=4.5.6

Context

This(#2582) pull request broke multiple JWTAuthHandlers hooked with a ChainAuthHandler.any() (Well actually it wasn't checking for scopes before)

So I am using vertx-web-openapi-router and it creates this similar double JWTAuthHandler inside a ChainAuthHandler when a route has security like this

      security:
        - oauth:
            - 'users:read'
        - oauth:
            - 'users:all'

With the change in referenced PR, ChainAuthHandler now calls postAuthentication for each JWTAuthHandler. But in postAuthentication JWTAuthHandler ends the context while checking for scopes at this line..

ctx.fail(403, new VertxException("JWT scopes != handler scopes", true));

Which causes ChainAuthHandler not to continue with the other handlers in the chain. This flow is not expected as its a any() handler and should continue and be successful if one of the handlers are successful.

Do you have a reproducer?

  @Test
  public void testWithMultipleJWTAuthHandlers() throws Exception {
    router.clear();

    JWTAuth authProvider = JWTAuth.create(vertx, new JWTAuthOptions()
        .setKeyStore(new KeyStoreOptions()
          .setType("jceks")
          .setPath("keystore.jceks")
          .setPassword("secret")));

    chain = ChainAuthHandler.any()
      .add(JWTAuthHandler.create(authProvider).withScope("users:read"))
      .add(JWTAuthHandler.create(authProvider).withScope("users:all"));
    router.route()
      .handler(chain)
      .handler(RoutingContext::end);

    final JsonObject payloadA = new JsonObject()
      .put("sub", "Paulo")
      .put("scope", String.join(" ", Arrays.asList("users:read")));

    testRequest(HttpMethod.GET, "/", req -> req.putHeader("Authorization", "Bearer " + authProvider.generateToken(payloadA)), 200, "OK", null);

    final JsonObject payloadB = new JsonObject()
      .put("sub", "Paulo")
      .put("scope", String.join(" ", Arrays.asList("users:read", "users:all")));

    testRequest(HttpMethod.GET, "/", req -> req.putHeader("Authorization", "Bearer " + authProvider.generateToken(payloadB)), 200, "OK", null);

    final JsonObject payloadC = new JsonObject()
      .put("sub", "Paulo")
      .put("scope",String.join(" ",Arrays.asList("users:all")));

    testRequest(HttpMethod.GET, "/", req -> req.putHeader("Authorization", "Bearer " + authProvider.generateToken(payloadC)), 200, "OK", null);
  }

Steps to reproduce

Add this test to ChainAuthHandlerTest class and run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants