quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.81k stars 2.69k forks source link

Security annotation error raised at startup when there is a REST client in other jars, when using quarkus-security extension #44443

Closed smil2k closed 1 day ago

smil2k commented 1 day ago

I have the same problem. The controller is in a different module, it is indexed, I've added the annotation and a beans.xml none of them helped. It was working with 3.12

Also the controller did not had any security annotation:

@RegisterRestClient(configKey = "filexchange-client")
@RegisterProvider(AccessTokenRequestReactiveFilter.class)
public interface FileXchangeClient {

    @GET
    @Path("/{visibility}/{fileName}")
    InputStream get(@PathParam("visibility") Visibility visibility, @PathParam("fileName") String fileName);
}

Originally posted by @smil2k in #42187

quarkus-bot[bot] commented 1 day ago

/cc @sberyozkin (security)

michalvavrik commented 1 day ago

Hello @smil2k , as noted here https://github.com/quarkusio/quarkus/issues/42187#issuecomment-2470720226, we do need a reproducer. Thank you

smil2k commented 1 day ago

@michalvavrik

What you call 'controller' judging by the code is a REST client. However this exception cannot be thrown for the REST client because >the code is run during scanning of REST resources. I cannot help without more information. Can you open issue with reproducer, >please?

However, if you actually have secured endpoint that are indexed, it doesn't add up. Reproducer would help.

This exception is thrown for the REST client. I suppose it was broken in 3.13.

Maybe it is scanning these interfaces also and thinks it is a server resource?

This is the exception:

java.lang.RuntimeException: java.lang.ExceptionInInitializerError
        at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:630)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:714)
        at java.base/java.util.Optional.orElseGet(Optional.java:364)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
        at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:467)
        at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:289)
        at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:244)
        at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:597)
        at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:647)
        ... 1 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(Unknown Source)
        ... 7 more
Caused by: java.lang.IllegalStateException: Security annotation placed on resource method 'com.loader.FileXchangeClient#get' wasn't detected by Quarkus during the build time.
Please consult https://quarkus.io/guides/cdi-reference#bean_discovery on how to make the module containing the code discoverable by Quarkus.

        at io.quarkus.resteasy.reactive.server.runtime.security.EagerSecurityHandler$Customizer.handlers(EagerSecurityHandler.java:272)
        at org.jboss.resteasy.reactive.server.core.startup.RuntimeResourceDeployment.addHandlers(RuntimeResourceDeployment.java:638)
        at org.jboss.resteasy.reactive.server.core.startup.RuntimeResourceDeployment.buildResourceMethod(RuntimeResourceDeployment.java:209)
        at org.jboss.resteasy.reactive.server.core.startup.RuntimeDeploymentManager.deploy(RuntimeDeploymentManager.java:136)
        at io.quarkus.resteasy.reactive.server.runtime.ResteasyReactiveRecorder.createDeployment(ResteasyReactiveRecorder.java:154)
        at io.quarkus.deployment.steps.ResteasyReactiveProcessor$setupDeployment713137389.deploy_5(Unknown Source)
        at io.quarkus.deployment.steps.ResteasyReactiveProcessor$setupDeployment713137389.deploy(Unknown Source)
        ... 8 more
smil2k commented 1 day ago

Ok, I found a source of the problem:

Another (server resource) implemented this interface, therefore the client interface became a server resource description also.

michalvavrik commented 1 day ago

thanks for confirming @smil2k