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()));
The dropwizard-auth client provides authentication using either HTTP Basic Authentication or OAuth2 bearer tokens. An authenticator is a strategy class which, given a set of client-provided credentials, possibly returns a principal (i.e., the person or entity on behalf of whom your service will do something).
To secure a resource in Dropwizard one uses a three-step approach. First, one should implement an Authenticator interface where a method verifying user credentials is defined. It is up to the API developer how to store and verify credentials; it is possible to store them in a database or a LDAP server, both options are supported by Dropwizard.
Otherwise some requests made to dropwizard on heavy load may fail due to congestion on the jersey client’s thread pool. The size of the work queue of the pool used for asynchronous requests.
Dropwizard uses YAML (YAML Ain't Markup Language) human-readable data format to store configuration. The configuration is deserialized into an instance of a class that extends io.dropwizard.Configuration in the case of our project it is DWGettingStartedConfiguration.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With