OIDC HowTo

257 views
Skip to first unread message

Erik Mattheis

unread,
Jul 13, 2018, 10:38:09 AM7/13/18
to Thorntail
I have a REST micro-service implemented with Thorntail and access to a corporate IDP that supports OIDC. I'd like to configure the service to unpack JWT bearer tokens and set the appropriate security context in Elytron to make standard Java EE security mechanisms viable (e.g. @RolesAllowed).

I'm finding a lot of tantalizing details while searching around, but no concrete examples of how to wire everything together. Like others, I've found KeyCloak to be confusing if you're not using their IDP. This seems promising: https://github.com/aaronanderson/swarm-oidc but I'd rather stick to built-in mechanisms if possible. I can't make heads or tails of the MicroProfile JWT project - that seems more like a spec for standardizing and exposing the JWT tokens as opposed to an actual security mechanism. It seems like the Elytron token-realm is appropriate here, so I'm going to dig in that direction and see how to get the Undertow layer to pass along the JWT bearer token.

If anyone has an example of OIDC integration for a REST API in Thorntail/Wildfly-Swarm or any other guidance, I'd appreciate it!

-- 
Erik

Sergey Beryozkin

unread,
Jul 13, 2018, 11:06:51 AM7/13/18
to Erik Mattheis, Thorntail
MP-JWT should be able to help if it is JWS only with the RSA signature and each of these microservices has the IDP public verification key available locally. It was also enhanced with the help from the user to check remote JWK URIs, so if the 3rd party IDP can offer the verification key as a publicly available JWK(set) then it will work too. MP-JWT then can indeed make the claims accessible via its API but unless the custom service needs them it is needed to use this API. I believe it should also work with RolesAllowed once MP-JWT populates the security context...

Alternatively I'd also consider creating a simple JAX-RS PreMatching ContainerRequestFilter which gets the Bearer value, uses the IDP specific mechanism to validate it, next, if IDP can return an introspection response with all the roles/etc claims then all is good, otherwise if it is only JWS -> use plain JSON parser to get the list of roles from the base64url-decoded middle JWS part, or use Jose4j/etc if preferred,  and register a custom JAX-RS SecurityContext to ensure RolesAllowed is enforced...

I'd not be surprised if the elytron token realm would have to be configured similarly to MP-JWT somehow but it would likely more complex overall. That said - if you can make it work this way then please let us know how - I'd be interested, few Thorntail fractions like management-console, health, open-api, can benefit...

Thanks, Sergey


--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+unsubscribe@googlegroups.com.
To post to this group, send email to thor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/thorntail/9a2a0989-7937-4969-ab35-20310a0c3821%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sergey Beryozkin

unread,
Jul 13, 2018, 11:07:56 AM7/13/18
to Erik Mattheis, Thorntail
Minor typo...,

On Fri, Jul 13, 2018 at 4:06 PM, Sergey Beryozkin <sbery...@gmail.com> wrote:
MP-JWT should be able to help if it is JWS only with the RSA signature and each of these microservices has the IDP public verification key available locally. It was also enhanced with the help from the user to check remote JWK URIs, so if the 3rd party IDP can offer the verification key as a publicly available JWK(set) then it will work too. MP-JWT then can indeed make the claims accessible via its API but unless the custom service needs them it is
 
*not *

Erik Mattheis

unread,
Jul 13, 2018, 11:31:56 AM7/13/18
to Thorntail
Thanks, Sergey! That's pretty much what I thought based on what I've seen, but I don't quite understand how to configure things, so looking for an example. Also, the JWT provided by our IDP has some custom claims from our internal authorization layer that I need to transform into a set of roles, so I need to plugin somewhere to do that translation.

Certainly doing something custom in JAX-RS is not too difficult, but populating the roles back to the container is problematic and it seems like there is already JWT support in Elytron, I just don't understand how to configure it.

-- 
Erik

Sergey Beryozkin

unread,
Jul 13, 2018, 12:09:37 PM7/13/18
to Erik Mattheis, Thorntail
You should see some examples there how to to get MP-JWT validate the tokens locally.

Re the JAX-RS filter option, once the claims role info is available, one can then easily make them available similarly to:

https://github.com/thorntail/thorntail-examples/blob/master/security/keycloak/src/main/java/org/wildfly/swarm/examples/keycloak/KeycloakSecurityContextFilter.java

You'd just register a new SecurityContext and override isUserInRole by matching against the custom claims.

If you use RestEasy then you'd complement it all with
https://github.com/resteasy/Resteasy/blob/master/resteasy-jaxrs/src/main/java/org/jboss/resteasy/plugins/interceptors/RoleBasedSecurityFeature.java

without depending on the container itself to enforce the RBAC rules.

If you have the existing (web.xml) security constraints then perhaps only the MP-JWT route can work, or the elytron/TokenRealm as the lower level solution...

Cheers, Sergey

--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+unsubscribe@googlegroups.com.
To post to this group, send email to thor...@googlegroups.com.

