quarkusio / quarkus

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

Smallrye JWT authentication not working on Azure App Function in Quarkus #39107

Open amal-sebs opened 4 months ago

amal-sebs commented 4 months ago

Describe the bug

I have created a Quarkus Application which has Azure App functions and Controllers as well. Authentication using Smallrye jwt is not working in the case of Azure App functions but working for Controllers.

I have an app function for login which works perfectly fine without the authentication and the Azure App function will return the result if the Roles Allowed annotation is removed.

Expected behavior

To return the result according to the correct Role

Actual behavior

Always getting 500 internal server error. In the logs seeing Unauthorized error.

How to Reproduce?

Add the smallrye to the application. Add the Roles allowed annotation to the the function to test. Call the function with HTTP method

Output of uname -a or ver

No response

Output of java -version

OpenJDK 11

Quarkus version or git rev

Quarkus - 3.5.1

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.9.5

Additional information

No response

quarkus-bot[bot] commented 4 months ago

/cc @Ladicek (smallrye), @jmartisk (smallrye), @phillip-kruger (smallrye), @radcortez (smallrye), @sberyozkin (jwt)

sberyozkin commented 4 months ago

@amal-sebs Please provide more details, such as the cause of 500 (stacktrace) etc, see also https://quarkus.io/guides/security-jwt#how-to-check-the-errors-in-the-logs

amal-sebs commented 4 months ago

This is my function-> @FunctionName("fruits") @RolesAllowed({"user"}) @SecurityRequirement(name = "jwt") public HttpResponseMessage getFruits(@HttpTrigger( name = "getFruits", methods = {HttpMethod.POST}, authLevel = AuthorizationLevel.ANONYMOUS, route = "/getFruits") HttpRequestMessage request, final ExecutionContext context)

Stack Trace -> Exception: UnauthorizedException: Stack: java.lang.reflect.InvocationTargetException [2024-03-01T12:40:18.191Z] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [2024-03-01T12:40:18.200Z] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [2024-03-01T12:40:18.203Z] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [2024-03-01T12:40:18.207Z] at java.base/java.lang.reflect.Method.invoke(Method.java:566) [2024-03-01T12:40:18.217Z] at com.microsoft.azure.functions.worker.broker.JavaMethodInvokeInfo.invoke(JavaMethodInvokeInfo.java:22) [2024-03-01T12:40:18.220Z] at com.microsoft.azure.functions.worker.broker.EnhancedJavaMethodExecutorImpl.execute(EnhancedJavaMethodExecutorImpl.java:22) [2024-03-01T12:40:18.222Z] at com.microsoft.azure.functions.worker.chain.FunctionExecutionMiddleware.invoke(FunctionExecutionMiddleware.java:19) [2024-03-01T12:40:18.230Z] at com.microsoft.azure.functions.worker.chain.InvocationChain.doNext(InvocationChain.java:21) [2024-03-01T12:40:18.234Z] at io.quarkus.azure.functions.runtime.QuarkusAzureFunctionsMiddleware.invoke(QuarkusAzureFunctionsMiddleware.java:19) [2024-03-01T12:40:18.236Z] at com.microsoft.azure.functions.worker.chain.InvocationChain.doNext(InvocationChain.java:21) [2024-03-01T12:40:18.241Z] at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:125) [2024-03-01T12:40:18.247Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:34) [2024-03-01T12:40:18.250Z] at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10) [2024-03-01T12:40:18.253Z] at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:44) [2024-03-01T12:40:18.259Z] at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:94) [2024-03-01T12:40:18.269Z] at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [2024-03-01T12:40:18.273Z] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) [2024-03-01T12:40:18.279Z] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [2024-03-01T12:40:18.291Z] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [2024-03-01T12:40:18.300Z] at java.base/java.lang.Thread.run(Thread.java:834) [2024-03-01T12:40:18.304Z] Caused by: io.quarkus.security.UnauthorizedException [2024-03-01T12:40:18.306Z] at io.quarkus.security.runtime.interceptor.check.RolesAllowedCheck.doApply(RolesAllowedCheck.java:70) [2024-03-01T12:40:18.308Z] at io.quarkus.security.runtime.interceptor.check.RolesAllowedCheck.apply(RolesAllowedCheck.java:55) [2024-03-01T12:40:18.310Z] at io.quarkus.security.runtime.interceptor.SecurityConstrainer.check(SecurityConstrainer.java:34) [2024-03-01T12:40:18.314Z] at io.quarkus.security.runtime.interceptor.SecurityHandler.handle(SecurityHandler.java:46) [2024-03-01T12:40:18.319Z] at io.quarkus.security.runtime.interceptor.RolesAllowedInterceptor.intercept(RolesAllowedInterceptor.java:29) [2024-03-01T12:40:18.322Z] at io.quarkus.security.runtime.interceptor.RolesAllowedInterceptor_Bean.intercept(Unknown Source) [2024-03-01T12:40:18.325Z] at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42) [2024-03-01T12:40:18.326Z] at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:70) [2024-03-01T12:40:18.336Z] at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62) [2024-03-01T12:40:18.340Z] at io.quarkus.resteasy.reactive.server.runtime.StandardSecurityCheckInterceptor.intercept(StandardSecurityCheckInterceptor.java:44) [2024-03-01T12:40:18.344Z] at io.quarkus.resteasy.reactive.server.runtime.StandardSecurityCheckInterceptor_RolesAllowedInterceptor_Bean.intercept(Unknown Source) [2024-03-01T12:40:18.374Z] at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42) [2024-03-01T12:40:18.387Z] at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30) [2024-03-01T12:40:18.399Z] at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27) [2024-03-01T12:40:18.439Z] ... 20 more

sberyozkin commented 4 months ago

@amal-sebs I have to admit I don't know how the infrastructure for hosting the Azure functions supports this jwt requirement. Is the token already verified at the gateway ? AFAIK, for the Amazon functions, in this case the already verified token (by Cognito I guess) is mapped to the Quarkus security identity, so may be this is what is needed for the Azure functions case too

sberyozkin commented 4 months ago

and what is authLevel = AuthorizationLevel.ANONYMOUS ?

amal-sebs commented 4 months ago

and what is authLevel = AuthorizationLevel.ANONYMOUS ?

There are three authLevels -> ANONYMOUS(no api key required, but enforcement of keys is possible), FUNCTION(function specific key required) and ADMIN

amal-sebs commented 4 months ago

@amal-sebs I have to admit I don't know how the infrastructure for hosting the Azure functions supports this jwt requirement. Is the token already verified at the gateway ? AFAIK, for the Amazon functions, in this case the already verified token (by Cognito I guess) is mapped to the Quarkus security identity, so may be this is what is needed for the Azure functions case too

I just went through what was done for Amazon functions and yes something similar is need for Azure functions too.

sberyozkin commented 4 months ago

@amal-sebs Thanks for confirming, would you like to work on the PR ? FYI, https://github.com/quarkusio/quarkus/blob/main/CONTRIBUTING.md

sberyozkin commented 4 months ago

This is a duplicate of #32479, but I'll close #32479 instead as this issue is newer. Workaround is shown in #32479, but I'd like to encourage you to go ahead with the fix

michalvavrik commented 4 months ago

/cc @patriot1burke