0

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 org.glassfish.soteria@3.0.0//org.glassfish.soteria.mechanisms.openid.domain.AccessTokenImpl.<init>(AccessTokenImpl.java:64)
    at org.wildfly.security.jakarta.security@3.0.0.Beta4//org.wildfly.security.soteria.original.OpenIdCredential.<init>(OpenIdCredential.java:58)
    at org.wildfly.security.jakarta.security@3.0.0.Beta4//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.validateAuthorizationCode(OpenIdAuthenticationMechanism.java:354)
    at org.wildfly.security.jakarta.security@3.0.0.Beta4//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.authenticate(OpenIdAuthenticationMechanism.java:273)
    at org.wildfly.security.jakarta.security@3.0.0.Beta4//org.wildfly.security.soteria.original.OpenIdAuthenticationMechanism.validateRequest(OpenIdAuthenticationMechanism.java:171)
    at org.wildfly.security.jakarta.security@3.0.0.Beta4//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 org.jboss.weld.core@5.0.1.Final//org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38)
    at org.jboss.weld.core@5.0.1.Final//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 org.glassfish.soteria@3.0.0//org.glassfish.soteria.mechanisms.jaspic.HttpBridgeServerAuthModule.validateRequest(HttpBridgeServerAuthModule.java:89)
    at org.wildfly.security.jakarta.authentication@3.0.0.Beta4//org.wildfly.security.auth.jaspi.impl.ElytronServerAuthContext.validateRequest(ElytronServerAuthContext.java:85)
    at org.wildfly.security.jakarta.authentication@3.0.0.Beta4//org.wildfly.security.auth.jaspi.impl.WrappingServerAuthContext.lambda$validateRequest$0(WrappingServerAuthContext.java:50)
    at org.wildfly.security.jakarta.authentication@3.0.0.Beta4//org.wildfly.security.auth.jaspi.impl.ThreadLocalCallbackHandler.get(ThreadLocalCallbackHandler.java:56)
    at org.wildfly.security.jakarta.authentication@3.0.0.Beta4//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 io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59)
    at io.undertow.core@2.3.0.Alpha2//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 io.undertow.core@2.3.0.Alpha2//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at org.wildfly.extension.undertow@27.0.0.Alpha5//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1431)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
    at io.undertow.servlet@2.3.0.Alpha2//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
    at io.undertow.core@2.3.0.Alpha2//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
    at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
    at org.jboss.xnio@3.8.7.Final//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.

Hantsy
  • 8,006
  • 7
  • 64
  • 109
  • Are you including the scopes in your initial request? That's the issue I ran into earlier today. I had nothing and adding the following made everything work: ``` spring.security.oauth2.client.registration.auth0.client-secret: spring.security.oauth2.client.registration.auth0.scope=openid,profile,email``` – Matt Raible Sep 17 '22 at 05:51
  • I have checked the `scope` attribute of `@OpenIdAuthenticationMechanismDefinition`, the default value is `{"openid","email","profile"}`, I did not setup it in my codes, so it should use the default value. – Hantsy Sep 17 '22 at 05:59
  • @MattRaible And I have checked the user history tab in Auth0 console there is a success exchange log. – Hantsy Sep 17 '22 at 06:10

2 Answers2

0

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.

Hantsy
  • 8,006
  • 7
  • 64
  • 109
0

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"}
)
Andrew Hughes
  • 311
  • 3
  • 5