在dropwizard auth中返回锁定的用户

时间:2017-01-11 07:26:17

标签: dropwizard

dropwizard auth模块中,我想返回我的rest-api的来电者用户已锁定

(凭据可能正确,但用户被锁定/禁用)

我看过这里:http://www.dropwizard.io/1.0.5/docs/manual/auth.html但找不到与之相关的任何内容。

authenticate的{​​{1}}方法返回我的Authenticator对象的可选项,文档说:

  

如果验证者,您应该只抛出AuthenticationException   无法检查凭据(例如,您的数据库已关闭)。

1 个答案:

答案 0 :(得分:0)

所以,对于某些背景,你应该只抛出AuthenticationException的原因是因为DW的好人提供的过滤器只处理这个异常。对于所有其他例外,这是未定义的。

有关详细信息,请参阅:AuthFilter#authenticate

然而,有一种非常简单的方法可以做你想做的事。

查看DW代码,您可以得到:

@Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        final BasicCredentials credentials =
                getCredentials(requestContext.getHeaders().getFirst(HttpHeaders.AUTHORIZATION));
        if (!authenticate(requestContext, credentials, SecurityContext.BASIC_AUTH)) {
            throw new WebApplicationException(unauthorizedHandler.buildResponse(prefix, realm));
        }
    }

此代码的作用是调用您的Authenticator来解析用户,然后检查它是否经过身份验证。如果不是,那么它会调用UnauthorizedHandler来检查它需要什么样的响应。遗憾的是,处理程序没有传入Principal,所以它只能返回一个静态异常。

现在,如果你想手工制作,这将是你的入口点。不是简单地使用他们提供的BasicCredentialAuthFilter,而是编写自己的东西,为你做正确的事。

但是,从代码片段中,我们可以看到所有这些过滤器都会抛出WebApplicationException。所以我们可以简化这个。

我们的Authenticator实现可以事先进行用户锁定检查,并为我们填充异常以绕过此行为。这样,下游逻辑就会被保留(对WebapplicationException做出反应,我认为它实际上是一个球衣feautere(参见:异常mapppers))。

所以,请考虑这个例子:

public class AuthenticatorTest extends io.dropwizard.Application<Configuration> {
    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        environment.jersey().register(new MyHelloResource());
        UserAuth a = new UserAuth();
        environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<Principal>()
                .setAuthenticator(a).setRealm("SUPER SECRET STUFF").buildAuthFilter()));
    }

    public static void main(String[] args) throws Exception {
        new AuthenticatorTest().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test.yaml");
    }

    @Path("test")
    @Produces(MediaType.APPLICATION_JSON)
    public static class MyHelloResource {

        @GET
        @Path("asd")
        @PermitAll
        public String test(String x) {
            return "Hello";
        }
    }

    public static class UserAuth implements Authenticator<BasicCredentials, Principal> {
        @Override
        public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException {
            throw new WebApplicationException(Response.status(403).entity("User is blocked").build());
        }
    }

}

此代码只是创建一个新的异常,而不是验证用户名。这导致了这种卷曲:

artur@pandaadb:/$ curl "artur:artur@localhost:9085/api/test/asd"
User is blockedartur@pandaadb:/$ curl "artur:artur@localhost:9085/api/test/asd" -v
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9085 (#0)
* Server auth using Basic with user 'artur'
> GET /api/test/asd HTTP/1.1
> Host: localhost:9085
> Authorization: Basic YXJ0dXI6YXJ0dXI=
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 403 Forbidden
< Date: Thu, 12 Jan 2017 14:19:27 GMT
< Content-Type: application/json
< Content-Length: 15
< 
* Connection #0 to host localhost left intact
User is blocked

现在,这可能不是您可以做的最干净的解决方案。如果您需要快速,那么您可以将异常抛出Authenticator。但是,正确的方法是:

  1. io.dropwizard.auth.AuthFilter
  2. 为基础实施新的AuthFilter
  3. 覆盖AuthFilter上的authenticate方法以检查您的用户并在那里抛出正确的异常。