问题描述
使用 DropWizard(Jersey Server),是否可以从 Authenticator 访问 HttpServletRequest
?
Using DropWizard(Jersey Server), Is it possible to access HttpServletRequest
from an Authenticator?
我会给它一个属性.
我试过了:
@Context
private HttpServletRequest servletRequest;
但它没有注入.
我使用以下方式注册了我的身份验证器:
I registered my Authenticator using:
env.jersey().register(
new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(new FooAuthentificator())
.setRealm("Realm").buildAuthFilter()));
推荐答案
有可能,但问题是,Authenticator
永远不会经过 DI 生命周期,所以它永远没有机会被注入.我们可以做的是我们自己显式地注入它.为此,我们需要获取 ServiceLocator
(它是主要的 IoC 容器,有点像 Spring 中的 ApplicationContext
).一旦我们有了 ServiceLocator
,我们就可以调用 locator.inject(anyObject)
来显式地解析任何注入依赖.
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.
在配置应用程序时,获取 ServiceLocator
的最简单位置是在 Feature
中.这里我们也可以注册 Jersey 组件.在 FeatureContext
上调用 register
(见下文)就像使用 Dropwizard 调用 env.jersey().register(...)
一样,它有同样的效果.所以我们可以做
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;
}
}
您可以看到通过调用 locator.inject(authenticator)
显式注入身份验证器.然后我们通过 Dropwizard 注册这个特性
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());
经过测试,工作正常.
注意,如果您想知道如何注入 HttpServletRequest
,当没有当前请求时,这是因为注入了代理.就像您将请求注入 Jersey 过滤器一样,同样的事情也会发生;注入了代理,因为只有一个单例过滤器,但是请求随着请求的变化而变化,所以需要注入代理.
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.
另请参阅:
这篇关于使用 Dropwizard 从 Authenticator 访问 HttpServletRequest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!