使用 Dropwizard 从 Authenticator 访问 HttpServletRequest
Access HttpServletRequest from an Authenticator using Dropwizard
使用 DropWizard(Jersey Server),是否可以从身份验证器访问 HttpServletRequest
?
我会给它一个属性。
我试过:
@Context
private HttpServletRequest servletRequest;
但是没有注入
我使用以下方式注册了我的身份验证器:
env.jersey().register(
new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(new FooAuthentificator())
.setRealm("Realm").buildAuthFilter()));
这是可能的,但问题是,Authenticator
永远不会经历 DI 生命周期,所以它永远没有机会被注入。我们 可以 做的是我们自己明确地注入它。为此,我们需要获取 ServiceLocator
(这是主要的 IoC 容器,有点像 ApplicationContext
和 Spring)。一旦我们有了 ServiceLocator
,我们就可以调用 locator.inject(anyObject)
来显式解决任何注入依赖关系。
配置应用程序时,最容易获得 ServiceLocator
的地方是 Feature
。这里我们也可以注册 Jersey 组件。在 FeatureContext
上调用 register
(如下所示)就像在 Dropwizard 上调用 env.jersey().register(...)
一样,效果相同。所以我们可以做
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
注册这个功能
env.jersey().register(new AuthenticatorFeature());
已测试,工作正常。
请注意,如果您想知道如何在没有当前请求时注入 HttpServletRequest
,那是因为注入了代理。就像将请求注入 Jersey 过滤器一样,也会发生同样的事情;注入了代理,因为只有一个单例过滤器,但是请求随着请求的不同而变化,所以需要注入代理。
另请参阅:
使用 DropWizard(Jersey Server),是否可以从身份验证器访问 HttpServletRequest
?
我会给它一个属性。
我试过:
@Context
private HttpServletRequest servletRequest;
但是没有注入
我使用以下方式注册了我的身份验证器:
env.jersey().register(
new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>().setAuthenticator(new FooAuthentificator())
.setRealm("Realm").buildAuthFilter()));
这是可能的,但问题是,Authenticator
永远不会经历 DI 生命周期,所以它永远没有机会被注入。我们 可以 做的是我们自己明确地注入它。为此,我们需要获取 ServiceLocator
(这是主要的 IoC 容器,有点像 ApplicationContext
和 Spring)。一旦我们有了 ServiceLocator
,我们就可以调用 locator.inject(anyObject)
来显式解决任何注入依赖关系。
配置应用程序时,最容易获得 ServiceLocator
的地方是 Feature
。这里我们也可以注册 Jersey 组件。在 FeatureContext
上调用 register
(如下所示)就像在 Dropwizard 上调用 env.jersey().register(...)
一样,效果相同。所以我们可以做
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
env.jersey().register(new AuthenticatorFeature());
已测试,工作正常。
请注意,如果您想知道如何在没有当前请求时注入 HttpServletRequest
,那是因为注入了代理。就像将请求注入 Jersey 过滤器一样,也会发生同样的事情;注入了代理,因为只有一个单例过滤器,但是请求随着请求的不同而变化,所以需要注入代理。
另请参阅: