elytron-oidc-client, how to add additional values to the scope parameter?

1,008 views
Skip to first unread message

ion

unread,
Jun 22, 2022, 12:18:57 AM6/22/22
to WildFly
Hi,

I am trying to configure elytron-oidc-client with Azure OIDC.
I'm using WF26 and I configured the elytron-oidc-client :
        <subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0">
            <provider name="azure">
                <provider-url>https://azure-url</provider-url>
                <ssl-required>external</ssl-required>
            </provider>
            <secure-deployment name="simple-webapp.war">
                <provider>azure</provider>
                <client-id>my-client-id</client-id>
                <credential name="secret" secret="my-client-secret" />
            </secure-deployment>
        </subsystem>

When I try to access the application I'm redirected to the Azure login and the requests seem to flow back and forth however it is failing to authenticate with this error:
ELY23013: Failed verification of token: ELY23019: Invalid ID token

I tested the Azure login with a sample spring boot application and it is successful when the scope parameter in the redirect to Azure includes the client id and offline_access besides openid. It is failing if the scope has only openid.

Looking at the logs it seems that elytron is only sending the openid in the scope.
How can I configure elytron to send the additional values in the scope?

Tried also with earlier WF version with Keycloak with no luck.

Any help is appreciated.
Thanks,
Ion

 

Farah Juma

unread,
Jun 22, 2022, 12:02:20 PM6/22/22
to WildFly
Thank you for trying this out.

Are there more details in the server log related to the invalid ID token?

Another thing to watch out for is that the current OIDC support assumes access tokens are JWTs. If the access tokens returned by Azure OIDC are opaque tokens, this won't work yet. ELY-2202 tracks adding support for this.

Ion Moraru

unread,
Jun 22, 2022, 1:23:47 PM6/22/22
to Farah Juma, WildFly
Hi Farah,

Unfortunately all I see in the logs is this line:
16:40:17,858 ERROR [org.wildfly.security.http.oidc] (default task-2) ELY23013: Failed verification of token: ELY23019: Invalid ID token
There is no other explanation on why it failed.

I have checked the logs to see what’s returned by Azure and I can see the id_token. I have decoded it at https://jwt.io and the type is JWT, looks good, signature is verified:


I am not sure if the problem is with the token, I wish I had more information in the log, but in my tests using spring boot I had to send the client id, openid and offline_access in the scope in order to be successful.
I would like to try that to see if it solving the problem but I don’t know how to configure elytron-oidc-client to send the additional attributes in the scope.

To be honest my current version of the application is working on an earlier version of  WF and I was using keycloak adapter but it fails with Azure. I don’t know how to configure the scope for the keycloak adapter either. I was trying to use elytron to see if it solves the issue.

If you can point me to some examples it would be great.

If you need more information please let me know.
Thanks,
Ion


 

-- 
You received this message because you are subscribed to a topic in the Google Groups "WildFly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/wildfly/Jez_5ieZHkE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to wildfly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wildfly/ce924ce7-a642-4141-ada2-8b08edd22222n%40googlegroups.com.

Farah Juma

unread,
Jun 22, 2022, 3:43:16 PM6/22/22
to WildFly
Currently, it isn't possible to configure additional scope values. Would you be able to create a WFLY issue so we can look into adding that?

I've created ELY-2353 so we can improve the logging for the future.

We will be looking to test our OIDC support with other OpenID Providers besides Keycloak so we will also take a closer look at the ID token and access token format returned by Azure.

Ion Moraru

unread,
Jun 23, 2022, 2:53:37 PM6/23/22
to Farah Juma, WildFly
Hi Farah,

I have created https://issues.redhat.com/browse/ELY-2355 for adding to the scope.
I am sorry, just realized that I may have created the issue on the wrong project, should have been WFY. I hope you can move it to the right project, if not let me know and I will create it again in the WFY project.

What would be my options at this point in time?
I assume that the keycloack adapter can’t deal with the additional scope either.

I can try to debug to see if I can figure out why the token is not accepted.
But in either case, is there a option to add custom code to deal with any of these issues?

