Describe the bug
Using smallrye-jwt extension and configure the validation of JAX-RS endpoints with the annotation @Authenticated.
I want to use custom error messages for all the errors in JAX-RS, so I implement a Provider for ExceptionMapper<UnauthorizedException>, this mapper return a JSON response.
Sending a request without the Authorization token header returns correctly the JSON reponse, but if the token gets expired, it returns the "default" response of NO CONTENT with the www-authenticate header.
Expected behavior
Return the custom JSON response of the ExceptionMapper.
Actual behavior
Return the default response of UnauthorizedException, and in DEBUG level shows this stacktrace:
DEBUG [io.qua.sma.jwt.run.aut.MpJwtValidator] (vert.x-eventloop-thread-6) Authentication failed: io.smallrye.jwt.auth.principal.ParseException: Failed to verify token
at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parse(DefaultJWTTokenParser.java:113)
at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator.authenticate(MpJwtValidator.java:55)
at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator.authenticate(MpJwtValidator.java:28)
at io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator_ClientProxy.authenticate(MpJwtValidator_ClientProxy.zig:134)
at io.quarkus.security.runtime.QuarkusIdentityProviderManagerImpl.handleProvider(QuarkusIdentityProviderManagerImpl.java:121)
at io.quarkus.security.runtime.QuarkusIdentityProviderManagerImpl.authenticate(QuarkusIdentityProviderManagerImpl.java:89)
at io.quarkus.security.runtime.IdentityProviderManagerCreator_ProducerMethod_ipm_91f102be1b2a781216db8a81e6ab4b9b1a84f03c_ClientProxy.authenticate(IdentityProviderManagerCreator_ProducerMethod_ipm_91f102be1b2a781216db8a81e6ab4b9b1a84f03c_ClientProxy.zig:105)
at io.quarkus.smallrye.jwt.runtime.auth.JWTAuthMechanism.authenticate(JWTAuthMechanism.java:50)
at io.quarkus.smallrye.jwt.runtime.auth.JWTAuthMechanism_ClientProxy.authenticate(JWTAuthMechanism_ClientProxy.zig:72)
at io.quarkus.vertx.http.runtime.security.HttpAuthenticator.attemptAuthentication(HttpAuthenticator.java:66)
at io.quarkus.vertx.http.runtime.security.HttpAuthenticator_ClientProxy.attemptAuthentication(HttpAuthenticator_ClientProxy.zig:150)
at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$1.handle(HttpSecurityRecorder.java:36)
at io.quarkus.vertx.http.runtime.security.HttpSecurityRecorder$1.handle(HttpSecurityRecorder.java:25)
at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1034)
at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:131)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:130)
at io.quarkus.vertx.http.deployment.devmode.VertxHotReplacementSetup$2.handle(VertxHotReplacementSetup.java:75)
at io.quarkus.vertx.http.deployment.devmode.VertxHotReplacementSetup$2.handle(VertxHotReplacementSetup.java:64)
at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:330)
at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:369)
at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:510)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:518)
at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.jose4j.jwt.consumer.InvalidJwtException: JWT (claims->{"sub":"8eXXXba5-9b5c-4583-XXXX-XXXd74XXXb61","token_use":"access","scope":"openid profile email","auth_time":1583022308,"iss":"https:\/\/cidp.providerdemo.com\/us_edfIwABCD","exp":1583025908,"iat":1583022308,"version":2,"jti":"111111-1111-4402-8f96-66656112e1e","client_id":"demodemodemo","username":"8eXXXba5-9b5c-4583-XXXX-XXXd74XXXb61"}) rejected due to invalid claims or other invalid content. Additional details: [[1] The JWT is no longer valid - the evaluation time NumericDate{1583079968 -> 1 mar. 2020 17:26:08 CET} is on or after the Expiration Time (exp=NumericDate{1583025908 -> 1 mar. 2020 2:25:08 CET}) claim value (even when providing 60 seconds of leeway to account for clock skew).]
at org.jose4j.jwt.consumer.JwtConsumer.validate(JwtConsumer.java:466)
at org.jose4j.jwt.consumer.JwtConsumer.processContext(JwtConsumer.java:311)
at org.jose4j.jwt.consumer.JwtConsumer.process(JwtConsumer.java:433)
at io.smallrye.jwt.auth.principal.DefaultJWTTokenParser.parse(DefaultJWTTokenParser.java:86)
... 27 more
Environment (please complete the following information):
uname -a or ver: Linux mo 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linuxjava -version: 11.0.6GraalVM CE 19.3.11.2.1mvnw --version or gradlew --version): Maven 3.6.3@jorsol Thanks, we have a number of issues related to the fact the security layer operates before the JAX-RS chain has even started. One idea would be to have an option for the security layer to start as a JAX-RS filter
Hi All, please watch #8570. Closing it as a duplicate
Most helpful comment
@jorsol Thanks, we have a number of issues related to the fact the security layer operates before the JAX-RS chain has even started. One idea would be to have an option for the security layer to start as a JAX-RS filter