使用 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 过滤器一样,也会发生同样的事情;注入了代理,因为只有一个单例过滤器,但是请求随着请求的不同而变化,所以需要注入代理。

另请参阅: