Java 如何使用自定义Dropwizard筛选器选择性地保护资源

Java 如何使用自定义Dropwizard筛选器选择性地保护资源,java,authentication,jersey,authorization,dropwizard,Java,Authentication,Jersey,Authorization,Dropwizard,我正在使用Dropwizard 0.9.2,我想创建一个资源,该资源不需要GET的身份验证,也需要POST的基本身份验证 我试过了 @Path("/protectedPing") @Produces(MediaType.TEXT_PLAIN) public class ProtectedPing { @GET public String everybody() { return "pingpong"; } @PermitAll @POST public String authent

我正在使用Dropwizard 0.9.2,我想创建一个资源,该资源不需要GET的身份验证,也需要POST的基本身份验证

我试过了

@Path("/protectedPing")
@Produces(MediaType.TEXT_PLAIN)
public class ProtectedPing {

@GET
public String everybody() {

    return "pingpong";
}

@PermitAll
@POST
public String authenticated(){
    return "secret pingpong";
}

CachingAuthenticator ca=新的CachingAuthenticator(environment.metrics(),ldapaauthenticator,cbSpec);
AdminAuthorizer authorizer=新的AdminAuthorizer();
BasicCredentialAuthFilter bcaf=新的BasicCredentialAuthFilter.Builder().setAuthenticator(ca.setRealm(“测试oauth”).setAuthorizer(authorizer.buildAuthFilter();
environment.jersey()寄存器(bcaf);
environment.jersey().register(RolesAllowedDynamicFeature.class);
register(新的AuthValueFactoryProvider.Binder(User.class));
environment.jersey().register(newprotectedping());
这似乎导致对“/protectedPing”的所有请求都需要基本身份验证


在Dropwizard 0.9.2中,文档说明如果我有一个可选受保护的资源,则创建一个自定义筛选器。我假设我需要这样做,但我不知道从哪里开始,或者我不知道我到底需要做什么。

这更像是一个球衣问题,而不是dropwizard问题。您可以在这里查看:

基本上你想要的是:

  • 创建一个注释,指示您要测试身份验证(例如@AuthenticatePost)

  • 创建资源并使用@AuthenticatePost注释正确的方法

  • 创建您的身份验证过滤器(可能类似于上面所做的)

  • 在动态特性中,测试传入资源上是否存在注释。这将适用于post,false适用于get。然后直接在资源方法上注册AuthenticationFilter,而不是在资源上全局注册

  • 这将是一个半完整的例子,说明我将如何解决这个问题:

    public class MyDynamicFeature implements DynamicFeature {
    
        @Override
        public void configure(ResourceInfo resourceInfo, FeatureContext context) {
            if(resourceInfo.getResourceMethod().getAnnotation(AuthenticateMe.class) != null ) {
                context.register(MyAuthFilter.class);
            }
        }
    
        public class MyAuthFilter implements ContainerRequestFilter {
    
            @Override
            public void filter(ContainerRequestContext requestContext) throws IOException {
                // do authentication here
            }
    
        }
    
        public @interface AuthenticateMe {
    
        }
    
        @Path("myPath")
        public class MyResource {
    
            @GET
            public String get() {
                return "get-method";
            }
    
            @POST
            @AuthenticateMe
            public String post() {
                return "post-method";
            }
        }
    }
    
    请注意,在向要素上下文注册身份验证之前,DynamicFeature会检查身份验证注释是否存在

    我希望这有帮助


    如果您有任何问题,请告诉我。

    我最后做了类似的事情,谢谢!我认为这更像是一个Jersey问题,但从Dropwizard的角度来看,很难理解Jersey的单词。我相信Jersey也有类似的方法,即使用Auth将用户绑定到resource方法中。如果无法创建用户,它将无法执行该方法。然而,这并不考虑所有预匹配的过滤器,这将运行不管。如果您感兴趣,以下是来自不同问题的一些信息:
    public class MyDynamicFeature implements DynamicFeature {
    
        @Override
        public void configure(ResourceInfo resourceInfo, FeatureContext context) {
            if(resourceInfo.getResourceMethod().getAnnotation(AuthenticateMe.class) != null ) {
                context.register(MyAuthFilter.class);
            }
        }
    
        public class MyAuthFilter implements ContainerRequestFilter {
    
            @Override
            public void filter(ContainerRequestContext requestContext) throws IOException {
                // do authentication here
            }
    
        }
    
        public @interface AuthenticateMe {
    
        }
    
        @Path("myPath")
        public class MyResource {
    
            @GET
            public String get() {
                return "get-method";
            }
    
            @POST
            @AuthenticateMe
            public String post() {
                return "post-method";
            }
        }
    }