If you need additional input please let me know.
Many thanks for your feedback,
Ion

Farah Juma

unread,
Jun 23, 2022, 3:54:08 PM6/23/22
to WildFly
On Thursday, June 23, 2022 at 2:53:37 PM UTC-4 ion wrote:
Hi Farah,

I have created https://issues.redhat.com/browse/ELY-2355 for adding to the scope.
I am sorry, just realized that I may have created the issue on the wrong project, should have been WFY. I hope you can move it to the right project, if not let me know and I will create it again in the WFY project.

Thanks! I've moved it to WFLY-16532.
 

What would be my options at this point in time?
I assume that the keycloack adapter can’t deal with the additional scope either.

Right, this wouldn't work with the Keycloak adapter.
 

I can try to debug to see if I can figure out why the token is not accepted.
But in either case, is there a option to add custom code to deal with any of these issues?

If you do debug, you could take a look at the org.wildfly.security.http.oidc.TokenValidator#parseAndVerifyTokenMethod, this is where the ID token and access token are parsed and could be considered invalid:


I'm curious about the format of the access token. If it isn't a JWT in this case, that might also be what's causing the parsing issue. Taking a closer look at what's happening in the method above would hopefully reveal more details.

Ion Moraru

unread,
Jun 24, 2022, 12:06:50 AM6/24/22
to Farah Juma, WildFly
Hi Farah,

I progressed a little further thanks to the fix in ELY-2353. I have compiled the adapter, run it and managed to find the reason for the token validation failure: Issuer (iss) claim value doesn’t match expected value.
This was a surprise to me, since I have checked it many times.
The problem is that the Azure URL ends in ‘/‘, something like "https://azure-url/". All the configuration, all the logs and all the http responses have the trailing /. In the error message the trailing / is missing from the expected value, seems that some of the code is trimming the trailing /.

I managed to get around it by adding // to the end of the provider-url:
        <subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0">
            <provider name="azure">
                <provider-url>https://azure-url//</provider-url>

                <ssl-required>external</ssl-required>
            </provider>
            <secure-deployment name="simple-webapp.war">
                <provider>azure</provider>
                <client-id>my-client-id</client-id>
                <credential name="secret" secret="my-client-secret" />
            </secure-deployment>
        </subsystem>


Unfortunately that did not solve the problem. That is because Azure is not returning the access token if the scope is missing the client id. The access token is null and it is now failing with a null pointer exception:

