JakartaEE 10 OpenIdAuthenticationMechanism failed with Auth0

617 Views Asked by At

Got help from the Redhat guy, finally my example works with Local KeyCloak(in Docker) as well as Okta.

My example is here: https://github.com/hantsy/jakartaee10-sandbox/tree/master/security-oidc

And I used the following stack when preparing the example codes.

  • Java 17
  • Jakarta EE 10
  • Wildfly Preview 27.0.0.Alpha5

But for the Auth0, it always throws a NPE when returning back to my application.

Error processing request
Context Path:
/security-oidc-examples

Servlet Path:
/callback

Path Info:
null

Query String:
code=uaOVw2pkvGnnrG-IcVR8qTsu7U2-B8zM2ig6OGBp_6olR&state=48e113ef-4bad-4c29-910e-a41cab8ca968

Stack Trace:

java.lang.NullPointerException: Cannot invoke "com.nimbusds.jwt.JWTClaimsSet.getClaims()" because "jwtClaimsSet" is null
    at [email protected]//org.glassfish.soteria.mechanisms.openid.domain.AccessTokenImpl.<init>(AccessTokenImpl.java:64)
    at [email protected]//org.wildfly.security.soteria.original.OpenIdCredential.<init>(OpenIdCredential.java:58)
    at [email protected]//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.validateAuthorizationCode(OpenIdAuthenticationMechanism.java:354)
    at [email protected]//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.authenticate(OpenIdAuthenticationMechanism.java:273)
    at [email protected]//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.validateRequest(OpenIdAuthenticationMechanism.java:171)
    at [email protected]//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism$Proxy$_$$_WeldClientProxy.validateRequest(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at [email protected]//org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
    at [email protected]//org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:106)
    at deployment.security-oidc-examples.war//org.jboss.weld.generated.proxies.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism$397943940$Proxy$_$$_WeldClientProxy.validateRequest(Unknown Source)
    at [email protected]//org.glassfish.soteria.mechanisms.jaspic.HttpBridgeServerAuthModule.validateRequest(HttpBridgeServerAuthModule.java:89)
    at [email protected]//org.wildfly.security.auth.jaspi.impl.ElytronServerAuthContext.validateRequest(ElytronServerAuthContext.java:85)
    at [email protected]//org.wildfly.security.auth.jaspi.impl.WrappingServerAuthContext.lambda$validateRequest$0(WrappingServerAuthContext.java:50)
    at [email protected]//org.wildfly.security.auth.jaspi.impl.ThreadLocalCallbackHandler.get(ThreadLocalCallbackHandler.java:56)
    at [email protected]//org.wildfly.security.auth.jaspi.impl.WrappingServerAuthContext.validateRequest(WrappingServerAuthContext.java:50)
    at org.wildfly.security.elytron-web.undertow-server-servlet@3.0.0.Beta1//org.wildfly.elytron.web.undertow.server.servlet.ServletSecurityContextImpl.authenticate(ServletSecurityContextImpl.java:174)
    at org.wildfly.security.elytron-web.undertow-server-servlet@3.0.0.Beta1//org.wildfly.elytron.web.undertow.server.servlet.ServletSecurityContextImpl.authenticate(ServletSecurityContextImpl.java:99)
    at [email protected]//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
    at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at [email protected]//io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53)
    at [email protected]//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at [email protected]//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at [email protected]//io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59)
    at [email protected]//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at org.wildfly.security.elytron-web.undertow-server-servlet@3.0.0.Beta1//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
    at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at [email protected]//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at [email protected]//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at [email protected]//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
    at [email protected]//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
    at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
    at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
    at [email protected]//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at [email protected]//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at [email protected]//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
    at [email protected]//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
    at [email protected]//io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
    at [email protected]//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
    at [email protected]//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at [email protected]//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at [email protected]//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
    at java.base/java.lang.Thread.run(Thread.java:833)

I have checked the auth0 console, there is a Client Login and Success Exchange log in the user History tab. Thus the access token is authorized in the Auth0 side.

To reproduce it, follow these steps:

  • Check out the exmaple codes
  • Create a regular web application in Auth0 and setup domain, clientId and clientSecret in the openid.properties file
  • Run mvn clean package wildfly:run -Pwildfly
  • Open a browser and navigate to http://localhost:8080/security-oidc-examples/protected

Update: tried on WildFly 27.0.0.Beta1, got the same exception.

2

There are 2 best solutions below

0
Hantsy On BEST ANSWER

Finally I got it work by adding the jwksReadTimeout = 5000 to the @OpenIdAuthenticationMechanismDefinition.

The Jakarta EE Security implementation does not throw the raw exception message to developers, it is very difficult to find the root cause. I tried to clone the soteria project and added some debug info and changed to catch all exceptions (catch(Exception e){}) in the AccessTokenImpl, I used my custom build version to replace the WildFly built-in module, and finally find the reason.

This maybe only a specific network issue on my side.

0
Andrew Hughes On

I ran into the exact same problem with Jakarta EE 10 OIDC, Auth0, and Wildfly 27. What I discovered was that Auth0 returns an opaque token by default unless an audience is specified. Jakarta's Security 3 was unable to validate the opaque token or get any claims from it, causing the jwtClaimsSet is null error.

I found that I had to add an audience to the extraParameters parameter of the annotation. The audience is an API created on Auth0. This caused Auth0 to send a non-opaque token, which Jakarta was then able to unpack and validate.

@OpenIdAuthenticationMechanismDefinition(
        providerURI = "${openIdConfig.issuerUri}",
        clientId = "${openIdConfig.clientId}",
        clientSecret = "${openIdConfig.clientSecret}",
        redirectURI = "${baseURL}/callback",
        // default 500ms caused timeouts for me
        jwksConnectTimeout = 5000,
        jwksReadTimeout = 5000,
        extraParameters = {"audience=http://my-api"}
)