First8 staat voor vakmanschap. Al onze collega’s zijn een groot aanhanger van Open Source en in het bijzonder het Java-platform. Wij zijn gespecialiseerd in het pragmatisch ontwikkelen van bedrijfskritische Java toepassingen waarbij integratie van systemen, hoge eisen aan beveiliging en veel transacties een belangrijke rol spelen. Op deze pagina vind je onze blogs.

Securing JAX-RS: Keycloak, CDI and EJB confusion

Working with the latest technology can be quite painful. Not necessarily because the software is buggy or immature, in my experience it is mostly because googling for a problem gives solutions for older versions. In this bug hunt, I was working with a Wildfly 9.0.1 hooked up to a Keycloak 1.3.1 server. I was trying to secure our REST API. I was mostly interested in doing programmatic security (the business rules can be quite complex) but it would be nice to simply slap on some @RolesAllowed annotations for the trivial cases. Of course, this didn’t work even though RESTEasy supports it.

Let’s have a look at our very basic API controller:

In this setup, the @RolesAllowed does not do anything. The Principal is
If you have a JAX-RS bean it isn’t strictly a CDI or EJB bean, so not everything works out of the box. Most things work though so it can be confusing at times. This was one of those times. If you put a @RequestScoped on it, you promote it to a CDI bean and some quirkiness will disappear. In this case, we actually have to promote it to a full blown EJB.

If you put a @Stateless annotation on your JAX-RS bean, you make it a stateless session EJB. The @RolesAllowed will work. And all the CDI features will still work since all EJB’s are also CDI beans. Unfortunately, security worked a bit too aggressive, even if I had the role, I was refused.

Turns out, for JAX-RS support for @RolesAllowed to work, you need to explicitly list all the roles available. Using @DeclareRoles didn’t work, I had to explicitly list all the roles you use in web.xml:

Also note that if you annotate one function with @RolesAllowed, all other functions will be protected as well. Be careful with that if you are experimenting since it can be misleading.

Googling for these kind of problems will lead you across many different solutions, some XML based for very old versions of JEE, others only offer part of the solution. As always, it helps if you understand a bit of what is happening inside the containers. So, if you run into a similar problem, try making sure it is an EJB (add @Stateless or something) and list all the roles in your web.xml. I am not sure if this is caused by the Keycloak adapter or by RESTEasy, that’s for another blog post if I find out.


Read more: