Jersey ContainerRequestFilter not triggered
Asked Answered
M

10

44

I'm trying to use a ContainerRequestFilter to enforce some authentication on a Tomcat based Jersey application. I followed this document. Problem : the filter is never triggered

The filter class :

@Provider
public class AuthFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext)
        throws IOException {

        // MY AUTHENTICATION CODE GOES HERE

    }

The web.xml file :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="debate-rest"
    version="3.0">
  <display-name>rest</display-name>
   <servlet>  
    <servlet-name>Jersey REST Service</servlet-name>  
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>  
    <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
        <param-value>com.hck.debate.rest.security.AuthFilter</param-value>
    </init-param>
    <init-param>  
      <param-name>jersey.config.server.provider.packages</param-name>  
      <param-value>com.hck.debate.rest.controller</param-value>  
    </init-param>  
    <init-param>  
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>  
        <param-value>true</param-value>  
    </init-param>      
    <load-on-startup>1</load-on-startup>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>Jersey REST Service</servlet-name>  
    <url-pattern>/*</url-pattern>  
  </servlet-mapping>
Manson answered 25/6, 2013 at 14:34 Comment(0)
M
38

Okay, I didn't get that the jersey.config.server.provider.packages init param needs to reference not only service classes (API endpoints) but ALL the classes including filters.

Now it works :

<init-param>  
  <param-name>jersey.config.server.provider.packages</param-name>  
  <param-value>com.hck.debate.rest.controller;com.hck.debate.rest.security</param-value>
</init-param>
<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>com.hck.debate.rest.security.AuthFilter</param-value>
</init-param>
Manson answered 27/6, 2013 at 14:8 Comment(5)
Your above code is working as it is with TomCat, maybe it's different with Glas FishEgger
The default behavior is to scan recursively, so you can also just use the single base package com.hck.debate.restColquitt
Also note that com.sun.jersey.spi.container.ContainerRequestFilters and com.sun.jersey.api.json.POJOMappingFeature are useless. These are Jersey 1.x properties. They have no impact on Jersey 2.xColquitt
Also note that by default, the package scanning is recursive. So instead of listing multiple packages, just declare a base package, like com.hck.debate.rest, and it will recursively scan all sub-packages.Colquitt
And just an FYI, the scanning is to pick up classes annotated with @Provider and @Path, so you need to make sure to also have the @Provider annotation.Colquitt
W
23

I also had to add the @Provider JAX-RS annotation to my filters.
This makes the filter discoverable during JAX-RS scanning phase.

@Provider
public class MyAppFilter implements ContainerRequestFilter {
    // filter logic
}
Withrow answered 31/3, 2014 at 7:33 Comment(3)
Same here without the annotation nothing happenedNosegay
is it "@Provider" really necessary ?Brahmaputra
Yes, I just had to add the @Provider annotation. Package scanning was already set up correctlyAttest
K
5

Some hints:

  1. Make sure you're using JAX-RS version 2.17.
  2. Make sure you're using the right imports in your filter:

    • import javax.ws.rs.container.ContainerRequestContext;
    • import javax.ws.rs.container.ContainerRequestFilter;
  3. Add the @Provider annotation

Knobkerrie answered 20/4, 2015 at 20:42 Comment(2)
is it "@Provider" really necessary ?Brahmaputra
Yes, it annotates the component as a provider of something. It is used to extend the base JAX-RS functionality.Knobkerrie
M
4

We were missing the below call in our ResourceConfig implementation class:

register(CorrelationIdFilter.class);
Mariano answered 13/8, 2018 at 14:58 Comment(0)
D
2

The minimum requirements to work filters with jersey:

  • add @Provider annotation to filter class
  • the namespace of filter class has to be included in 'jersey.config.server.provider.packages' init-param

Any other settings aren't required (e.g. 'com.sun.jersey.spi.container.ContainerRequestFilters' init-param or ResourceConfig)

Demmy answered 18/10, 2014 at 6:34 Comment(2)
is it "@Provider" really necessary ?Brahmaputra
yes, it is. Jersey will load only the marked classes from the specified namespaceDemmy
C
2

I had the same problem for JAX-RS 2 , jersey and the below annotation fixed it

 @PreMatching
Cretonne answered 1/12, 2014 at 23:33 Comment(2)
But that changes semantics! Adding this method solely influences when the filter is invoked. I seriously doubt that this changes the configuration of anything!Sonnie
Thanks, this is just what I needed.Allare
A
0

Instead of using the @Provider annotation (which did not work in my case), you can register your ContainerRequestFilter manually with your JerseyServletFactory:

JerseyServletFactory jerseyServletFactory = new JerseyServletFactory(config);
HttpServlet myServiceServlet = jerseyServletFactory.create(myResource);

// Register your ContainerRequestFilter like this
jerseyServletFactory.addRequestFilter(new MyFilter());

httpServer.register(myServiceServlet, "/api");
httpServer.start();
Anamorphism answered 30/9, 2015 at 16:49 Comment(3)
and where is this piece of code supposed to be placed?Morbid
@Morbid During initialization. I've place my code between the creation and the start of the JettyHttpServer, with the other stuff that needs to get initialized on start (Datasources, Resources, DAOs, etc.)Anamorphism
I did the same, now i want to call destroy (for some custom cleanup task) of servlet. I am not able to get the reference back of this filter to call destroy in shutdown event.Pulverize
R
0

If you were stuck like me, note that TomEE 1.7.X uses JAX-RS 1.1, which does not include ContainerRequestFilter.

Rubirubia answered 3/8, 2016 at 11:51 Comment(0)
B
0

For anybody having this problem in MULE ESB. Remember to register path with:

<jersey:resources doc:name="REST">
   <component doc:name="rest component">
     <spring-object bean="endpoit"/>
   </component>
   <jersey:package packageName="path @Provider-s"/>
</jersey:resources >
Bookplate answered 6/12, 2016 at 10:23 Comment(0)
D
-1

Instead of javax.ws.rs, i used com.sun.jersey and it worked

import com.sun.jersey.spi.container.ContainerRequestFilter import com.sun.jersey.spi.container.ContainerRequest

Dropwizard users need to do this

environment.jersey().getResourceConfig()
           .getContainerRequestFilters()
           .add(filter);
Defy answered 7/5, 2016 at 5:29 Comment(1)
And thereby creating code that relies on packages you shouldnt rely on.Sonnie

© 2022 - 2024 — McMap. All rights reserved.