Authentication 启用身份验证后,我的所有资源都需要身份验证

Authentication 启用身份验证后,我的所有资源都需要身份验证,authentication,dropwizard,Authentication,Dropwizard,我正在使用dropwizard开发一个应用程序,我试图设置一个简单的用例,用户需要在某些资源(URL)上进行身份验证,而不是在其他资源上进行身份验证 在阅读了所有教程之后,我面临着一个问题,我的所有资源都被强制进行身份验证…这不是我想要的 以下是我启动应用程序的步骤: } 我的TestAuthorizer看起来像: public class TestAuthorizer implements Authorizer<User> { @Override public boolean

我正在使用dropwizard开发一个应用程序,我试图设置一个简单的用例,用户需要在某些资源(URL)上进行身份验证,而不是在其他资源上进行身份验证

在阅读了所有教程之后,我面临着一个问题,我的所有资源都被强制进行身份验证…这不是我想要的

以下是我启动应用程序的步骤:

}

我的
TestAuthorizer
看起来像:

public class TestAuthorizer implements Authorizer<User> {

@Override
public boolean authorize(User user, String s) {
    return true;
}
@Path("/login")
public class LoginResource {

private static final Logger logger = LoggerFactory.getLogger(LoginResource.class);

@POST
@Produces(MediaType.APPLICATION_JSON)
public Response login(@Auth User principal, @Context HttpServletRequest request) {
    return Response.ok()
            .cookie(new NewCookie("test_cookie", request.getSession().getId(), "/", null, null, 5, false))
            .build();
}
}
其他资源只是普通资源,我在方法上尝试了
@PermitAll
,但没有成功,我在类级别尝试了,什么都没有

我正在使用Dropwizard 1.0.3版


感谢您的帮助。

来源-动态功能将启用@PermitAll上的身份验证,而不是禁用它

请参见AuthDynamicFeature:

final boolean annotationOnClass = (resourceInfo.getResourceClass().getAnnotation(RolesAllowed.class) != null) ||
            (resourceInfo.getResourceClass().getAnnotation(PermitAll.class) != null);
        final boolean annotationOnMethod = am.isAnnotationPresent(RolesAllowed.class) || am.isAnnotationPresent(DenyAll.class) ||
            am.isAnnotationPresent(PermitAll.class);

        if (annotationOnClass || annotationOnMethod) {
            context.register(authFilter);
因此,为了不在特定资源上使用auth,您永远不能将其应用于类级别(因为它将应用于所有资源方法)

请参见此示例:

public class AuthenticatorTest extends io.dropwizard.Application<DBConfiguration> {
    @Override
    public void run(DBConfiguration 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
        @UnitOfWork
        public String test(String x) {
            return "Hello";
        }


        @GET
        @Path("asd2")
        public String test2() {
            return "test2";
        }

    }

    public static class Person implements Principal {
        @Override
        public String getName() {
            return null;
        }

    }

    public static class UserAuth implements Authenticator<BasicCredentials, Principal> {
        @Override
        public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException {
            return Optional.of(new Principal() {
                @Override
                public String getName() {
                    return "artur";
                }

            });
        }
    }

}

第一个方法拒绝401的访问,而第二个方法正确地打印test2

Dropwizard提示API用户为包含@Auth user principal参数的方法提供凭据。如果删除参数和注释,则该方法将不受密码保护

像@PermitAll和@RolesAllowed这样的注释与授权有关,而不是身份验证


编辑:查看。

PermitAll将启用身份验证。您可以将其他资源发布到不起作用的位置吗?如果您没有角色,则不必注册RoleAllowedDynamicFeature。另外,您可以省略授权人的注册。这很有效。谢谢您的回答,我想我误解了权限注释。@Bambara没问题:)这的确是个坏名字。更容易将其视为授权注释,而不是身份验证。它定义了身份验证后要执行的操作。此外,如果答案是正确的,您可以接受:)接受答案,这正是我所想的,注释将在身份验证后发生。是的-但是要对注释执行任何合理的操作,必须首先进行身份验证。否则,授权没有意义,因为您没有用户授权。一切都很混乱。我用@Authenticate注释编写了我自己的版本,它只显式地启用身份验证,而不必依赖(对我来说)提供的令人困惑的注释。如果你有一个gist或github页面,我就是一个接受者。谢谢这是不对的。有关详细信息,请参见AuthDynamicFeature。PermitAll和RoleAllowed将触发DW注册身份验证筛选器。因此,这将具有与Auth注释相同的效果。Auth注释的主要目的是将主体注入到资源方法中。虽然Auth还将启用身份验证,但如果资源中不需要主体,则应改用PermitAll。请参阅文档:但他从授权人处返回true,他没有用户角色。他也不能登记他的授权人。根据文档,有多种方法可以保护资源。旧的就是我描述的那个。如果您具有基于角色的授权,则需要另一个。尽管授权需要知道谁在访问资源,但过滤器是注册的。如果用户没有角色,可以使用@Auth注释来保护所需的资源方法。你的downwote是不合理的。首先,这是一个测试代码,我在玩它,但它不起作用,我没有在玩权限,但做
返回true有什么害处
如果您还没有设置规则:)另一方面,@pandaadb所说的是真的,从Dropwizard源代码中可以清楚地看出,
@PermitAll
将触发身份验证,
@Auth
只需将主体插入您尝试访问的方法中,它还用于身份验证,但正如我们在本帖中所说的,DW注释不清晰,并且没有引导。只是为您提供了一个更简单的解决方案:)。true没什么不好的,如果您不需要,您可以省略授权人的注册。
final boolean annotationOnClass = (resourceInfo.getResourceClass().getAnnotation(RolesAllowed.class) != null) ||
            (resourceInfo.getResourceClass().getAnnotation(PermitAll.class) != null);
        final boolean annotationOnMethod = am.isAnnotationPresent(RolesAllowed.class) || am.isAnnotationPresent(DenyAll.class) ||
            am.isAnnotationPresent(PermitAll.class);

        if (annotationOnClass || annotationOnMethod) {
            context.register(authFilter);
public class AuthenticatorTest extends io.dropwizard.Application<DBConfiguration> {
    @Override
    public void run(DBConfiguration 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
        @UnitOfWork
        public String test(String x) {
            return "Hello";
        }


        @GET
        @Path("asd2")
        public String test2() {
            return "test2";
        }

    }

    public static class Person implements Principal {
        @Override
        public String getName() {
            return null;
        }

    }

    public static class UserAuth implements Authenticator<BasicCredentials, Principal> {
        @Override
        public Optional<Principal> authenticate(BasicCredentials credentials) throws AuthenticationException {
            return Optional.of(new Principal() {
                @Override
                public String getName() {
                    return "artur";
                }

            });
        }
    }

}
artur@pandaadb:~/dev/eclipse/eclipse_jee$ curl localhost:9085/api/test/asd -v
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9085 (#0)
> GET /api/test/asd HTTP/1.1
> Host: localhost:9085
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Date: Tue, 01 Nov 2016 10:30:10 GMT
< WWW-Authenticate: Basic realm="SUPER SECRET STUFF"
< Content-Type: text/plain
< Content-Length: 49
< 
* Connection #0 to host localhost left intact
Credentials are required to access this resource.artur@pandaadb:~/dev/eclipse/eclipse_jee$ 
artur@pandaadb:~/dev/eclipse/eclipse_jee$ curl localhost:9085/api/test/asd2 -v
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9085 (#0)
> GET /api/test/asd2 HTTP/1.1
> Host: localhost:9085
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Tue, 01 Nov 2016 10:30:14 GMT
< Content-Type: application/json
< Vary: Accept-Encoding
< Content-Length: 5
< 
* Connection #0 to host localhost left intact
test2