In the quarkus security-jwt, the token payloads contains the claim groups
that can be used to control endpoint access.
But I'm looking for a way to load the claim groups
from another source, like from a database or from a http request send to another service.
Currently, I'm trying to load them from my database inside the principal factory, as described in the Quarkus security-jwt guide.
How ever, these is a blocking process, so Quarkus throws the exception io.quarkus.runtime.BlockingOperationNotAllowedException: Cannot start a JTA transaction from the IO thread.
I've already try using quarkus-hibernate-orm-panache
and quarkus-hibernate-reactive-panache
packages, but no success so far.
import io.smallrye.common.annotation.Blocking;
import io.smallrye.jwt.auth.principal.*;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Alternative;
import org.jose4j.jwt.consumer.JwtContext;
import org.jose4j.jwx.JsonWebStructure;
import java.util.Set;
@ApplicationScoped
@Alternative
@Priority(1)
public class JwtPrincipalFactory extends JWTCallerPrincipalFactory {
private final DefaultJWTTokenParser parser = new DefaultJWTTokenParser();
@Blocking
@Override
public JWTCallerPrincipal parse(final String token, final JWTAuthContextInfo context) throws ParseException {
final JwtContext jwtContext = this.parser.parse(token, context);
final String type = ((JsonWebStructure) jwtContext.getJoseObjects().getFirst()).getHeader("typ");
// TODO: io.quarkus.runtime.BlockingOperationNotAllowedException: Cannot start a JTA transaction from the IO thread.
final Set<String> groups = Set.of("none");
// insert "groups" into context claims
jwtContext.getJwtClaims().setClaim("groups", groups);
return new DefaultJWTCallerPrincipal(type, jwtContext.getJwtClaims());
}
}
Using the custom JWT factory works better when you need to customize or optimize the verification, but if you prefer to use it to augment the token content from DB, then it must be run in a blocking mode, see https://quarkus.io/guides/security-jwt#blocking-calls. But the recommended Quarkus security way for augmenting the identity is to use SecurityIdentityAugmentor
, see https://quarkus.io/guides/security-customization#security-identity-customization