01:24:19,813 DEBUG [org.wildfly.security.http.oidc] (default task-2) Problem parsing ID token: 
...
: org.jose4j.jwt.consumer.InvalidJwtException: JWT processing failed. Additional details: [[17] Unexpected exception encountered while processing JOSE object (java.lang.NullPointerException): null]
at org.bitbucket.jose4j//org.jose4j.jwt.consumer.JwtConsumer.process(JwtConsumer.java:422)
at org.bitbucket.jose4j//org.jose4j.jwt.consumer.JwtConsumer.processToClaims(JwtConsumer.java:171)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.TokenValidator.parseAndVerifyToken(TokenValidator.java:93)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.OidcRequestAuthenticator.resolveCode(OidcRequestAuthenticator.java:363)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.OidcRequestAuthenticator.authenticate(OidcRequestAuthenticator.java:284)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.RequestAuthenticator.doAuthenticate(RequestAuthenticator.java:91)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.RequestAuthenticator.authenticate(RequestAuthenticator.java:44)
at org.wildfly.securit...@1.19.1.CR1-SNAPSHOT//org.wildfly.security.http.oidc.OidcAuthenticationMechanism.evaluateRequest(OidcAuthenticationMechanism.java:82)
at org.wildfly.security.elytron-ba...@1.19.0.Final//org.wildfly.security.auth.server.SecurityIdentityServerMechanismFactory$1.evaluateRequest(SecurityIdentityServerMechanismFactory.java:85)
at org.wildfly.secu...@1.19.0.Final//org.wildfly.security.http.HttpAuthenticator$AuthenticationExchange.authenticate(HttpAuthenticator.java:325)
at org.wildfly.secu...@1.19.0.Final//org.wildfly.security.http.HttpAuthenticator$AuthenticationExchange.access$800(HttpAuthenticator.java:300)
at org.wildfly.secu...@1.19.0.Final//org.wildfly.security.http.HttpAuthenticator.authenticate(HttpAuthenticator.java:94)
at org.wildfly.security.ely...@1.10.1.Final//org.wildfly.elytron.web.undertow.server.SecurityContextImpl.authenticate(SecurityContextImpl.java:107)
at org.wildfly.security.elytron-web.undertow-server-ser...@1.10.1.Final//org.wildfly.elytron.web.undertow.server.servlet.ServletSecurityContextImpl.authenticate(ServletSecurityContextImpl.java:115)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55)
at io.under...@2.2.17.Final//io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)
at io.under...@2.2.17.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.under...@2.2.17.Final//io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53)
at io.under...@2.2.17.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59)
at io.under...@2.2.17.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at org.wildfly.security.elytron-web.undertow-server-ser...@1.10.1.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
at io.under...@2.2.17.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.under...@2.2.17.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at io.under...@2.2.17.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:275)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:79)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:134)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:131)
at io.undert...@2.2.17.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undert...@2.2.17.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1544)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1544)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1544)
at org.wildfly.ext...@26.1.1.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1544)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:255)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:79)
at io.undert...@2.2.17.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:100)
at io.under...@2.2.17.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:387)
at io.under...@2.2.17.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:852)
at org.jbos...@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jbos...@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
at org.jbo...@3.8.7.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException
at org.bitbucket.jose4j//org.jose4j.jwx.CompactSerializer.deserialize(CompactSerializer.java:30)
at org.bitbucket.jose4j//org.jose4j.jwx.JsonWebStructure.fromCompactSerialization(JsonWebStructure.java:79)
at org.bitbucket.jose4j//org.jose4j.jwt.consumer.JwtConsumer.process(JwtConsumer.java:320)
... 49 more
 

Do you have any suggestions? Is there any way I can add custom code to inject the additional scope required?
Ion

<Screen Shot 2022-06-22 at 12.55.35.png>
<Screen Shot 2022-06-22 at 12.55.35.png>


--
You received this message because you are subscribed to a topic in the Google Groups "WildFly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/wildfly/Jez_5ieZHkE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to wildfly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wildfly/6c468f3c-609e-4e8f-bbe2-d9a1590781den%40googlegroups.com.
<Screen Shot 2022-06-22 at 12.55.35.png>

Farah Juma

unread,
Jun 24, 2022, 11:52:47 AM6/24/22
to WildFly
On Friday, June 24, 2022 at 12:06:50 AM UTC-4 ion wrote:
Hi Farah,

I progressed a little further thanks to the fix in ELY-2353. I have compiled the adapter, run it and managed to find the reason for the token validation failure: Issuer (iss) claim value doesn’t match expected value.
This was a surprise to me, since I have checked it many times.
The problem is that the Azure URL ends in ‘/‘, something like "https://azure-url/". All the configuration, all the logs and all the http responses have the trailing /. In the error message the trailing / is missing from the expected value, seems that some of the code is trimming the trailing /.

I've created ELY-2356 to see if we can remove the code that trims the trailing slash.
The scope parameter is set here so since you're already using a SNAPSHOT version of Elytron, you could potentially try tweaking that:

Farah Juma

unread,
Sep 1, 2022, 11:04:56 AM9/1/22
to WildFly
Just FYI, ELY-2356 has been fixed in WildFly 26.1.2.Final. Thanks for reporting this!

Ion Moraru

unread,
Sep 1, 2022, 11:14:01 PM9/1/22
to Farah Juma, WildFly
Great! 
We had to use keycloack in between our application and Azure but this should simplify the solution in the future.
I will try it out but it would be later, probably next week. 
Thanks for letting me know,
Ion

Reply all
Reply to author
Forward
0 new messages