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

Allow token propagation filters to be used within the SecurityIdentityAugmentor #33994

Closed
jskillin-idt opened this issue Jun 12, 2023 · 4 comments · Fixed by #34933
Closed

Allow token propagation filters to be used within the SecurityIdentityAugmentor #33994

jskillin-idt opened this issue Jun 12, 2023 · 4 comments · Fixed by #34933
Labels
area/security kind/enhancement New feature or request
Milestone

Comments

@jskillin-idt
Copy link
Contributor

Description

I tried to write a SecurityIdentityAugmentor that reuses the JWT to check with another service for a set of roles, since the JWT doesn't have the complete set of roles in this envrionment.

Initially, I tried to write a simple Quarkus REST client that used the AccessTokenRequestReactiveFilter and would get the JWT injected into the HTTP Bearer header, but that filter was unable to see a token in the context.

I found some StackOverflow hints that suggested I could strip the raw token from the identity and then wire up the REST client to just toss the token in the HTTP Bearer header, but this feels wrong. It seems like I should be able to wire up Quarkus to do this for me.

This is the code I've come up with, where I'm doing the work of @RegisterProvider(AccessTokenRequestReactiveFilter.class):

  @Override
  public Uni<SecurityIdentity> augment(SecurityIdentity identity, AuthenticationRequestContext context) {
    return context.runBlocking(build(identity));
  }

  @Inject
  @RestClient
  protected AuthServiceClient authServiceClient;

  protected Supplier<SecurityIdentity> build(SecurityIdentity identity) {
    if(identity.isAnonymous()) {
      return () -> identity;
    } else {
      return () -> {
        QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder(identity);
        // TODO: way to do this that doesn't involve handling the raw JWT?
        Principal principal = identity.getPrincipal();
        if (principal instanceof JsonWebToken) {
          JsonWebToken jwtToken = (JsonWebToken) principal;
          List<String> roles = authServiceClient.getRoles(jwtToken.getRawToken());
          roles.forEach(builder::addRole);
        }
        return builder.build();
      };
    }
  }

And then the snippet from the REST client:

  @GET
  @Path("/roles")
  @ClientHeaderParam(name = "Authorization", value = "Bearer {jwtToken}")
  Uni<List<String>> getRoles(@NotBody String jwtToken)

@sberyozkin suggested that it may be possible "the token CDI producers can be tweaked a bit not to rely on the injected security identity" and asked me to open this issue.

Implementation ideas

No response

@jskillin-idt jskillin-idt added the kind/enhancement New feature or request label Jun 12, 2023
@quarkus-bot
Copy link

quarkus-bot bot commented Jun 12, 2023

/cc @sberyozkin (security)

@michalvavrik
Copy link
Member

IMHO it can't be done without CDI or ugly hack because we need to propagate original context with token somehow and OIDC token propagation reactive does not depend on Vert.X web. But it can't be done with injecting access token as it works now. I'll have a look.

@michalvavrik
Copy link
Member

#34933 was only solution I could manage, therefore I'll let someone else to handle this issue.

@quarkus-bot quarkus-bot bot added this to the 3.3 - main milestone Jul 27, 2023
@jskillin-idt
Copy link
Contributor Author

Thank you for your work! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security kind/enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants