All -
I got JWT token security working now with Karaf-4.2.6, but I had to switch from
CXF to JAX-RS whiteboard. The JAX-RS whiteboard spec is officially part of OSGi
7 but this solution works fine with K-4.2.6 and OSGi-6. It took me a while to
figure this out, so I want to share what I learned here.
There are 3 jigsaw pieces needed to make this work.
1. The filter needs to be registered as ContainerRequestFilter with the
osgi.jaxrs.extension property set to true, otherwise it is not picked up. The
filter also needs the annotation for which it is applicable. If omitted the
filter method will be called for every endpoint call. The name of the
annotation is arbitrary but it seems that JWTAdminTokenNeeded, JWTTokenNeeded
and JWTUserTokenNeeded are most common.
@JWTAdminTokenNeeded
@Component( service = ContainerRequestFilter.class, property = {
"osgi.jaxrs.extension=true” } )
public class JWTAdminTokenNeededFilter implements
ContainerRequestFilter {
2. The endpoint component needs to be registered with the osgi.jaxrs.resource
property set to true, like so.
@Component(service = TheService.class, property = {
"osgi.jaxrs.resource=true" })
public class TheServiceImpl implements TheService {
3. The endpoint method needs the annotation for the required filter.
@Override
@JWTAdminTokenNeeded
@PUT
@Path("/")
public Response updateThingy(ThingyDTO thingy) {
Most, if not all of the above is described in the OSGi 7 JAX-RS whiteboard
Specification here
https://osgi.org/specification/osgi.cmpn/7.0.0/service.jaxrs.html
<https://osgi.org/specification/osgi.cmpn/7.0.0/service.jaxrs.html> but
sometimes you won’t see it until you know what you are looking for.
Hope this helps.
BTW… I am still a tad confused why this won’t work with CXF so if someone has
some ideas I’d be more than happy to give that another try.
Erwin
> On Aug 26, 2019, at 19:19, Erwin Hogeweg <[email protected]> wrote:
>
> Hi,
>
> Does anyone have an example on how to register a ContainerRequestFilter with
> CXF in Karaf-4.2?
>
> As far as I can see everything is in place, but the filter() and validate()
> methods are never called before the service methods are invoked. I am sure I
> am missing something but so far I haven’t discovered it yet. I was wondering
> if somebody had an idea before I start digging in the CXF code.
>
>
> Thanks for your help,
>
> Erwin
>
>
> This is from my JWTTokenNeededFilter file.
> @JWTTokenNeeded
> @Component( immediate = true,
> name = "my.jwt.filters.JWTTokenNeededFilter",
> configurationPolicy = ConfigurationPolicy.OPTIONAL
> )
> @Provider
> @Priority(Priorities.AUTHENTICATION)
> public class JWTTokenNeededFilter implements ContainerRequestFilter {…}
>
>
> In my RS Service Component I define the Filters as follows (Not entirely sure
> if this is correct).
>
> @Component(
> immediate = true,
> name = "com.seecago.rome.usermgt.service",
> configurationPolicy = ConfigurationPolicy.OPTIONAL,
> property = {
> "type=internal",
> “service.exported.interfaces=my.service.MyManagementService",
> "service.exported.configs=org.apache.cxf.rs
> <http://org.apache.cxf.rs/>",
> "org.apache.cxf.rs.address=/UserProfile",
> "service.exported.intents=HTTP",
>
> “org.apache.cxf.rs.provider=my.jwt.filters.JWTAdminTokenNeededFilter",
>
> “org.apache.cxf.rs.provider=my.jwt.filters.JWTUserTokenNeededFilter",
>
> “org.apache.cxf.rs.provider=my.jwt.filters.JWTTokenNeededFilter"})
>
>
> This is how I defined a secure service call:
> @Override
> @JWTTokenNeeded
> public SomeResult getItemById(Long itemId) {…}
>
>
> And this is what scr:info n returns for the Filter Component:
>
> *** Bundle: my.server.security (205)
> Component Description:
> Name: my.jwt.filters.JWTTokenNeededFilter
> Implementation Class: my.jwt.filters.JWTTokenNeededFilter
> Default State: enabled
> Activation: immediate
> Configuration Policy: optional
> Activate Method: activate
> Deactivate Method: deactivate
> Modified Method: -
> Configuration Pid: [my.jwt.filters.JWTTokenNeededFilter]
> Services:
> javax.ws.rs.container.ContainerRequestFilter
> Service Scope: singleton
> Component Description Properties:
> Component Configuration:
> ComponentId: 5
> State: active
> Component Configuration Properties:
> component.id <http://component.id/> = 5
> component.name = my.jwt.filters.JWTTokenNeededFilter
>
>
>