Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injection to ContainerRequestFilter in a java REST API

I guess I am dealing with a bug in Glassfish 4; but I am not sure. Basically I am trying to inject a service into a ContainerRequestFilter; but I am getting an exception while trying. I can do injection in resources where I make rest calls, but I can't use injection for filters. There is a filed bug in glassfish jira: https://java.net/jira/browse/GLASSFISH-20597. I tried the workaround mentioned in there but it didn't solve my problem.

Here is the exception I get:

org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=Authenticator,parent=SecurityInterceptor,qualifiers

Here is the code that I am working with, do you have any idea what I am missing here?

@Provider
@PreMatching
public class SecurityInterceptor implements ContainerRequestFilter {

@Inject
private Authenticator authenticator; // can't inject this service here, but I can inject this to RequestScoped Resources
private static final Logger LOG = Logger.getLogger(SecurityInterceptor.class.getName());

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    if (!requestContext.getMethod().equals("OPTIONS")) {
        String path = OyumBuFunctions.normalizeString(requestContext.getUriInfo().getPath());
            String authToken = requestContext.getHeaderString(OyumbuRestHeaders.AUTH_TOKEN_HEADER);
            if (!authenticator.isAuthTokenValid(authToken)) {
                requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
            }
            else{
                LOG.log(Level.INFO, "authenticated");
            }
    }        
  }
}
like image 787
cubbuk Avatar asked Oct 01 '22 11:10

cubbuk


2 Answers

I ran into a similar issue and came across this posting while searching for a solution. Fortunately I found a solution and thought to post it here. Note that this only works in JAX-RS 2.0 as it makes use of the DynamicFeature class

@Provider
public class AuthenticatorFeature implements DynamicFeature {

    @Inject
    private Autheticator authenticator;

    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
        context.register(new SecurityInterceptor(authenticator);
    }
} 

Binding the authenticator to the ContainerRequestFilter.

public class SecurityInterceptor implements ContainerRequestFilter {
    Authenticator authenticator;  
    public SecurityInterceptor(Authenticator authenticator){
       this.authenticator = authenticator;
    }

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        authenticator.doSomething(...);
    }
}

Some hopefully helpful readings

creating resource filters with jersey and jaxrs 2.0

Securing REST Resources with JAX-RS 2.0

like image 142
meja Avatar answered Oct 18 '22 10:10

meja


As mentioned in this answer https://stackoverflow.com/a/23996225/1045081, giving @Path annotation to the service to be injected saves the situation. Still didn't understand how to solve it properly, but just writing it here so that it could be useful for someone who encounters a similar problem.

like image 40
cubbuk Avatar answered Oct 18 '22 10:10

cubbuk