5

Using DropWizard(Jersey Server), Is it possible to access HttpServletRequest from an Authenticator?

I would give it an attribute.

I tried with:

@Context
private HttpServletRequest servletRequest;

But it's not injected.

I registered my Authenticator using:

env.jersey().register(
                new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(new FooAuthentificator())
                        .setRealm("Realm").buildAuthFilter()));
Pier-Alexandre Bouchard
  • 5,135
  • 5
  • 37
  • 72

1 Answers1

6

It's possible, but the problem is, the Authenticator never goes through the DI lifecycle, so it never gets a chance to get injected. What we can do though is explicitly inject it ourselves. To do that, we need to get a hold of the ServiceLocator (which is the main IoC container, kind of like ApplicationContext with Spring). Once we have the ServiceLocator, we can call locator.inject(anyObject) to explicitly resolve any injection dependencies.

The easiest place to get the ServiceLocator, when configuring the app, is in a Feature. Here we can also register Jersey components. Calling register on the FeatureContext (seen below) is just like calling env.jersey().register(...) with Dropwizard, it has the same effect. So we can do

public class AuthenticatorFeature implements Feature {

    @Override
    public boolean configure(FeatureContext ctx) {
        ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(ctx);
        TestAuthenticator authenticator = new TestAuthenticator();
        locator.inject(authenticator);
        ctx.register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
                        .setAuthenticator(authenticator)
                        .setRealm("SEC REALM")
                        .buildAuthFilter()));
        ctx.register(new AuthValueFactoryProvider.Binder<>(User.class));
        return true;
    }
}

You can see that explicitly inject the authenticator, with the call to locator.inject(authenticator). Then we register this feature through Dropwizard

env.jersey().register(new AuthenticatorFeature());

Tested, and works fine.


Note, if you are wondering how it's possible to inject the HttpServletRequest, when there is no current request, it's because a proxy is injected. Same thing as if you were to inject the request into a Jersey filter, the same thing happens; a proxy is injected, as there is only a singleton filter, but the request changes from request to request, so a proxy needs to be injected.

See Also:

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720