Erik Mattheis

unread,
Jul 13, 2018, 12:56:39 PM7/13/18
to Thorntail
Cool. I'll dig a little farther.

For pure JAX-RS stuff this is all pretty straightforward, but my real interest is to wire JWT all the way back into the container. We have some legacy apps that use traditional JAAS-style EE RBAC, so I would like to have the container aware of the JWT claims. We have a custom JBoss EAP integration that does this with an old Catalina-style authenticator and some SAML flows to our IDP.

I'd really like to understand how to configure the token realm in Elytron for JWT and intercept the role-mapping process. There's clearly been work done around this:


-- 
Erik

Sergey Beryozkin

unread,
Jul 13, 2018, 6:19:33 PM7/13/18
to Erik Mattheis, Thorntail
Sure, I can see why it has to be done in your case by configuring the elytron subsystem somehow,
I'm not sure how flexible it is at the elytron level, i.e, I'm not sure it is not tightly linked to Keycloak, hopefully not.
It might make sense to ask at the wildfly list for more info, let us know please what you find and then we'll try to map it to the thorntail config somehow.

shows how to set up the login module (not sure about the custom ones...)

I guess the token realm can be set using a similar approach somehow (directly in YAML)

Sergey

--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+unsubscribe@googlegroups.com.
To post to this group, send email to thor...@googlegroups.com.

Erik Mattheis

unread,
Jul 31, 2018, 12:23:28 PM7/31/18
to Thorntail
So, I started a thread on the Wildfly forum: https://developer.jboss.org/thread/278404


Which I'm now trying to map into the Thorntail config YAML. Not sure everything is supported, however. The higher level parts are pretty well covered here: http://docs.wildfly-swarm.io/2.0.0.Final/#_elytron

But I'm getting confused in particular when I start to go deeper into the HTTP authentication mechanism configs. I'll let everyone know how it goes, but any advice is appreciated.

Erik Mattheis

unread,
Aug 2, 2018, 5:45:28 PM8/2/18
to Thorntail
Made a lot of progress and was able to port the JAX-RS JWT example from Wildfly to Thorntail: https://github.com/emattheis/jaxrs-jwt

The one major problem is that when the custom elytron HTTP authentication factory is enabled, undertow seems to require auth for EVERY request, despite the explicit configuration in the web descriptor. In the example, the /rest/token path needs to be unprotected to generate the JWT used to test the protected endpoints. I was able to disable auth, hit the token endpoint to get the JWT, re-enable auth and prove that the JWT token-realm works correctly, but I can't figure out how to keep the public endpoints available - undertow always challenges with 401 if the authorization header is missing.

Erik Mattheis

unread,
Aug 2, 2018, 6:27:34 PM8/2/18
to Thorntail

Sergey Beryozkin

unread,
Aug 3, 2018, 1:55:42 PM8/3/18
to Erik Mattheis, Thorntail
May be you can introduce Undertow handlers which exclude somehow some request paths from the security checks  ? For ex, have a look at the mp health code,
Sergey

On Fri, 3 Aug 2018 01:27 Erik Mattheis, <erikma...@gmail.com> wrote:
--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+...@googlegroups.com.

To post to this group, send email to thor...@googlegroups.com.

Erik Mattheis

unread,
Aug 3, 2018, 3:59:53 PM8/3/18
to Thorntail
At that point, it's probably just as easy to implement the fix for ELY-1510 in a custom HttpServerAuthenticationMechanism :P

Sergey Beryozkin

unread,
Aug 4, 2018, 2:02:11 PM8/4/18
to Erik Mattheis, Thorntail
Sure... Though it is also worth reviewing if having a semi-secured endpoint is safe...
Sergey

On Fri, 3 Aug 2018 22:59 Erik Mattheis, <erikma...@gmail.com> wrote:
At that point, it's probably just as easy to implement the fix for ELY-1510 in a custom HttpServerAuthenticationMechanism :P

--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+...@googlegroups.com.
To post to this group, send email to thor...@googlegroups.com.

Sergey Beryozkin

unread,
Aug 7, 2018, 7:28:42 AM8/7/18
to Erik Mattheis, Thorntail
Specifically, I forgot to mention it, not all customers like exposing the HTTP Server header (which might identify for ex a given version of Undertow/etc) and this header will be leaked via the unsecured GET response unless the server is configured not to send it back, etc...

Sergey

On Sat, Aug 4, 2018 at 7:01 PM, Sergey Beryozkin <sbery...@gmail.com> wrote:
Sure... Though it is also worth reviewing if having a semi-secured endpoint is safe...
Sergey
On Fri, 3 Aug 2018 22:59 Erik Mattheis, <erikma...@gmail.com> wrote:
At that point, it's probably just as easy to implement the fix for ELY-1510 in a custom HttpServerAuthenticationMechanism :P

--
You received this message because you are subscribed to the Google Groups "Thorntail" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thorntail+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages