Quarkus ContainerRequestFilter verify user in repository

Viewed 60

I want to implement a custom filter jwt in my project. When i verify this email in postgres, i can't call repository in ContainerRequestFilter.

My filter

@Provider
@PreMatching
public class SecurityFilter implements ContainerRequestFilter {
  @Inject
  JsonWebToken jwt;

  @Inject
  UserRepository userRepository;

  private boolean hasJwt() {
    return jwt.getClaimNames() != null;
  }

  @Override
  public void filter(ContainerRequestContext requestContext) {
    if (hasJwt()) {
      String email = requestContext.getSecurityContext().getUserPrincipal().getName();

      User user = userRepository.findByEmail(email);
      System.out.println(email);
      
    } else {
      System.out.println("No jwt");
    }
  }
}

My repository

@ApplicationScoped
public class UserRepository implements PanacheRepository<User> {

  public User findByEmail(String email) {
    return find("email", email).firstResult();
  }
}

Error


2022-09-08 11:08:16,356 ERROR [org.jbo.res.rea.com.cor.AbstractResteasyReactiveContext] (vert.x-eventloop-thread-1) Request failed: io.quarkus.runtime.BlockingOperationNotAllowedException: You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking EntityManager operations make sure you are doing it from a worker thread.
    at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.checkBlocking(TransactionScopedSession.java:115)
    at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createQuery(TransactionScopedSession.java:346)
    at org.hibernate.engine.spi.SessionLazyDelegator.createQuery(SessionLazyDelegator.java:542)
    at org.hibernate.engine.spi.SessionLazyDelegator.createQuery(SessionLazyDelegator.java:65)
    at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.createQuery(Unknown Source)
    at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:362)
    at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:338)
    at io.quarkus.hibernate.orm.panache.common.runtime.CommonPanacheQueryImpl.firstResult(CommonPanacheQueryImpl.java:283)
    at io.quarkus.hibernate.orm.panache.runtime.PanacheQueryImpl.firstResult(PanacheQueryImpl.java:159)

How can i call repository in this filter

1 Answers

I suppose you are using quarkus-resteasy-reactive in combination with quarkus-hibernate-orm (non reactive).

You are trying to call a blocking operation (hibernate) in a non-blocking context (resteasy-reactive).

You can get around this by using the @Blocking annotation on the UserRepository#findByEmail method. This method will be then use a worker thread and won't block the I/O thread of the non-blocking context.

So in your example:

@ApplicationScoped
public class UserRepository implements PanacheRepository<User> {

  @Blocking
  public User findByEmail(String email) {
    return find("email", email).firstResult();
  }
}

Sources: https://quarkus.io/blog/resteasy-reactive-smart-dispatch/#to-block-or-not-to-block-that-is-the-question

Related