Search code examples
cdiquarkus

Override beans from an external library (Quarkus)


I want to override a bean that's used by Quarkus to disable authentication/authorization.

With the following implementation, it works that REST endpoints can be configured at start time to not be secured:

@Alternative
@Priority(1)
@ApplicationScoped
public class CustomOidcAuthController extends TestAuthController {

    private static final Logger LOGGER = Logger.getLogger(CustomOidcAuthController.class);

    @ConfigProperty(name = "quarkus.oidc.enabled", defaultValue = "false")
    boolean quarkusOidcEnabled;

    @PostConstruct
    public void check() {
        LOGGER.info("isAuthorizationEnabled(): " + isAuthorizationEnabled());
    }

    @Override
    public boolean isAuthorizationEnabled() {
        return quarkusOidcEnabled;
    }
}

This is with the Bean residing in the same Quarkus module.

However, I want to externalize this class into a separate library and if I do this, it no longer works.

Noteworthy:

  1. Yes, the @Priority of my bean (1) is higher than the default (3000)
  2. The beans are discovered, if I explicitly inject them.
  3. They are however not used, if I inject the subtype that Quarkus uses internally (either TestAuthController or AuthorizationController).
    • Therefore the endpoints are always secured
    • As can be seen here from the IntelliJ debugger enter image description here
  4. Currently I have an empty beans.xml, but with building a Jandex Index I also observe the same behavior (related How to create a Jandex index in Quarkus for classes in a external module)
  5. I can get the behavior I want, if I use quarkus.arc.selected-alternatives=com.xxx.CustomOidcAuthController, however this is not preferable, since each Service using the library would need to configure this and this will certainly cause problems, because it can be easily forgotten.

Solution

  • Well, the priority of the TestAuthController is indeed 3000 and therefore it takes precedence. Injection of CustomOidcAuthController works because there's no other bean that has CustomOidcAuthController in its set of bean types.

    In other words, it works as expected (and defined by the spec).